Zastanawiałem się, czy da się zapisać częściowo wytrenowany model Keras i kontynuować trening po ponownym załadowaniu modelu.
Powodem tego jest to, że w przyszłości będę miał więcej danych treningowych i nie chcę ponownie trenować całego modelu.
Funkcje, których używam to:
#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)
Edycja 1: dodano w pełni działający przykład
Przy pierwszym zestawie danych po 10 epokach utrata ostatniej epoki wyniesie 0,0748, a dokładność 0,9863.
Po zapisaniu, usunięciu i ponownym załadowaniu modelu utrata i dokładność modelu wytrenowanego na drugim zbiorze danych będzie wynosić odpowiednio 0,1711 i 0,9504.
Czy jest to spowodowane nowymi danymi szkoleniowymi, czy całkowicie ponownie przeszkolonym modelem?
"""
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))
python
tensorflow
neural-network
keras
resuming-training
Wilmar van Ommeren
źródło
źródło
Odpowiedzi:
Właściwie -
model.save
zapisuje wszystkie informacje potrzebne do ponownego uruchomienia szkolenia w Twoim przypadku. Jedyną rzeczą, która może zostać zepsuta przez ponowne załadowanie modelu, jest stan optymalizatora. Aby to sprawdzić - spróbujsave
ponownie załadować model i wytrenować go na danych treningowych.źródło
save()
, zapisuje najlepszy wynik (najmniejszą stratę) modelu, czy też ostatni wynik (ostatnią aktualizację) modelu? dziękisave_best_only=True
jest ustawiony jawnie.Większość z powyższych odpowiedzi dotyczyła ważnych punktów. Jeśli korzystasz z najnowszej wersji Tensorflow (
TF2.1
lub nowszej), pomoże Ci następujący przykład. Modelowa część kodu pochodzi ze strony internetowej 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)
Prosimy o zapisanie modelu w formacie * .tf. Z mojego doświadczenia wynika, że jeśli masz zdefiniowany jakikolwiek custom_loss, format * .h5 nie zapisze statusu optymalizatora, a zatem nie będzie służył twojemu celowi, jeśli chcesz przekwalifikować model z miejsca, w którym zostawiliśmy.
# 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)
Takie podejście spowoduje ponowne uruchomienie szkolenia, które zostawiliśmy przed zapisaniem modelu. Jak wspomniano przez innych, jeśli chcesz zapisać wagi najlepszego modelu lub chcesz zapisać ciężary modelu każdej epoce trzeba użyć Keras callbacks funkcyjny (ModelCheckpoint) z opcjami takimi jak
save_weights_only=True
,save_freq='epoch'
isave_best_only
.Aby uzyskać więcej informacji, sprawdź tutaj i inny przykład tutaj .
źródło
Problem może polegać na tym, że używasz innego optymalizatora - lub innych argumentów do swojego optymalizatora. Po prostu miałem ten sam problem z niestandardowym, wstępnie wytrenowanym modelem, używając
reduce_lr = ReduceLROnPlateau(monitor='loss', factor=lr_reduction_factor, patience=patience, min_lr=min_lr, verbose=1)
dla modelu pretrained, gdzie pierwotny współczynnik uczenia się zaczyna się od 0,0003 i podczas przedtreningowego jest redukowany do min_learning rate, który wynosi 0,000003
Właśnie skopiowałem tę linię do skryptu, który używa wstępnie wytrenowanego modelu i uzyskałem naprawdę złe dokładności. Dopóki nie zauważyłem, że ostatnim tempem uczenia się wstępnie trenowanego modelu był minimalny współczynnik uczenia, czyli 0,000003. A jeśli zacznę od tego współczynnika uczenia się, na początku otrzymam dokładnie takie same dokładności, jak dane wyjściowe wstępnie wytrenowanego modelu - co ma sens, ponieważ zaczyna się od wskaźnika uczenia się, który jest 100 razy większy niż ostatni współczynnik uczenia się używany w model spowoduje ogromne przeregulowanie GD, a tym samym znaczne zmniejszenie dokładności.
źródło
Zauważ, że Keras czasami ma problemy z wczytanymi modelami, jak tutaj . Może to wyjaśniać przypadki, w których nie zaczynasz od tej samej wytrenowanej dokładności.
źródło
Wszystko powyżej pomaga, musisz wznowić od tego samego współczynnika uczenia () co LR, kiedy model i wagi zostały zapisane. Ustaw go bezpośrednio na optymalizatorze.
Należy pamiętać, że poprawa od tego miejsca nie jest gwarantowana, ponieważ model mógł osiągnąć lokalne minimum, które może być globalne. Nie ma sensu wznawiać modelu w celu wyszukania innego lokalnego minimum, chyba że zamierzasz zwiększyć tempo uczenia się w kontrolowany sposób i popchnąć model do możliwie lepszego minimum niedaleko.
źródło
Możesz także uderzać w Concept Drift, zobacz Czy należy ponownie trenować model, gdy dostępne są nowe obserwacje . Jest też koncepcja katastrofalnego zapomnienia, o której mówi wiele artykułów naukowych. Oto jedno z MNIST Empiryczne badanie katastrofalnego zapomnienia
źródło