Tensorflow2016. 11. 19. 16:05


지금까지 우리는 기본적으로 제공되고 있는 tf.contrib.learn 의 알고리즘 API들을 그대로 사용하여 학습을 시키고 loss를 구하고 평가를 하였습니다.


LinearClassifier: Constructs a linear classification model.

LinearRegressor: Constructs a linear regression model.

DNNClassifier: Construct a neural network classification model.

DNNRegressor: Construct a neural network regressions model.


그런데 우리의 목적에 맞게 조금 변형하고 보완하여 사용하고 싶을 때나, 혹은 다른 종류의 알고리즘을 사용하고 싶을 경우에는 이러한 미리 만들어진 API를 사용해서는 어려운 일이 될 것입니다.


이를 위해서 Tensorflow에서는 Estimator라는 객체를 통해서 쉽게 자신만의 알고리즘을 구현할 수 있도록 제공하고 있습니다.

전체적인 진행 흐름은 아래와 같이 이루어집니다.


Instantiate an Estimator

Construct a custom model function

Configure a neural network using tf.contrib.layers

Choose an appropriate loss function from tf.contrib.losses

Define a training op for your model

Generate and return predictions

(출처 : https://www.tensorflow.org/versions/master/tutorials/estimators/index.html)


이를 위한 튜토리얼이 위의 출처 링크에 해당합니다.

전체적인 소스는 여기에서 다운로드 받을 수 있습니다. (https://github.com/tensorflow/tensorflow/blob/r0.11/tensorflow/examples/tutorials/estimators/abalone.py)


다운 받은 소스를 한번 실행을 해보면 아래와 같은 결과를 보여줍니다.


[실행]

...

INFO:tensorflow:Create CheckpointSaverHook

INFO:tensorflow:loss = 846.871, step = 1

INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmpRGB1it/model.ckpt.

INFO:tensorflow:loss = 104.052, step = 101

INFO:tensorflow:loss = 85.5976, step = 201

INFO:tensorflow:loss = 76.8586, step = 301

INFO:tensorflow:loss = 72.0811, step = 401

INFO:tensorflow:loss = 68.9045, step = 501

...

INFO:tensorflow:loss = 40.4448, step = 4601

INFO:tensorflow:loss = 41.045, step = 4701

INFO:tensorflow:loss = 41.0788, step = 4801

INFO:tensorflow:loss = 40.1266, step = 4901

INFO:tensorflow:Saving checkpoints for 5000 into /tmp/tmpRGB1it/model.ckpt.

INFO:tensorflow:Loss for final step: 39.8036.

...

INFO:tensorflow:Eval steps [0,1) for training step 5000.

INFO:tensorflow:Saving evaluation summary for 5000 step: loss = 20.5465

Loss: 20.546515

...

Predictions: [ 34.80521393  18.04696846  21.22025871  34.60494995  13.17673302

  18.98731041]



[소스]


그러면, 어떻게 Estimator를 생성하면 되는지에 대해서 소스를 보면서 살펴보도록 하겠습니다.

Estimator 객체를 생성하기 위해서는 2개의 파라메터가 필요합니다. 아래와 같이 model_fn과 params 정보입니다.



nn = tf.contrib.learn.Estimator(
model_fn=model_fn, params=model_params)


model_fn 은 함수의 이름입니다. 이 함수에서는 어떻게 학습을 할 것인지, loss는 어떻게 구할 것인지, 평가는 어떻게 할 것인지 등에 대한 알고리즘 로직이 구현이 되어 있어야 합니다. 우리가 만들어야 하는 시스템의 두뇌 역할을 하게 되는 부분입니다.


params는 초기에 model_fn에 전달해 주어야 하는 파라메터들의 정보입니다.

이 튜토리얼에서는 간단하게 learning_rate 만을 파라메터로 전달해 주고 있습니다. 이 params를 이용해서 learning_rate 뿐만아니라 dropout이나 lambda 같은 정보들을 전달해 주도록 사용하면 될 것 같습니다.



# Learning rate for the model
LEARNING_RATE = 0.001

# Set model params
model_params = {"learning_rate": LEARNING_RATE}



이제 그럼 본격적으로 model_fn이 어떻게 생성되는지 살펴보겠습니다.


model_fn의 기본 구성은 다음과 같이 되어야 합니다.

def model_fn(features, targets, mode, params):

   # Logic to do the following:

   # 1. Configure the model via TensorFlow operations (학습 모델을 구성)

   # 2. Define the loss function for training/evaluation (loss function을 정의)

   # 3. Define the training operation/optimizer (optimizer를 정의)

   # 4. Generate predictions (결과 값을 예측)

   return predictions, loss, train_op


크게 4개의 정보를 인자로 받아서 3개의 정보를 결과로 return을 해주어야 하는 함수가 됩니다.


인자중에서 features는 학습을 하기 위해서 사용될 features data 정보입니다. 이 데이터는 fit(), evaluate(), predict()과 같은 함수들이 호출되면서 전달되게 됩니다.


targets는 결과정보인 label data가 포함되어 있는 Tensor 값입니다. 이 데이터도 또한 fit(), evaluate(), predict()과 같은 함수들이 호출되면서 전달되게 됩니다.


mode는 modekeys 값들중에 하나로서, training mode 와 evaluation mode 와 inference mode 중에 하나가 됩니다.

training mode는 데이터를 통해 학습하는 단계로서 fit() 함수로 호출이 되는 모드입니다. 실제 사용되는 값은 tf.contrib.learn.ModeKeys.TRAIN 입니다.

evaluation mode는 학습된 결과를 평가하는 단계로서 evaluate() 함수로 호출이 되는 모드입니다. 실제 사용되는 값은 tf.contrib.learn.ModeKeys.EVAL 입니다.

inference mode는 학습이 완료된 모델에 예측을 위한 데이터로 결과를 보는 단계로서 predict() 함수로 호출이 되는 모드입니다. 실제 사용되는 값은 tf.contrib.learn.ModeKeys.INFER 입니다.


params는 앞에서 Estimator를 생성할 때 주어지는 params가 전달되어집니다.



이렇게 하여 model_fn에서 받은 인자들로 로직들이 처리가 되고 난후에는 결과값으로 3가지 정보를 리턴해주어야 합니다.


predictions는 예측된 결과 데이터를 담고 있습니다. 이 정보는 학습을 통해서 만들어진 결과 정보가 됩니다.

loss는 예측된 결과 데이터와 실제 결과 label 데이터와 비교하여 측정된 cost 정보가 됩니다.

train_op는 학습이 될 때 실행이 되는 하나의 operation 입니다.



그럼 이제 실제적으로 소스에서 어떻게 구현을 하고 있는지 살펴보겠습니다.


이번 튜토리얼에서는 3개 layer로 구성된 NN 형태의 모델을 구성하고 있습니다.

모델을 구성하기 위해서 tf.contrib.layers에서 제공하는 API들을 사용해서 각각의 layers들을 구성하고 이렇게 생성된 output_layer 의 값을 tf.reshape() 함수로 vector 형태의 데이터로 변환합니다. 그리고 이 데이터는 age를 예측하는 결과 값이 됩니다.



# Connect the first hidden layer to input layer
# (features) with relu activation
first_hidden_layer = tf.contrib.layers.relu(features, 10)

# Connect the second hidden layer to first hidden layer with relu
second_hidden_layer = tf.contrib.layers.relu(first_hidden_layer, 10)

# Connect the output layer to second hidden layer (no activation fn)
output_layer = tf.contrib.layers.linear(second_hidden_layer, 1)

# Reshape output layer to 1-dim Tensor to return predictions
predictions = tf.reshape(output_layer, [-1])
predictions_dict = {"ages": predictions}


이 결과값은 targets의 label 데이터와 비교 연산을 하여 loss 값을 생성합니다.



# Calculate loss using mean squared error
loss = tf.contrib.losses.mean_squared_error(predictions, targets)

 

최종적으로 이러한 loss 값이 minimize 된 값을 찾기 위한 optimizer를 지정해줍니다. 이것을 train_op로 넘겨주면 실제 학습이 되면서 수행이 되는 operation 이 됩니다.



train_op = tf.contrib.layers.optimize_loss(
loss=loss,
global_step=tf.contrib.framework.get_global_step(),
learning_rate=params["learning_rate"],
optimizer="SGD")


이렇게하여 커스텀 Estimator를 만드는 방법에 대해서 알아보았습니다.


실제적으로 Estimator를 구현하기 위해서는 많은 알고리즘과 optimizer에 대해서 알고 있어야 하거나 가져다 쓸수 있어야 합니다.


우리가 모델을 구성하고 만들때 우선은 이미 만들어져 있는 알고리즘 API들을 사용해서 먼저 가능여부를 확인하고 보다 성능을 개선하고 원하는 값이 나오도록 하고자 할때 이번 튜토리얼과 같이 Estimator를 만들면서 자신의 목적에 맞는 알고리즘을 만들어가는 것이 좋을 것 같습니다.




Posted by 대소니

댓글을 달아 주세요