분자가 다항식일 때는 음의 부호와 괄호의 문제가 오답을 일으킵니다. 다음 문제는 분수계수의 방정식이므로 먼저 2를 곱하여 간단하게 만드는 것이 좋습니다. 먼저 오답의 유형을 봅시다.


먼저 방정식에서 를 따로 떼어 내어 살펴봅시다. 분수 앞의 음의 부호를 분자에 올려 줄 때, 분자에 괄호가 있다고 생각해야 합니다. 그러면 이 됩니다. 여기에 2를 곱하면 로 올바른 식은 입니다. 첫 번째 오답은 음의 부호 처리가 잘못되었고, 두 번째 오답은 음의 부호를 처리하다가 각항에 빠짐없이 곱하는 것을 놓쳤습니다.



출처

    • 중학수학 개념사전 92


'수학' 카테고리의 다른 글

이차방정식  (0) 2017.03.13
연립방정식의 해와 그래프  (0) 2017.03.08
다항식과 방정식의 구분  (0) 2017.03.07
분모의 유리화  (0) 2017.03.07
유리수와 무리수  (0) 2017.03.07

tf.contrib.learn


tf.contrib.learn은 다음을 포함하여 머신러닝의 메커니즘을 단순화하는 상위 레벨의 TensorFlow 라이브러리입니다.

  • running training loops
  • running evaluation loops
  • managing data sets
  • managing feeding

tf.contrib.learn은 많은 일반 모델을 정의합니다. 



Basic usage


tf.contrib.learn을 사용하면 linear regression 프로그램이 얼마나 단순해지는지 알 수 있습니다.

import tensorflow as tf
# NumPy is often used to load, manipulate and preprocess data.
import numpy as np

# Declare list of features. We only have one real-valued feature. There are many
# other types of columns that are more complicated and useful.
features
= [tf.contrib.layers.real_valued_column("x", dimension=1)]

# An estimator is the front end to invoke training (fitting) and evaluation
# (inference). There are many predefined types like linear regression,
# logistic regression, linear classification, logistic classification, and
# many neural network classifiers and regressors. The following code
# provides an estimator that does linear regression.
estimator
= tf.contrib.learn.LinearRegressor(feature_columns=features)

# TensorFlow provides many helper methods to read and set up data sets.
# Here we use `numpy_input_fn`. We have to tell the function how many batches
# of data (num_epochs) we want and how big each batch should be.
x
= np.array([1., 2., 3., 4.])
y
= np.array([0., -1., -2., -3.])
input_fn
= tf.contrib.learn.io.numpy_input_fn({"x":x}, y, batch_size=4,
                                              num_epochs
=1000)

# We can invoke 1000 training steps by invoking the `fit` method and passing the
# training data set.
estimator
.fit(input_fn=input_fn, steps=1000)

# Here we evaluate how well our model did. In a real example, we would want
# to use a separate validation and testing data set to avoid overfitting.
estimator
.evaluate(input_fn=input_fn)

실행 결과는 다음과 같습니다. 

    {'global_step': 1000, 'loss': 1.9650059e-11}



A custom model


tf.contrib.learn은 미리 정의된 모델들만 제공하지 않습니다. TensorFlow에 내장되어 있지 않은 커스텀 모델을 만들 수 있습니다. tf.contrib.learn의 data set, feeding, training 등 높은 수준의 추상화는 유지할 수 있습니다. 설명을 위해, 낮은 수준은 TensorFlow API를 이용하여 linear regression에 대한 equivalent 모델을 구현하는 방법을 나타냅니다.


tf.contrib.leanr을 이용하여 커스텀 모델을 정의하기 위해, tf.contrib.learn.Estimator를 사용해야 합니다. tf.contrib.learn.LinearRegressor는 tf.contrib.learn.Estimator의 서브 클래스입니다. Estimator를 sub-classing하는 대신에 Estimator에 model_fn 함수를 제공합니다. tf.contrib.learn은 prediction, training step, loss를 evaluate할 수 있는 방법을 알려줍니다. 코드는 다음과 같습니다. 

import numpy as np
import tensorflow as tf
# Declare list of features, we only have one real-valued feature
def model(features, labels, mode):
 
# Build a linear model and predict values
  W
= tf.get_variable("W", [1], dtype=tf.float64)
  b
= tf.get_variable("b", [1], dtype=tf.float64)
  y
= W*features['x'] + b
 
# Loss sub-graph
  loss
= tf.reduce_sum(tf.square(y - labels))
 
# Training sub-graph
  global_step
= tf.train.get_global_step()
  optimizer
= tf.train.GradientDescentOptimizer(0.01)
  train
= tf.group(optimizer.minimize(loss),
                   tf
.assign_add(global_step, 1))
 
# ModelFnOps connects subgraphs we built to the
 
# appropriate functionality.
 
return tf.contrib.learn.ModelFnOps(
      mode
=mode, predictions=y,
      loss
= loss,
      train_op
=train)

estimator
= tf.contrib.learn.Estimator(model_fn=model)
# define our data set
x
=np.array([1., 2., 3., 4.])
y
=np.array([0., -1., -2., -3.])
input_fn
= tf.contrib.learn.io.numpy_input_fn({"x": x}, y, 4, num_epochs=1000)

# train
estimator
.fit(input_fn=input_fn, steps=1000)
# evaluate our model
print(estimator.evaluate(input_fn=input_fn, steps=10))

결과는 다음과 같습니다.

{'loss': 5.9819476e-11, 'global_step': 1000}

커스텀 모델 함수의 내용이 낮은 수준 API의 수동 모델 training loop와 얼마나 유사한지 주목하세요.



출처


'머신러닝 > TensorFlow' 카테고리의 다른 글

tf.train API  (0) 2017.03.07
TensorFlow Core tutorial  (0) 2017.02.28
설치하기  (2) 2017.02.21
TensorFlow란?  (0) 2017.02.21

참조자의 이해


무엇을 가리켜 변수라 할까요? 다음은 여러분이 잘 알고 있는 변수의 정의입니다.


변수는 할당된 메모리 공간에 붙여진 이름입니다. 그리고 그 이름을 통해서 해당 메모리 공간에 접근이 가능합니다.



int &num2 = num1;


이 문장은 다소 혼란스러울 수 있습니다. 왜냐하면 & 연산자는 변수의 주소 값을 반환하는 연산자이기 때문입니다. 하지만 위의 문장에서 보이듯이 & 연산자는 전혀 다른 의미로도 사용됩니다. 이미 선언된 변수의 앞에 이 연산자가 오면 주소 값의 반환을 명령하는 뜻이 되지만, 새로 선언되는 변수의 이름 앞에 등장하면, 이는 참조자의 선언을 뜻하는게 됩니다.


int *ptr = &num1;    // 변수 num1의 주소 값을 반환해서 포인터 ptr에 저장해라!

int &num2 = num1    // 변수 num1에 대한 참조자 num2를 선언해라!


따라서 변수 num1의 선언 이후에 다음 문장이 실행되면,


int &num2 = num1;


num2는 num1의 '참조자'가 되며, 이는 num1이라 이름 붙어있는 메모리 공간에 num2라는 이름이 하나 더 붙은 꼴입니다.


참조자는 자신이 팜조하는 변수를 대신할 수 있는 또 하나의 이름인 것입니다.


전통적으로 C++에서는 참조자를 다음과 같이 설명합니다.


변수에 별명(별칭)을 하나 붙여주는 것 입니다.




참조자의 수에는 제한이 없으며, 참조자를 대상으로도 참조자를 선언할 수 있습니다. 


하지만, 필요 이상으로 참조자를 선언하는 것은 바람직하지 않으며, 참조자를 대상으로 또 다른 참조를 만드는 일이 흔히 필요하지는 않습니다. 



참조자의 선언 가능 범위


참조자는 변수에 대해서만 선언이 가능하고, 선언됨과 동시에 누군가를 참조해야만 합니다.


int &ref = 20; (x)


참조자는 본디, 변수에 또 다른 이름을 붙이는 것이기 때문에 상수를 대상으로 참조자를 선언할 수는 없습니다. 또한 미리 참조자를 선언했다가, 후에 누군가를 참조하는 것은 불가능하며, 참조의 대상을 바꾸는 것도 불가능합니다.


int &ref; (x)


참조자를 선언하면서 NULL로 초기화하는 것도 불가능합니다. 


int &ref = NULL; (x)


참조자는 무조건 선언과 동시에 변수를 참조하도록 해야 합니다.


int arr[3] = {1, 3, 5};

int &ref1 = arr[0];

int &ref2 = arr[1];

int &ref3 = arr[2];


배열요소는(배열이 아니라, 배열의 요소는) 변수로 간주되어 참조자의 선언이 가능합니다. 그리고 포인터 변수도 변수이기 때문에 참조자의 선언이 가능합니다.


int num = 12;

int *ptr = #

int **dptr=&ptr;


int &ref = num;

int *(&pref) = ptr;

int **(&dpref) = dptr;



출처

  • 열혈 C++ 프로그래밍


실행중인 프로그램은 운영체제로부터 메모리 공간을 할당 받는데, 이는 크게 데이터, 스택, 힙 영역으로 나뉩니다.


  • 데이터 : 전역변수가 저장되는 영역


  • 스택 : 지역변수 및 매개변수가 저장되는 영역


  • 힙 : malloc 함수 호출에 의해 프로그램이 실행되는 과정에서 동적으로 할당이 이뤄지는 영역


  • malloc & free : malloc 함수 호출에 의해 할당된 메모리 공간은 free 함수 호출을 통해서 소멸하지 않으면 해제되지 않습니다.


출처

  • 열혈 C++ 프로그래밍
  • const int num = 10;

-> 변수 num을 상수화!


  • const int * ptr1 = &val1;

-> 포인터 ptr1을 이용해서 val1의 값을 변경할 수 없음


  • int * const ptr2 = &val2;

-> 포인터 ptr2가 상수화 됨


  • const int * const ptr3 = &val3;

-> 포인터 ptr3이 상수화 되었으며, ptr3을 이용해서 val3의 값을 변경할 수 없음


출처

  • 열혈 C++ 프로그래밍

의 계산에서 분수꼴인 부분에 각각 12를 곱하여 분모를 없애고 로 문제를 풀면 틀리는 이유는 무엇일까요?


위 문제는 다항식과 방정식을 구분하지 못하는 오류에서 비롯됩니다. 분모의 최소공배수를 곱하였던 것은 등식이 있는 방정식에서 사용했던 방법입니다. 위 식은 등식이 아니기 때문에 수를 곱하면 당연히 다른 수가 됩니다.


만약 인 일차방정식이라면 양변에 12를 곱해서 로 만들면 됩니다. 이를 풀면 입니다. 그러나 와 같은 다항식에 12를 곱해서 와 같이 분모를 없애고 계산하면 답이 틀립니다.


가 올바른 방법입니다. 통분의 과정이 복잡하여 다른 방법을 찾는다면 아예 방법이 없는 것은 아닙니다. 12를 곱했다면 반대로 다시 12로 나누어 주면 됩니다. 준식(주어진 식)에 12를 곱하고 다시 나누는 과정을 거치면 처럼 올바른 식에 도달할 수도 있습니다.


출처

    • 중학수학 개념사전 92


'수학' 카테고리의 다른 글

연립방정식의 해와 그래프  (0) 2017.03.08
분자가 다항식일 때의 방정식의 해  (0) 2017.03.08
분모의 유리화  (0) 2017.03.07
유리수와 무리수  (0) 2017.03.07
제곱근  (0) 2017.03.06

같은 수의 곱으로 유리화가 되지 않을 때


분모의 유리화 중에는 처럼 분모와 같은 수를 곱하여도 유리수가 되지 않는 경우가 있습니다. 만약 분모에 을 곱하면 로 여전히 무리수이고, 를 곱해도 마찬가지입니다. 분모와 같은 수를 곱하여 가 되어도 계산해 보면 로 여전히 무리수입니다. 이 문제를 해결하기 위해서는 다항식의 곱셈 중에 합차공식, 즉 를 이용하면 됩니다.



출처

    • 중학수학 개념사전 92

'수학' 카테고리의 다른 글

분자가 다항식일 때의 방정식의 해  (0) 2017.03.08
다항식과 방정식의 구분  (0) 2017.03.07
유리수와 무리수  (0) 2017.03.07
제곱근  (0) 2017.03.06
인수분해  (0) 2017.03.06

유리수와 무리수를 합하여 실수라고 하는데 실수는 '실제의 수'라는 뜻입니다. 그렇다면 가짜의 수인 '허수'도 있습니다.


복소수는 실수와 허수로 구성되어 있으며 실수는 유리수와 무리수로 구성되어 있습니다.


유리수는 분수로 만들 수 있는 수이고, 무리수는 분수로 만들 수 없는 수입니다. 외우기 좋도록 약간 변형하면 유리수는 분수로 만들기 유리한 수이고, 무리수는 분수로 만들기에 무리가 있는 수입니다.


출처

    • 중학수학 개념사전 92


'수학' 카테고리의 다른 글

다항식과 방정식의 구분  (0) 2017.03.07
분모의 유리화  (0) 2017.03.07
제곱근  (0) 2017.03.06
인수분해  (0) 2017.03.06
소인수분해  (0) 2017.03.06

tf.train API


머신러닝의 자세한 이론적 내용은 이 튜토리얼의 범위를 벗어납니다. 그러나 TensorFlow는 loss function을 최소화하기 위해 각 variable을 천천히 변경하는 optimizer를 제공합니다. 가장 간단한 optimizer는 gradient desent 방법입니다. 해당 variable에 대한 loss의 derivative의 magnitude에 따라 각 variable을 수정합니다. 일반적으로 수동으로 symbolic derivative를 계산하는 것은 지루하고 오류가 발생하기 쉽습니다. 결과적으로, TensorFlow는 tf.gradients 함수를 사용하여 model의 description만 제공된 derivative를 자동으로 생성할 수 있습니다. 단순화를 위해 일반적으로 optimizer를 수행합니다. 

optimizer = tf.train.GradientDescentOptimizer(0.01)
train
= optimizer.minimize(loss)
sess.run(init) # reset values to incorrect defaults.
for i in range(1000):
  sess
.run(train, {x:[1,2,3,4], y:[0,-1,-2,-3]})

print(sess.run([W, b]))

최종 model 매개변수가 생성됩니다.

[array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]

이제 실제 머신러닝을 해봤습니다. 이런 간단한 linear regression을 수행한다면 TensorFlow 핵심 코드가 많이 필요하지는 않지만, 좀 더 복잡한 model과  data를 입력하는 method는 더 많은 코드가 필요합니다. 따라서 TensorFlow는 일반적인 패턴, 구조 및 기능에 대해 더 높은 level의 추상화를 제공합니다. 우리는 다음 section에서 이러한 추상화를 사용하는 방법을 배웁니다.


complete program


완성된 training 가능한 linear regression model은 다음과 같습니다.

import numpy as np
import tensorflow as tf

# Model parameters
W
= tf.Variable([.3], tf.float32)
b
= tf.Variable([-.3], tf.float32)
# Model input and output
x
= tf.placeholder(tf.float32)
linear_model
= W * x + b
y
= tf.placeholder(tf.float32)
# loss
loss
= tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
# optimizer
optimizer
= tf.train.GradientDescentOptimizer(0.01)
train
= optimizer.minimize(loss)
# training data
x_train
= [1,2,3,4]
y_train
= [0,-1,-2,-3]
# training loop
init
= tf.global_variables_initializer()
sess
= tf.Session()
sess
.run(init) # reset values to wrong
for i in range(1000):
  sess
.run(train, {x:x_train, y:y_train})

# evaluate training accuracy
curr_W
, curr_b, curr_loss  = sess.run([W, b, loss], {x:x_train, y:y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))

실행하면 다음과 같은 결과를 보여줍니다.

W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11

좀 더 복잡한 이 프로그램은 여전히 TensorBorad에서 시각화 할 수 있습니다.

TensorBoard final model visualization

출처





'머신러닝 > TensorFlow' 카테고리의 다른 글

tf.contrib.learn  (0) 2017.03.08
TensorFlow Core tutorial  (0) 2017.02.28
설치하기  (2) 2017.02.21
TensorFlow란?  (0) 2017.02.21
#include <iostream>

inline int SQUARE(int x)
{
    return x*x;
}

int main(void)
{
    std::cout << SQUARE(5) << std::endl;
    std::cout << SQUARE(12) << std::endl;
    return 0;
}

매크로를 이용한 함수의 인라인화는 전처리기에 의해서 처리되지만, 키워드 inline을 이용한 함수의 인라인화는 컴파일러에 의해서 처리가 됩니다. 따라서 컴파일러는 함수의 인라인화가 오히려 성능에 해가 된다고 판단할 경우, 이 키워드를 무시해버리기도 합니다. 또한 컴파일러는 필요한 경우 일부 함수를 임의로 인라인 처리하기도 합니다.


다음과 같이 정의된 인라인 함수는

inline int SQUARE(int x) { return x*x; }


int형 기반으로 정의된 함수이기 때문에 다음의 함수 호출 문장에서 데이터 손실이 발생합니다.

std::cout << SQUARE(3.15);


함수의 오버로딩을 통해서 이 문제를 해결할 수는 있으나, 그렇게 되면 여러 개의 함수를 추가로 정의하는 꼴이 되니, 한번만 정의하면 되는 매크로 함수의 장점과는 거리가 멀어지게 됩니다. 그러나 c++의 템플릿이라는 것을 이용하면 매크로 함수와 마찬가지로 자료형에 의존적이지 않은 함수가 완성됩니다.


#include <iostream>

template 
inline T SQUARE(T x)
{
    return x*x;
}

int main(void)
{
    std::cout << SQUARE(5.5) <<< std::endl;
    std::cout << SQUARE(12) <<< std::endl;
    return 0;
}


위 코드를 실행해보면, 데이터의 손실이 발생하지 않음을 알 수 있습니다.



출처

    • 열혈 C++ 프로그래밍


+ Recent posts