EXCELSIOR

학습된 모델 재사용하기 - Transfer Learning 본문

DeepLearning/Learning TensorFlow

학습된 모델 재사용하기 - Transfer Learning

Excelsior-JH 2018. 10. 12. 00:07

학습된 모델 재사용하기 - Transfer Learning

1. Transfer Learning 이란?

규모가 매우 큰 DNN 모델을 학습 시킬 때 처음부터 새로 학습 시키는 것은 학습 속도가 느린 문제가 있다. 이러한 경우 기존에 학습된 비슷한 DNN모델이 있을 때 이 모델의 하위층(lower layer)을 가져와 재사용하는 것이 학습 속도를 빠르게 할 수 있을 뿐만아니라 학습에 필요한 Training set도 훨씬 적다.

예를 들어, 아래의 그림처럼 CIFAR10 데이터셋을 분류(비행기, 자동차, 새, 고양이, 사슴, 개, 개구리, 말, 배, 트럭의 10개 클래스)하는 모델 A가 이 있다고 하자. 그런 다음, 분류된 CIFAR10 이미지에서 자동차의 종류를 분류하는 모델인 B를 학습시킨다고 할 때, 학습된 모델 A에서의 일부분(lower layer)을 재사용하여 모델 B를 학습 시킬 수 있다. 이러한 방법을 Transfer Learning이라고 한다.




2. 텐서플로 모델 재사용하기

텐서플로에서는 사전에 학습된 모델을 복원하여 새로운 모델을 학습시키는 데 사용할 수 있다. 텐서플로의 tf.train.Saver클래스를 이용해 학습된 모델을 저장하고 복원할 수 있게 해준다. Saver에 대한 자세한 내용은

[러닝 텐서플로]Chap10.1 - 모델 익스포트와 서빙, Saver에서 확인할 수 있다.

먼저, 텐서플로 모델을 재사용하기 위해 모델을 학습 시키기 위한 코드 부터 작성해보도록 하자.


2.1 학습된 모델 저장하기

아래의 예제 코드는, 5개의 hidden layer로 구성된 MNIST 데이터셋을 분류하는 모델이다. tf.train.Saver를 이용해 학습된 모델을 'my_model.ckpt'에 저장하는 코드이다.

import os
import numpy as np
import tensorflow as tf

# MNIST Load
(train_x, train_y), (test_x, test_y) = tf.keras.datasets.mnist.load_data()

# Train & TestSet reshape
train_x = train_x.astype(np.float32).reshape(-1, 28*28) / 255.
train_y = train_y.astype(np.int32)
test_x = test_x.astype(np.float32).reshape(-1, 28*28) / 255.
test_y = test_y.astype(np.int32)

# Split Validation set from Train set
valid_x, train_x = train_x[:5000], train_x[5000:]
valid_y, train_y = train_y[:5000], train_y[5000:]

# mini-batch
def shuffle_batch(inputs, labels, batch_size):
   rnd_idx = np.random.permutation(len(inputs))
   n_batches = len(inputs) // batch_size
   for batch_idx in np.array_split(rnd_idx, n_batches):
       batch_x, batch_y = inputs[batch_idx], labels[batch_idx]
       yield batch_x, batch_y
       

################
# layer params #
################
n_inputs = 28*28
n_hidden1 = 300
n_hidden2 = 50
n_hidden3 = 50
n_hidden4 = 50
n_hidden5 = 50
n_outputs = 10

# input layer
inputs = tf.placeholder(tf.float32, shape=[None, n_inputs], name="inputs")
# output layer
labels = tf.placeholder(tf.int32, shape=[None], name='labels')

with tf.name_scope('dnn'):
   hidden1 = tf.layers.dense(inputs, n_hidden1, activation=tf.nn.relu, name="hidden1")
   hidden2 = tf.layers.dense(hidden1, n_hidden2, activation=tf.nn.relu, name='hidden2')
   hidden3 = tf.layers.dense(hidden2, n_hidden3, activation=tf.nn.relu, name='hidden3')
   hidden4 = tf.layers.dense(hidden3, n_hidden4, activation=tf.nn.relu, name='hidden4')
   hidden5 = tf.layers.dense(hidden4, n_hidden5, activation=tf.nn.relu, name='hidden5')
   logits = tf.layers.dense(hidden5, n_outputs, name='logits')
   
with tf.name_scope('loss'):
   cross_entropy = tf.reduce_mean(
       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits))
   
################
# Hyper-params #
################
learning_rate = 0.01
n_epochs = 5
batch_size = 50

with tf.name_scope('train'):
   train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)
   
with tf.name_scope('eval'):
   correct = tf.nn.in_top_k(logits, labels, 1)
   accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
   
# Saver 정의
MODEL_PATH = './model/'
saver = tf.train.Saver()

# 모델을 쉽게 재사용 할 수 있도록
# 텐서플로 컬렉션(collection)에 저장
train_vars = {'inputs': inputs, 'labels': labels
             'hiddens1': hidden1, 'hiddens2': hidden2,
             'hiddens3': hidden3, 'hiddens4': hidden4,
             'hiddens5': hidden5, 'logits': logits}

for key, var in train_vars.items():
   tf.add_to_collection(key, var)

# Train
with tf.Session() as sess:
   tf.global_variables_initializer().run()
   
   for epoch in range(n_epochs):
       for batch_x, batch_y in shuffle_batch(train_x, train_y, batch_size):
           sess.run(train_op, feed_dict={inputs: batch_x,
                                         labels:batch_y})
           
       # validation
       accuracy_val = accuracy.eval(feed_dict={inputs: valid_x, labels: valid_y})
       print('epoch: {:02d}, valid. Acc: {:.4f}'.format(epoch, accuracy_val))
   
   # model save
   save_path = saver.save(sess, os.path.join(MODEL_PATH, 'my_model.ckpt'))
   
"""
epoch: 00, valid. Acc: 0.8768
epoch: 01, valid. Acc: 0.9276
epoch: 02, valid. Acc: 0.9462
epoch: 03, valid. Acc: 0.9544
epoch: 04, valid. Acc: 0.9570
"""


2.2 학습된 모델을 이용해 4번째 레이어만 수정하기

이제 '1.1-학습된 모델 저장하기' 에서 저장한 'my_model.ckpt'을 이용해, 4번째 hidden layer의 노드 수를 20개로 수정한 뒤 새로운 모델을 학습시키는 코드이다. 아래의 코드는 위의 코드에서 tf.add_to_collection에 저장한 inputs, labels, hidden3를 불러온 뒤, new_hidden4, new_logits을 추가한 새로운 모델을 학습하여 my_new_model.ckpt에 저장하는 코드이다.

import tensorflow as tf

#################
# layers params #
#################
n_hidden4 = 20  # new hidden
n_outputs = 10  # new output

MODEL_PATH = './model/'
saver = tf.train.import_meta_graph(os.path.join(MODEL_PATH, 'my_model.ckpt.meta'))

inputs = tf.get_default_graph().get_collection('inputs')[0]
labels = tf.get_default_graph().get_collection('labels')[0]

hidden3 = tf.get_default_graph().get_collection('hidden3')[0]

new_hidden4 = tf.layers.dense(hidden3, n_hidden4, activation=tf.nn.relu, name='new_hidden4')
new_logits = tf.layers.dense(new_hidden4, n_outputs, name='new_logits')

with tf.name_scope('new_loss'):
   cross_entropy = tf.reduce_mean(
       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=new_logits))
   
################
# Hyper-params #
################
learning_rate = 0.001
n_epochs = 5
batch_size = 50

with tf.name_scope('new_train'):
   train_op = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
   
with tf.name_scope('new_eval'):
   correct = tf.nn.in_top_k(new_logits, labels, 1)
   accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))

# New Saver
new_saver = tf.train.Saver()
   
# Train the New Model
with tf.Session() as sess:
   tf.global_variables_initializer().run()
   saver.restore(sess, os.path.join(MODEL_PATH, 'my_model.ckpt'))
   
   for epoch in range(n_epochs):
       for batch_x, batch_y in shuffle_batch(train_x, train_y, batch_size):
           sess.run(train_op, feed_dict={inputs: batch_x,
                                         labels: batch_y})
           
       # validation
       accuracy_val = accuracy.eval(feed_dict={inputs: valid_x, labels: valid_y})
       print('epoch: {:02d}, valid. Acc: {:.4f}'.format(epoch, accuracy_val))
   
   # save the new model
   save_path = new_saver.save(sess, os.path.join(MODEL_PATH, 'my_new_model.ckpt'))
   
"""
INFO:tensorflow:Restoring parameters from ./model/my_model.ckpt
epoch: 00, valid. Acc: 0.9548
epoch: 01, valid. Acc: 0.9732
epoch: 02, valid. Acc: 0.9696
epoch: 03, valid. Acc: 0.9746
epoch: 04, valid. Acc: 0.9752
"""



3. 텐서플로를 이용한 Transfer Learning

이번에는 텐서플로를 이용해 '1. Transfer Learning이란'에서 살펴본 Transfer Learning을 구현해보도록 하자. '2.1 학습된 모델 저장하기'의 예제코드를 통해 저장한 'my_model.ckpt'에서 hidden1, hidden2 레이어는 Freezing(동결)한 뒤 재사용 하고, hidden3레이어는 Freezing하지 않고 재사용(즉, 학습시킨 다는 의미)한다. 그리고 마지막으로 hidden4, logits를 새로 만들어 transfer learning을 수행해보자.


3.1 재사용할 레이어 동결(freezing)하는 방법 (1)

우선, 학습시킬 레이어(hidden3, hidden4, logits)와 동결(학습시키지 않을)할 레이어(hidden1, hidden2)를 텐서플로의 tf.get_collection()을 이용하여 다음과 같이 설정해줘야 한다.

  • 학습시킬 레이어(hidden3, hidden4, logits) : tf.get_collection()sope인자에 정규표현식으로 학습시킬 레이어를 아래의 코드처럼 'hidden[34]|logits'라고 지정하면 텐서의 name이 매칭되는 레이어를 찾는다. 그런 다음 optimizer.minimize()var_list인자에 넣어주면 된다.

# 학습시킬 레이러 설정 예시
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                  scope='hidden[34]|logits')  # 정규표현식
train_op = optimizer.minimize(loss, var_list=train_vars)

  • 재사용할 레이어(hidden1~3) : 마찬가지로, tf.get_collection()scope인자에 정규표현식으로 'hidden[123]'을 넣어준 뒤 tf.train.Saver()에 넣어준다.

# 재 사용할 레이어 불러오는 예시
reuse_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                              scope='hidden[123]') # 정규표현식
restore_saver = tf.train.Saver(reuse_vars)

with tf.Session() as sess:
   restore_saver.restore(sess, './model/my_model.ckpt')


이제, 위에서 살펴본 내용을 토대로 재사용할 하위층(low layer)을 동결시킨 후 새로운 레이어를 추가한 새로운 모델을 학습시켜 보자.

n_inputs = 28 * 28  # MNIST
n_hidden1 = 300  # Reusing
n_hidden2 = 50  # Reusing
n_hidden3 = 50  # Reusing
n_hidden4 = 20  # New
n_outputs = 10  # New

inputs = tf.placeholder(tf.float32, shape=[None, n_inputs], name='inputs')
labels = tf.placeholder(tf.int32, shape=[None], name='labels')

with tf.name_scope('dnn'):
   hidden1 = tf.layers.dense(inputs, n_hidden1,
                             activation=tf.nn.relu, name='hidden1')  # Reusing
   hidden2 = tf.layers.dense(hidden1, n_hidden2,
                             activation=tf.nn.relu, name='hidden2')  # Reusing  
   hidden3 = tf.layers.dense(hidden2, n_hidden3,
                             activation=tf.nn.relu, name='hidden3')  # Reusing  
   hidden4 = tf.layers.dense(hidden3, n_hidden4,
                             activation=tf.nn.relu, name='hidden4')  # New  
   logits = tf.layers.dense(hidden4, n_outputs, name='logits')  # new
   
with tf.name_scope('loss'):
   cross_entropy = tf.reduce_mean(
       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits))
   
################
# Hyper-params #
################
learning_rate = 0.01
n_epochs = 5
batch_size = 50

with tf.name_scope('train'):
   optimizer = tf.train.GradientDescentOptimizer(learning_rate)
   train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                  scope='hidden[34]|logits')
   train_op = optimizer.minimize(cross_entropy, var_list=train_vars)
   
with tf.name_scope('eval'):
   correct = tf.nn.in_top_k(logits, labels, 1)
   accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
   
# New Saver 정의
MODEL_PATH = './model/'
new_saver = tf.train.Saver()

# Reusing layer load
reuse_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                              scope='hidden[123]')
restore_saver = tf.train.Saver(reuse_vars)

# Train the New Model
with tf.Session() as sess:
   tf.global_variables_initializer().run()
   restore_saver.restore(sess, os.path.join(MODEL_PATH, 'my_model.ckpt'))
   
   for epoch in range(n_epochs):
       for batch_x, batch_y in shuffle_batch(train_x, train_y, batch_size):
           sess.run(train_op, feed_dict={inputs: batch_x,
                                         labels: batch_y})
           
       # validation
       accuracy_val = accuracy.eval(feed_dict={inputs: valid_x, labels: valid_y})
       print('epoch: {:02d}, valid. Acc: {:.4f}'.format(epoch, accuracy_val))
   
   # save the new model
   save_path = new_saver.save(sess, os.path.join(MODEL_PATH, 'my_transfer_model.ckpt'))
   
'''
INFO:tensorflow:Restoring parameters from ./model/my_model.ckpt
epoch: 00, valid. Acc: 0.9480
epoch: 01, valid. Acc: 0.9516
epoch: 02, valid. Acc: 0.9580
epoch: 03, valid. Acc: 0.9578
epoch: 04, valid. Acc: 0.9584
'''


3.2 재사용할 레이어 동결(freezing)하는 방법 (2)

3.1에서 처럼 optimizer.minimize()var_list의 인자로 학습 시킬 레이어를 지정해주는 방법 말고 tf.stop_gradient()를 사용해 Transfer Learning을 수행할 수 있다. 아래의 예시 코드처럼 동결(freezing)시킬 마지막 레이어(여기서는 hidden2) 바로뒤에 tf.stop_gradient()를 넣어주면 된다.

# tf.stop_gradient()를 사용한 Transfer Learning
hidden2 = tf.layers.dense(hidden1, ...)
hidden2_stop = tf.stop_gradient(hidden2)
hidden3 = tf.layers.dense(hidden2_stop, ...)
# ...


아래의 코드는 3.1의 예제코드를 tf.stop_gradient()를 사용해 작성한 코드이다.

n_inputs = 28 * 28  # MNIST
n_hidden1 = 300  # Reusing
n_hidden2 = 50  # Reusing
n_hidden3 = 50  # Reusing
n_hidden4 = 20  # New
n_outputs = 10  # New

inputs = tf.placeholder(tf.float32, shape=[None, n_inputs], name='inputs')
labels = tf.placeholder(tf.int32, shape=[None], name='labels')

with tf.name_scope('dnn'):
   hidden1 = tf.layers.dense(inputs, n_hidden1,
                             activation=tf.nn.relu, name='hidden1')  # Reusing
   hidden2 = tf.layers.dense(hidden1, n_hidden2,
                             activation=tf.nn.relu, name='hidden2')  # Reusing
   hidden2_stop = tf.stop_gradient(hidden2)  # freezing
   hidden3 = tf.layers.dense(hidden2_stop, n_hidden3,
                             activation=tf.nn.relu, name='hidden3')  # Reusing  
   hidden4 = tf.layers.dense(hidden3, n_hidden4,
                             activation=tf.nn.relu, name='hidden4')  # New  
   logits = tf.layers.dense(hidden4, n_outputs, name='logits')  # new
   
with tf.name_scope('loss'):
   cross_entropy = tf.reduce_mean(
       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits))
   
################
# Hyper-params #
################
learning_rate = 0.01
n_epochs = 5
batch_size = 50

with tf.name_scope('train'):
   train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)
   
with tf.name_scope('eval'):
   correct = tf.nn.in_top_k(logits, labels, 1)
   accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
   
# New Saver 정의
MODEL_PATH = './model/'
new_saver = tf.train.Saver()

# Reusing layer load
reuse_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                              scope='hidden[123]')
restore_saver = tf.train.Saver(reuse_vars)

# Train the New Model
with tf.Session() as sess:
   tf.global_variables_initializer().run()
   restore_saver.restore(sess, os.path.join(MODEL_PATH, 'my_model.ckpt'))
   
   for epoch in range(n_epochs):
       for batch_x, batch_y in shuffle_batch(train_x, train_y, batch_size):
           sess.run(train_op, feed_dict={inputs: batch_x,
                                         labels: batch_y})
           
       # validation
       accuracy_val = accuracy.eval(feed_dict={inputs: valid_x, labels: valid_y})
       print('epoch: {:02d}, valid. Acc: {:.4f}'.format(epoch, accuracy_val))
   
   # save the new model
   save_path = new_saver.save(sess, os.path.join(MODEL_PATH, 'my_transfer_model2.ckpt'))

'''
INFO:tensorflow:Restoring parameters from ./model/my_model.ckpt
epoch: 00, valid. Acc: 0.9504
epoch: 01, valid. Acc: 0.9544
epoch: 02, valid. Acc: 0.9554
epoch: 03, valid. Acc: 0.9562
epoch: 04, valid. Acc: 0.9576
'''


3.3 동결시킨 층 캐싱하기

3.1과 3.2에서 hidden1, hidden2레이어를 재사용함과 동시에 동결(freezing) 시켰는데, 이러한 동결된 레이어는 변하지 않으므로 가장 마지막 동결된 레이어(hidden2)에서 나온 출력을 다음과 캐싱(caching) 할 수 있다.

  1. 전체 Training Set으로 마지막 동결된 레이어 hidden2의 출력을 실행한다. →(충분한 메모리가 있다는 가정하에)

  2. 학습하는 동안 Training Set에 대한 미니배치가 아닌 1에서 출력한 hidden2레이어의 출력에 대해 미니배치를 만든 다음 레이어에 넣어준다.

import numpy as np
import tensorflow as tf

n_inputs = 28 * 28  # MNIST
n_hidden1 = 300  # Reusing
n_hidden2 = 50  # Reusing
n_hidden3 = 50  # Reusing
n_hidden4 = 20  # New
n_outputs = 10  # New

inputs = tf.placeholder(tf.float32, shape=[None, n_inputs], name='inputs')
labels = tf.placeholder(tf.int32, shape=[None], name='labels')

with tf.name_scope('dnn'):
   hidden1 = tf.layers.dense(inputs, n_hidden1,
                             activation=tf.nn.relu, name='hidden1')  # Reusing
   hidden2 = tf.layers.dense(hidden1, n_hidden2,
                             activation=tf.nn.relu, name='hidden2')  # Reusing
   hidden2_stop = tf.stop_gradient(hidden2)  # freezing
   hidden3 = tf.layers.dense(hidden2_stop, n_hidden3,
                             activation=tf.nn.relu, name='hidden3')  # Reusing  
   hidden4 = tf.layers.dense(hidden3, n_hidden4,
                             activation=tf.nn.relu, name='hidden4')  # New  
   logits = tf.layers.dense(hidden4, n_outputs, name='logits')  # new
   
with tf.name_scope('loss'):
   cross_entropy = tf.reduce_mean(
       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits))
   
################
# Hyper-params #
################
learning_rate = 0.01
n_epochs = 5
batch_size = 50

with tf.name_scope('train'):
   train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)
   
with tf.name_scope('eval'):
   correct = tf.nn.in_top_k(logits, labels, 1)
   accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
   
# New Saver 정의
MODEL_PATH = './model/'
new_saver = tf.train.Saver()

# Reusing layer load
reuse_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                              scope='hidden[123]')
restore_saver = tf.train.Saver(reuse_vars)

# Train
n_batches = len(train_x) // batch_size

with tf.Session() as sess:
   tf.global_variables_initializer().run()
   restore_saver.restore(sess, os.path.join(MODEL_PATH, 'my_model.ckpt'))
   
   # Caching
   h2_cache = sess.run(hidden2, feed_dict={inputs: train_x})
   h2_cache_valid = sess.run(hidden2, feed_dict={inputs: valid_x})
   
   for epoch in range(n_epochs):
       # mini-batch for hidden2
       shuffle_idx = np.random.permutation(len(train_x))
       hidden2_batches = np.array_split(h2_cache[shuffle_idx], n_batches)
       label_batches = np.array_split(train_y[shuffle_idx], n_batches)
       for hidden2_batch, label_batch in zip(hidden2_batches, label_batches):
           sess.run(train_op, feed_dict={hidden2: hidden2_batch,
                                         labels: label_batch})
           
       accuracy_val = accuracy.eval(feed_dict={hidden2: h2_cache_valid,
                                               labels: valid_y})
       print('epoch: {:02d}, valid. Acc: {:.4f}'.format(epoch, accuracy_val))
   
   # save the new model
   save_path = new_saver.save(sess, os.path.join(MODEL_PATH, 'my_caching_model.ckpt'))
   
'''
INFO:tensorflow:Restoring parameters from ./model/my_model.ckpt
epoch: 00, valid. Acc: 0.9504
epoch: 01, valid. Acc: 0.9544
epoch: 02, valid. Acc: 0.9554
epoch: 03, valid. Acc: 0.9562
epoch: 04, valid. Acc: 0.9576
'''


4. 마무리

이번 포스팅에서는 Transfer Learning에 대해서 알아보았으며, 텐서플로를 이용하여 사전에 학습된 모델을 재사용하고, Transfer Learning을 수행하는 방법에 대해 알아보았다. 위의 코드에 대한 전체코드는 https://github.com/ExcelsiorCJH/Hands-On-ML/blob/master/Chap11-Training_DNN/Chap11_3-Training_DNN.ipynb 에서 확인할 수 있다.


11 Comments
  • 프로필사진 바밤바 2018.10.12 13:24 재사용을 통해 컴퓨팅 리소스측면에서 개선 되는 부분의 훌륭한 글 감사합니다! 한가지 읽으면서 궁금한 부분은 특정 레이어층을 그대로 사용하게 되면서 학습결과가 오히려 떨어지거나 단점 또한 나타날거 같은데, 이 부분도 설명 첨부 가능하실까요? 항상 좋은 글 잘보고 있습니다 ^^
  • 프로필사진 Favicon of https://excelsior-cjh.tistory.com Excelsior-JH 2018.10.12 15:39 신고 안녕하세요:-)
    특정 레이어층을 그대로(동결, freezing) 사용하는 경우는 새로만들 모델이 사전에 학습된 모델과 비슷한 작업을 수행하는 모델일 때 사용하는 것으로 알고 있습니다.

    만약, Transfer Learning 시에 결과가 좋지 않게 나올 경우에는 동결된 층을 해제한 뒤에 전체 모델을 새롭게 학습 시키는게 더 나을듯 합니다.
  • 프로필사진 Favicon of https://jujuen.tistory.com 글쓰는 엔지니어 2018.10.12 19:30 신고 머신러닝에 관심많은 직장인입니다 ㅎㅎㅎㅎ 글 잘읽었어요 감사해요!!
  • 프로필사진 Favicon of https://excelsior-cjh.tistory.com Excelsior-JH 2018.10.12 20:40 신고 안녕하세요 :-)
    읽어 주셔서 감사합니다 ㅎㅎ
    저도 머신러닝/딥러닝에 관심이 많아 공부하고 있어요 ㅎㅎ
    더 열심히 포스팅 하겠습니다 :-)
  • 프로필사진 바밤바 2018.10.14 15:30 추가 설명 감사합니다 ^.^
  • 프로필사진 대학원생 2018.11.28 18:35 안녕하세요.! 글 정말 잘 읽었습니다! 도움 많이 되었어요!:)

    저도 저렇게 transfer learning 방법을 이용해서 기존 학습된 모델의 변수들을 그대로 사용해서 새로운 변수들을 사용하려고 코드를 구현하고 있습니다.

    여기서 여쭤보고 싶은 게 있는데요, 이전 변수들을 사용해서 새롭게 저장된 new_model.ckpt에는 새로운 변수들과 이전 변수들 모두 같이 저장이 되는건가요? 아님 새로운 변수만 저장이 되나요?

    새로운 변수만 저장이 된다면 이전에 학습된 변수, 이번에 새로 학습한 변수를 나중에 또 사용하고 싶다면 두 개의 체크포인트를 로드해야하는건가요? 그게 궁금합니다..!
  • 프로필사진 Favicon of https://excelsior-cjh.tistory.com Excelsior-JH 2018.11.29 13:35 신고 안녕하세요 도움이 되셨다니 다행이네요 :-)

    음.. 제 생각에는 new_model.ckpt에는 새로운 변수들만 저장될것 같습니다.

    따라서, 새로운 변수만 저장되기 때문에 이전의 변수와 새로운 변수를 사용하고 싶으실 경우에는 별도의 ckpt 파일을 만들어줘야 할 듯합니다 :-)

    혹시 제가 틀렸을 경우 알려 주시기 바랍니다.
    감사합니다 :-)
  • 프로필사진 Favicon of https://data-newbie.tistory.com 분석뉴비 2019.04.27 20:39 신고 좋은 글 감사합니다! 제가 transfer learning이 지식이 없어서 몇가지 질문을 드릴려고 하는데요!

    다름이 아니라 혹시 2.2에서 4번째 layer를 사용하면서 5번째 layer는 없애고 loss를 정의한 것 같은데,
    예를 들어 1234 4` 5 (1,2,3,4,5 는 학습된 layer) 4`는 새로 추가한 layer
    저런식으로도 가능한건가요?

    근데 만약 가능해서 다른 domain에서 학습을 시킬 때 4` 때문에 기존의 학습된 5번째 layer도 학습된 것은 거의 사라지고 새로운 layer 처럼 되버릴까요?

    그래서 학습된 network 뒷단에 새로운 layer를 추가하는 건가요?
    감사합니다!
  • 프로필사진 Favicon of https://excelsior-cjh.tistory.com Excelsior-JH 2019.04.28 10:13 신고 안녕하세요 :-)
    저도 transfer learning에 대한 지식이 많은 편은 아니지만, 질문하신 부분에 대해 답변을 드리자면,

    1. 12344`5 로 네트워크 구성하기
    - 위와 같이 새로운 layer 4` 를 추가하여 모델을 구성할 수 있습니다.

    2. 새로운 도메인에서 학습할 때
    - 위와 같은 경우에 4` layer에 의해 5번째 layer 또한 새롭게 학습 될 듯하며, 5번째 layer를 별도로 freezing 시키고 4` 레이어만 학습을 시킬 수 있긴 하지만 그렇게는 사용하지 않을 듯 합니다.

    감사합니다 :-)
  • 프로필사진 Favicon of https://data-newbie.tistory.com 분석뉴비 2019.04.28 11:13 신고 빠른 답변 정말 감사하고
    잘 정리된 글 정말 감사합니다 :)
    즐거운 주말되세요!
  • 프로필사진 데싸신입 2019.11.18 00:52 혹시 시계열 데이터도 Transfer Learning이 가능할까여?
댓글쓰기 폼