TensorFlow :: tutorial_mnist_Experts 2

Published onesixx on

https://tensorflow.rstudio.com/tutorial_mnist_pros.html

 

Training

Train the Model

모델을 정의하고, training loss함수를 정의함. 이제 tensorFlow을 사용하여 바로 모델 훈련 시작

optimizer는 학습속도 0.5의 gradient descent 알고리즘을 사용한다. 
TensorFlow는 전체 연산 그래프를 알고있기 때문에, loss의 gradients를 찾기위해 자동적으로 미분을 사용한다. 
다행이 TensorFlow는 여러종류의 [built-in optimization algorithms] 을 가지고 있다. 
(https://www.tensorflow.org/api_docs/python/train.html#optimizers). 

cross entropy를 최소화하는 backpropagation 알고리즘을 사용한다. 

optimizer <- tf$train$GradientDescentOptimizer(0.5)
train_step <- optimizer$minimize(cross_entropy)

train_step에서 산출된 매개변수는 gradient descent 알고리즘에 다시 참여한다.
따라서, 모델훈련을 하려면 train_step을 반복해서 실행해야한다.(여기서는 1000번 실행 )

이 한줄에 코드에서 TensorFlow가 실제 하는 일은 computation graph에 신규 operation들을 추가하는 것이었다. 
이런 operation들은 gradient들을 계산하기 위해, parameter update단계를 계산하고 parameter들에 update단계를 적용하는 것을 포함한다. 
These operations included ones to compute gradients, compute parameter update steps, and apply update steps to the parameters.

The returned operation train_step, when run, will apply the gradient descent updates to the parameters. Training the model can therefore be accomplished by repeatedly running train_step.

for (i in 1:1000) {
  batches <- mnist$train$next_batch(100L)
  batch_xs <- batches[[1]]
  batch_ys <- batches[[2]]
  sess$run(train_step,
           feed_dict = dict(x = batch_xs, yTruth = batch_ys))
}

각 loop반복시 마다 전체 데이터를 사용하는 대신에,
mnist$train$next_batch(100L)로 training 데이터셋에서 임의로 100개를 추출하여 사용한다. 

We then run the train_step operation, using feed_dictto replace the placeholder tensors x and yTruth with the training examples. Note that you can replace any tensor in your computation graph using feed_dict – it’s not restricted to just placeholders.

 

 5. Cost function 1

Evaluate the Model

모델은 충분히 좋은가?? (Training과정에서도 모델평가의 기준이 있어야  W b를 결정할수 있다.)

일반적인 machine learning에서는 모델이 어떻게 하면 나빠지는가에 대해 정의한다. => error, cost, loss 
충분히 좋다 =  비용함수를 기준으로 얼마나 모델이 나쁜지를 측정하고, 해당 함수가 최소화 되는 W와 b를 얻는다.
즉, Error를 minimize하려고 노력하고, Error margin이 더 작을 수록,  Model이 좋다고 할수 있다.

Error (오차 = 기대값 – 실제출력값) 측정 방법 
– Cross Entropy(MLE, maximun likelyhood)
– MSE(mean square error)
– 유클리디안 제곱 거리

Cross-entropy (Likelyhood)
정보를 압축하는 코드에 관한 생각에서 출발했지만, 머신러닝에서 중요한 아이디어로 자리매했다.

여기서,  y :  예측된 확률분포 (predicted probability distribution)
               y′ : training data로부터 얻은 실제 분포 (true distribution) :   one-hot vector with the digit labels

두 분포 (y , y′ )가 같을때, 최소값을 얻는다.  

거칠게 표현하면,  cross-entropy 는 예측값이 True값을 나타내기에 얼마나 나쁜가를 측정한다.
understanding.
https://www.khanacademy.org/computing/computer-science/informationtheory/info-theory/v/intro-information-theory

cross-entropy 구현하기 위해서는 우선 실제 레이블을 담고 있을  (정확한answer를 input할) 새로운 placeholder를  추가한다. 

yTruth <- tf$placeholder(tf$float32, shape(NULL, 10L))

Then we can implement the cross-entropy function, −∑y′log(y):

cross_entropy <- tf$reduce_mean(-tf$reduce_sum(yTruth * tf$log(y), reduction_indices=1L))

1) tf$log computes the logarithm of each element of y.
2) we multiply each element of yTruth with the corresponding element of tf$log(y).
3) tf$reduce_sum adds the elements in the second dimension of y, due to the reduction_indices=1L parameter.
4) tf$reduce_mean computes the mean over all the examples in the batch.

Note that tensor indices (like the one used for reduction_indices) are 0
-based within the TensorFlow API (rather than 1-based as is typical with R vectors).

Now that we know what we want our model to do, it’s very easy to have TensorFlow train it to do so.
TensorFlow가  전체 그래프를 알고 있기때문에,  설정해 놓은 Variable들이 loss를 최소화하는데  얼마나 영향을 미치는지 효과적으로 결정하기 위해  자동으로 backpropagation 알고리즘( backpropagation algorithm )을 사용한다. 

 

We can specify a loss function just as easily. Loss indicates how bad the model’s prediction was on a single example; we try to minimize that while training across all the examples. Here, our loss function is the cross-entropy between the target and the model’s prediction:

cross_entropy <- tf$reduce_mean(-tf$reduce_sum(yTruth * tf$log(y), reduction_indices=1L))

Note that tf$reduce_sum sums across all classes and tf$reduce_mean takes the average over these sums.

Note also that tensor indexes within the TensorFlow API (like the one used for reduction_indices) are 0-based rather than 1-based as is typical with R vectors.

 

Then it can apply your choice of optimization algorithm to modify the variables and reduce the loss.

optimizer <- tf$train$GradientDescentOptimizer(0.5)
train_step <- optimizer$minimize(cross_entropy)

여기서,  we ask TensorFlow to minimize cross_entropy using the gradient descent algorithm with a learning rate of 0.5. Gradient descent is a simple procedure, where TensorFlow simply shifts each variable a little bit in the direction that reduces the cost.  
But TensorFlow also provides [many other optimization algorithms] (https://www.tensorflow.org/api_docs/python/train.html#optimizers): using one is as simple as tweaking one line.

What TensorFlow actually does here, behind the scenes, is
to add new operations to your graph which implement backpropagation and gradient descent.
Then it gives you back a single operation which, when run, does a step of gradient descent training, slightly tweaking your variables to reduce the loss.

 

ASSESS

 6. 모델평가

모델 훈련후, 평가가 필요하다. 우선 제대로 예측한 label 과  틀리게 예측한 Label의 갯수를 세어 보자.
tf$argmax() 는 tensor내 한 축(차원)을따라 가장 큰 값의 index를 알려주는 함수이다. 
예를 들어 tf$argmax(y, 1L)는 각 input 이미지에 대해  가장 높은 확률(most likely)을 가진 label을 return하게 되고, 
       반면,  tf$argmax(yTruth, 1L)는 true label 이다.  

tf$equal를 사용해서 예측값과 truth를 비교한다.
 TensorFlow API내의 tensor들은 기본적으로 0으로 채워져 있기 때문에,  tf$argmax가 tensor의 두번째 차원에서 적용하기 위해 1L 을 넘긴다. 

correct_prediction <- tf$equal(tf$argmax(y, 1L), tf$argmax(yTruth, 1L))

 위에서 계산한 결과(correct_prediction)는 booleans의 list 이다.

accuracy <- tf$reduce_mean(tf$cast(correct_prediction, tf$float32))

예측이 얼마나 맞았는지 확인하기 위해 (어떤 fraction이 정확한지를 결정하기 위해, To determine what fraction are correct)
계산된 booleans 리스트를 숫자(floating point numbers)로 casting하고, 그것의 평균을 계산한다. 이것이 정확도(Accuracy)
예를 들면,   c(T, F, T, T…) 는   c(1,0,1,1)로 casting되고, 평균을 계산하면 0.75가된다. 

feed_dict의 매개변수로 test 데이터셋을 넣어 , test data의 accuracy를 계산한다.

sess$run(accuracy, feed_dict=dict(x = mnist$test$images, yTruth = mnist$test$labels))

결국 test data에 대한 정확도를 구해보면,  92% 이다.  

## [1] 0.9157

결과적으로 좋은건가? 음….뭐 나쁘지 않다고 할수도 있지만,  매우 간단한 모델을 사용했기 때문에, 사실 “아주 별로다:라고 평가할수 있다. 
약간만 수정하면 97%까지 정확도를 올리수 있다. 좋은 모델은 정확도가 99.7%이상이 될수도 있다. (참고,  list of results.)

<전체code>

datasets <- tf$contrib$learn$datasets
mnist <- datasets$mnist$read_data_sets("MNIST-data", one_hot = TRUE)

mnist[[1]]

options(digits=4, scipen=666)
library(tensorflow)
# Load mnist data
#sess <- tf$Session()
sess <- tf$InteractiveSession()

# Create the model
x    <- tf$placeholder(tf$float32, shape(NULL, 784L))   # input images
# Define loss and optimizer
yHat <- tf$placeholder(tf$float32, shape(NULL,  10L))   # target output classes

W <- tf$Variable(tf$zeros(shape(784L, 10L)))
b <- tf$Variable(tf$zeros(shape(10L)))


# Create session and initialize  variables
#sess$run(tf$global_variables_initializer())
init <- tf$global_variables_initializer() # 변수 초기화
sess$run(init)


y <- tf$nn$softmax(tf$matmul(x, W) + b)


cross_entropy <- tf$reduce_mean(-tf$reduce_sum(yHat * log(y), reduction_indices=1L))

#train_step <- tf$train$GradientDescentOptimizer(0.5)$minimize(cross_entropy)
optimizer <- tf$train$GradientDescentOptimizer(0.5)
train_step <- optimizer$minimize(cross_entropy)

# Train
for (i in 1:1000) {
  batches  <- mnist$train$next_batch(100L)
  batch_xs <- batches[[1]]
  batch_ys <- batches[[2]]
  sess$run(train_step,
           feed_dict = dict(x = batch_xs, yHat = batch_ys))
}

# Test trained model
correct_prediction <- tf$equal(tf$argmax(y, 1L), tf$argmax(yHat, 1L))
accuracy <- tf$reduce_mean(tf$cast(correct_prediction, tf$float32))

sess$run(accuracy,
         feed_dict = dict(x = mnist$test$images, yHat = mnist$test$labels))

 

http://jorditorres.org/first-contact-with-tensorflow/

https://tensorflow.blog/4

 

Categories: DL

onesixx

Blog Owner

Leave a Reply

Your email address will not be published.