본문 바로가기
AI 이론과 개발의 혼재/Implementation

AdamOptimizer Save and Restore for Retraining - 딥러닝 재학습

by ministar 2018. 8. 30.





TensorFlow를 이용하여 딥러닝 재학습 하기




이미 기학습된 모델을 불러와 예측/분류 하는 일은 비교적 간편하나,

그 모델을 다시 불러와서 재학습시키는 것은 생각보다 까다로웠다. --물론 필자에게만 해당된 얘기일수도^_ㅠ --

TensorFlow를 이용하여 딥러닝 재학습을 하기 위한 방법 및 이슈 해결 방안을 기록한다.  


방법1. logits, optimizer 재정의


학습한 모델을 먼저 불러와보자.

 Input Data를 넣을 Placeholder X, X2, Y와  분류 결과를 내뱉는 logits 를 가져왔다. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

with tf.Session() as sess : saver = tf.train.import_meta_graph(GRAPH_PATH, clear_devices = True) checkpoint = tf.train.get_checkpoint_state(CKPT_FILE_PATH) saver.restore(sess, checkpoint.model_checkpoint_path) op_placeholder = [op for op in sess.graph.get_operations() if op.type == 'Placeholder'] for op in op_placeholder: if 'X2' in op.name.upper(): X2 = sess.graph.get_tensor_by_name(op.name+':0') elif 'X' in op.name.upper(): X = sess.graph.get_tensor_by_name(op.name+':0') elif 'Y' in op.name.upper(): Y = sess.graph.get_tensor_by_name(op.name+':0') elif 'TRAINING' in op.name.upper(): TRAINING = sess.graph.get_tensor_by_name(op.name+':0') k = [op.name for op in sess.graph.get_operations() if "Logits" in op.name][0] model_name =k.split('/')[0] inference = sess.graph.get_tensor_by_name(model_name+'/Logits/Predictions:0') #softmax 값 logits = sess.graph.get_tensor_by_name(model_name+'/Logits/Logits/BiasAdd:0') #logits



재학습을 시키기 위하여 Cost와 optimizer를 재정의하고 학습을 시켜보자.


1
2
3
4
5
6
7

l_rate = 0.0001 / 100 d_rate = 0.01 cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=Y)) global_step = tf.Variable(0, trainable = False) optimizer = tf.train.AdamOptimizer(learning_rate = l_rate, name = 'transferAdam').minimize(cost)


아래와 같은 에러가 뜬다. 

tensorflow Adamoptimizer beta1_power not initialized

tensorflow/core/framework/op_kernel.cc:1152] Failed precondition: Attempting to use uninitialized value beta1_power



다른 tensor graph들은 전부 restore를 통해 값을 가지고 있어, 별도의 initialization이 필요없지만,

새롭게 정의한 optimizer에 대해서는 initialization을 안했다고 오류가 난다. 


이럴 경우에는 새로 정의한 optimizer에 대해서만 initialization을 해주면 된다.  

위에 코드를 보면 알겠지만 새로 정의한 것에 필자는 이름을 'transferAdam'으로 저장해주었다. 

일반적으로 이름을 따로 명시하지 않으면, default 값 'Adam'으로 지정된다.


1
2
3

new_opt_var_list = [v for v in tf.global_variables() if ('transferAdam' in v.name or 'beta1_power' in v.name or 'beta2_power' in v.name )] init = tf.variables_initializer(var_list=new_opt_var_list) sess.run(init)



Initialize를 해주었으니 ~ 다시 학습 시작을 하면, 무난히 잘 돌아감을 확인할 수 있다.


1
2
3
4
5
6

for i in range(10) : feed_dict = {X: x_1, X2: x_2, Y: y, TRAINING : True} c, _ = sess.run([cost, optimizer], feed_dict=feed_dict) print(f'{i} -- cost : {c}')




방법2. 학습 시 Optimizer Save 해주기!


두번째 방법은~ 학습 때 Optimizer를 따로 tensorFlow 그래프에 저장해주는 것이다.


[학습 시] 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

#... 그래프 정의 부분 생략 ... # tf.add_to_collection("optimizer", optimizer) for i in range(10) : feed_dict = {X: x_1, X2: x_2, Y: y, TRAINING : True} c, _ = sess.run([cost, new_op], feed_dict=feed_dict) print(f'{i} -- cost : {c}') print('save model') saver.save(sess, CKPT_FILE_PATH + "model_tl")



Saver.save() 후 , 다시 Restore 할때 아래와 같이 불러오면 된다. 

1

new_op = tf.get_collection("optimizer")


이 경우에는 별도의 initialization 없이 바로 재학습이 가능하다 :) 



댓글