Keras: ¿Cómo guardar el modelo y seguir entrenando?

Tengo un modelo que he entrenado durante 40 épocas. Mantuve puntos de control para cada época, también model.save() el modelo con model.save() . El código para la formación es

 n_units = 1000 model = Sequential() model.add(LSTM(n_units, input_shape=(None, vec_size), return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units)) model.add(Dropout(0.2)) model.add(Dense(vec_size, activation='linear')) model.compile(loss='mean_squared_error', optimizer='adam') # define the checkpoint filepath="word2vec-{epoch:02d}-{loss:.4f}.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # fit the model model.fit(x, y, epochs=40, batch_size=50, callbacks=callbacks_list) 

Sin embargo, cuando se carga el modelo y se vuelve a entrenar, comienza de nuevo como si no se hubiera entrenado anteriormente. La pérdida no comienza desde el último entrenamiento.

Lo que me confunde es que cuando cargue el modelo con la estructura de modelo redefinida y load_weight , el model.predict() funciona bien. Por lo tanto creo que los pesos del modelo están cargados.

 model = Sequential() model.add(LSTM(n_units, input_shape=(None, vec_size), return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units)) model.add(Dropout(0.2)) model.add(Dense(vec_size, activation='linear')) filename = "word2vec-39-0.0027.hdf5" model.load_weights(filename) model.compile(loss='mean_squared_error', optimizer='adam') 

Sin embargo, cuando sigo entrenando con

 filepath="word2vec-{epoch:02d}-{loss:.4f}.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # fit the model model.fit(x, y, epochs=40, batch_size=50, callbacks=callbacks_list) 

La pérdida es tan alta como el estado inicial.

Busqué y encontré algunos ejemplos de cómo guardar y cargar modelos: http://machinelearningmastery.com/save-load-keras-deep-learning-models/ https://github.com/fchollet/keras/issues/1872

Pero ninguno de ellos funciona. ¿Alguien puede ayudarme? Gracias.

Actualizar

Cargando un modelo Keras entrenado y continúa entrenando.

Lo intenté

 model.save('partly_trained.h5') del model load_model('partly_trained.h5') 

funciona. Pero cuando cerré Python, load_model abrir y load_model nuevo. Fracasa. La pérdida es tan alta como el estado inicial.

Actualizar

Probé el código de ejemplo de Yu-Yang. Funciona. Pero volviendo a mi código, todavía he fallado. Este es el entrenamiento original. La segunda época debe comenzar con la pérdida = 3.1 ***.

 13700/13846 [============================>.] - ETA: 0s - loss: 3.0519 13750/13846 [============================>.] - ETA: 0s - loss: 3.0511 13800/13846 [============================>.] - ETA: 0s - loss: 3.0512Epoch 00000: loss improved from inf to 3.05101, saving model to LPT-00-3.0510.h5 13846/13846 [==============================] - 81s - loss: 3.0510 Epoch 2/60 50/13846 [..............................] - ETA: 80s - loss: 3.1754 100/13846 [..............................] - ETA: 78s - loss: 3.1174 150/13846 [..............................] - ETA: 78s - loss: 3.0745 

Cerré Python y lo volví a abrir. Modelo cargado con model = load_model("LPT-00-3.0510.h5") luego entrenar con

 filepath="LPT-{epoch:02d}-{loss:.4f}.h5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # fit the model model.fit(x, y, epochs=60, batch_size=50, callbacks=callbacks_list) 

La pérdida comienza con 4.54.

 Epoch 1/60 50/13846 [..............................] - ETA: 162s - loss: 4.5451 100/13846 [..............................] - ETA: 113s - loss: 4.3835 

Como es bastante difícil aclarar dónde está el problema, creé un ejemplo de juguete a partir de su código y parece que funciona bien.

 import numpy as np from numpy.testing import assert_allclose from keras.models import Sequential, load_model from keras.layers import LSTM, Dropout, Dense from keras.callbacks import ModelCheckpoint vec_size = 100 n_units = 10 x_train = np.random.rand(500, 10, vec_size) y_train = np.random.rand(500, vec_size) model = Sequential() model.add(LSTM(n_units, input_shape=(None, vec_size), return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units)) model.add(Dropout(0.2)) model.add(Dense(vec_size, activation='linear')) model.compile(loss='mean_squared_error', optimizer='adam') # define the checkpoint filepath = "model.h5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # fit the model model.fit(x_train, y_train, epochs=5, batch_size=50, callbacks=callbacks_list) # load the model new_model = load_model("model.h5") assert_allclose(model.predict(x_train), new_model.predict(x_train), 1e-5) # fit the model checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] new_model.fit(x_train, y_train, epochs=5, batch_size=50, callbacks=callbacks_list) 

La pérdida continúa disminuyendo después de cargar el modelo. (reiniciar python tampoco da ningún problema)

 Using TensorFlow backend. Epoch 1/5 500/500 [==============================] - 2s - loss: 0.3216 Epoch 00000: loss improved from inf to 0.32163, saving model to model.h5 Epoch 2/5 500/500 [==============================] - 0s - loss: 0.2923 Epoch 00001: loss improved from 0.32163 to 0.29234, saving model to model.h5 Epoch 3/5 500/500 [==============================] - 0s - loss: 0.2542 Epoch 00002: loss improved from 0.29234 to 0.25415, saving model to model.h5 Epoch 4/5 500/500 [==============================] - 0s - loss: 0.2086 Epoch 00003: loss improved from 0.25415 to 0.20860, saving model to model.h5 Epoch 5/5 500/500 [==============================] - 0s - loss: 0.1725 Epoch 00004: loss improved from 0.20860 to 0.17249, saving model to model.h5 Epoch 1/5 500/500 [==============================] - 0s - loss: 0.1454 Epoch 00000: loss improved from inf to 0.14543, saving model to model.h5 Epoch 2/5 500/500 [==============================] - 0s - loss: 0.1289 Epoch 00001: loss improved from 0.14543 to 0.12892, saving model to model.h5 Epoch 3/5 500/500 [==============================] - 0s - loss: 0.1169 Epoch 00002: loss improved from 0.12892 to 0.11694, saving model to model.h5 Epoch 4/5 500/500 [==============================] - 0s - loss: 0.1097 Epoch 00003: loss improved from 0.11694 to 0.10971, saving model to model.h5 Epoch 5/5 500/500 [==============================] - 0s - loss: 0.1057 Epoch 00004: loss improved from 0.10971 to 0.10570, saving model to model.h5 

Por cierto, la redefinición del modelo seguido de load_weight() definitivamente no funcionará, porque save_weight() y load_weight() no guardan / cargan el optimizador.

Comparé mi código con este ejemplo http://machinelearningmastery.com/text-generation-lstm-recurrent-neural-networks-python-keras/ bloqueando cuidadosamente línea por línea y ejecutando nuevamente. Después de un día entero, finalmente, encontré lo que estaba mal.

Al hacer mapeo char-int, utilicé

 # title_str_reduced is a string chars = list(set(title_str_reduced)) # make char to int index mapping char2int = {} for i in range(len(chars)): char2int[chars[i]] = i 

Un conjunto es una estructura de datos desordenada. En Python, cuando un conjunto se convierte en una lista ordenada, el orden se da aleatoriamente. Por lo tanto, mi diccionario char2int es aleatorio cada vez que vuelvo a abrir python. He arreglado mi código agregando un ordenado ()

 chars = sorted(list(set(title_str_reduced))) 

Esto obliga a la conversión a una orden fija.

Aquí está la documentación oficial de kera para guardar un modelo:

https://keras.io/getting-started/faq/#how-can-i-save-a-keras-model

En esta publicación, el autor proporciona dos ejemplos de cómo guardar y cargar su modelo en un archivo como:

  • Formato JSON.
  • YAML foramt.

Creo que puedes escribir

model.save('partly_trained.h5' )

y

model = load_model('partly_trained.h5') ,

en lugar de

model = Sequential() model.add(LSTM(n_units, input_shape=(None, vec_size), return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(n_units)) model.add(Dropout(0.2)) model.add(Dense(vec_size, activation='linear')) model.compile(loss='mean_squared_error', optimizer='adam') ,

Luego sigue entrenando. Porque model.save almacena tanto architecture como pesos.