티스토리 뷰

반응형

Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.

Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.

 

아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.

Loading a trained Keras model and continue training

훈련된 Keras 모델을 로드하고 계속 학습시키기

 문제 내용 

I was wondering if it was possible to save a partly trained Keras model and continue the training after loading the model again.

Keras 모델을 일부만 학습시키고, 모델을 저장한 후에 다시 로드해서 학습을 계속 진행할 수 있는지 궁금합니다.

 

The reason for this is that I will have more training data in the future and I do not want to retrain the whole model again.

이는 미래에 더 많은 학습 데이터가 추가될 경우 전체 모델을 다시 학습시키지 않고 추가 데이터만 이용해서 모델을 학습시키고 싶기 때문입니다.

 

The functions which I am using are:

제가 사용하는 함수는 다음과 같습니다:
#Partly train model
model.fit(first_training, first_classes, batch_size=32, nb_epoch=20)

#Save partly trained model
model.save('partly_trained.h5')

#Load partly trained model
from keras.models import load_model
model = load_model('partly_trained.h5')

#Continue training
model.fit(second_training, second_classes, batch_size=32, nb_epoch=20)

Edit 1: added fully working example

편집 1: 동작하는 예제  추가

 

With the first dataset after 10 epochs the loss of the last epoch will be 0.0748 and the accuracy 0.9863.

첫 번째 데이터셋으로 10 에포크를 수행한 후 마지막 에포크의 손실은 0.0748이고 정확도는 0.9863입니다.

 

After saving, deleting and reloading the model the loss and accuracy of the model trained on the second dataset will be 0.1711 and 0.9504 respectively.

모델을 저장, 삭제 및 다시 로드한 후 두 번째 데이터 세트에서 훈련된 모델의 손실과 정확도는 각각 0.1711과 0.9504가 된다.

 

Is this caused by the new training data or by a completely re-trained model?

이는 새로운 학습 데이터 때문인가 아니면 완전히 새롭게 학습한 모델인가요?
"""
Model by: http://machinelearningmastery.com/
"""
# load (downloaded if needed) the MNIST dataset
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.models import load_model
numpy.random.seed(7)

def baseline_model():
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu'))
    model.add(Dense(num_classes, init='normal', activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

if __name__ == '__main__':
    # load data
    (X_train, y_train), (X_test, y_test) = mnist.load_data()

    # flatten 28*28 images to a 784 vector for each image
    num_pixels = X_train.shape[1] * X_train.shape[2]
    X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32')
    X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32')
    # normalize inputs from 0-255 to 0-1
    X_train = X_train / 255
    X_test = X_test / 255
    # one hot encode outputs
    y_train = np_utils.to_categorical(y_train)
    y_test = np_utils.to_categorical(y_test)
    num_classes = y_test.shape[1]

    # build the model
    model = baseline_model()

    #Partly train model
    dataset1_x = X_train[:3000]
    dataset1_y = y_train[:3000]
    model.fit(dataset1_x, dataset1_y, nb_epoch=10, batch_size=200, verbose=2)

    # Final evaluation of the model
    scores = model.evaluate(X_test, y_test, verbose=0)
    print("Baseline Error: %.2f%%" % (100-scores[1]*100))

    #Save partly trained model
    model.save('partly_trained.h5')
    del model

    #Reload model
    model = load_model('partly_trained.h5')

    #Continue training
    dataset2_x = X_train[3000:]
    dataset2_y = y_train[3000:]
    model.fit(dataset2_x, dataset2_y, nb_epoch=10, batch_size=200, verbose=2)
    scores = model.evaluate(X_test, y_test, verbose=0)
    print("Baseline Error: %.2f%%" % (100-scores[1]*100))

Edit 2: tensorflow.keras remarks

편집 2: tensorflow.keras에 대한 비고

 

For tensorflow.keras change the parameter nb_epochs to epochs in the model fit. The imports and basemodel function are:

tensorflow.keras의 경우 모델 fit에서 nb_epochs 매개 변수를 epochs로 변경합니다. imports와 basemodel 함수는 다음과 같습니다:
import numpy
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import load_model


numpy.random.seed(7)

def baseline_model():
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

 

 

 높은 점수를 받은 Solution 

Actually - model.save saves all information need for restarting training in your case. The only thing which could be spoiled by reloading model is your optimizer state. To check that - try to save and reload model and train it on training data.

실제로, model.save는 여러분이 다시 학습을 시작하는 데 필요한 모든 정보를 저장합니다. 모델을 다시 로드하는 것이 옵티마이저 상태를 손상시킬 수 있는데 이를 확인하려면 모델을 저장하고 다시 로드한 후에 훈련 데이터를 사용해서 모델을 훈련해보세요.

 

 

 

 가장 최근 달린 Solution 

Most of the above answers covered important points. If you are using recent Tensorflow (TF2.1 or above), Then the following example will help you. The model part of the code is from Tensorflow website.

위의 대부분 답변에서는 중요한 포인트를 다루고 있습니다. 최근 버전의 Tensorflow(TF2.1 이상)를 사용하는 경우, 다음 예제가 도움이 됩니다. 모델 부분의 코드는 Tensorflow 웹사이트에서 가져온 것입니다.
import tensorflow as tf
from tensorflow import keras
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

def create_model():
  model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(512, activation=tf.nn.relu),  
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
    ])

  model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',metrics=['accuracy'])
  return model

# Create a basic model instance
model=create_model()
model.fit(x_train, y_train, epochs = 10, validation_data = (x_test,y_test),verbose=1)

 

Please save the model in *.tf format. From my experience, if you have any custom_loss defined, *.h5 format will not save optimizer status and hence will not serve your purpose if you want to retrain the model from where we left.

모델을 *.tf 형식으로 저장하세요. 제 경험상, 사용자 정의 손실 함수가 정의되어 있는 경우 *.h5 형식은 옵티마이저 상태를 저장하지 않으므로 모델을 이전 상태에서 다시 학습시키는 목적으로는 적합하지 않습니다.
# saving the model in tensorflow format
model.save('./MyModel_tf',save_format='tf')


# loading the saved model
loaded_model = tf.keras.models.load_model('./MyModel_tf')

# retraining the model
loaded_model.fit(x_train, y_train, epochs = 10, validation_data = (x_test,y_test),verbose=1)

 

This approach will restart the training where we left before saving the model. As mentioned by others, if you want to save weights of best model or you want to save weights of model every epoch you need to use keras callbacks function (ModelCheckpoint) with options such as save_weights_only=True, save_freq='epoch', and save_best_only.

이 방법을 사용하면 모델을 저장한 시점부터 훈련을 재개할 수 있습니다. 다른 분들이 언급한 대로, 최적의 모델 가중치를 저장하거나 각 에포크마다 모델 가중치를 저장하려면 keras 콜백 함수(ModelCheckpoint)를 사용해야 합니다. 이 경우, save_weights_only=True, save_freq='epoch', 그리고 save_best_only 옵션을 사용하세요.

 

For more details, please check here and another example here.

자세한 내용은 여기와 다른 예제를 확인해주세요.

 

 

 

출처 : https://stackoverflow.com/questions/42666046/loading-a-trained-keras-model-and-continue-training

반응형
댓글
공지사항
최근에 올라온 글