web-dev-qa-db-fra.com

Keras: Comment sauvegarder le modèle et continuer la formation?

J'ai un modèle que j'ai formé pour 40 époques. J'ai gardé des points de contrôle pour chaque époque et enregistré le modèle avec model.save(). Le code de formation est

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)

Cependant, lorsque vous chargez le modèle et que vous vous entraînez à nouveau, tout recommence comme s'il n'avait pas été formé auparavant. La perte ne commence pas à partir du dernier entraînement.

Ce qui me trouble, c'est que lorsque je charge un modèle avec la redéfinition de la structure du modèle et de load_weight, la model.predict() fonctionne bien. Ainsi, je crois que les poids du modèle sont chargés.

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')

Cependant, quand je continue à m'entraîner avec

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 perte est aussi élevée que l'état initial.

J'ai cherché et trouvé des exemples d'enregistrement et de chargement de modèles: http://machinelearningmastery.com/save-load-keras-deep-learning-models/https://github.com/fchollet/keras/ numéros/1872

Mais aucun d'entre eux ne fonctionne. Quelqu'un peut-il m'aider? Merci.

Mise à jour

Chargement d'un modèle Keras formé et poursuite de la formation

J'ai essayé

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

Ça marche. Mais quand j'ai fermé python, rouvrez et load_model à nouveau. Il échoue. La perte est aussi élevée que l'état initial.

Mise à jour

J'ai essayé l'exemple de code de Yu-Yang. Ça marche. Mais revenons à mon code, j'ai encore échoué. Ceci est la formation d'origine. La deuxième époque devrait commencer avec une perte = 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

J'ai fermé Python et l'ai rouvert. Modèle chargé avec model = load_model("LPT-00-3.0510.h5") puis entraînez-vous avec

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 perte commence avec 4.54.

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

Comme il est assez difficile de clarifier où se situe le problème, j'ai créé un exemple de jouet à partir de votre code, et il semble bien fonctionner.

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 perte continue de diminuer après le chargement du modèle. (le redémarrage de python ne pose également aucun problème)

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

BTW, redéfinir le modèle suivi de load_weight() ne fonctionnera certainement pas, car save_weight() et load_weight() ne sauvegardera/chargera pas l'optimiseur.

14
Yu-Yang

J'ai comparé mon code avec cet exemple http://machinelearningmastery.com/text-generation-lstm-recurrent-neural-networks-python-keras/ En bloquant soigneusement ligne par ligne et en relançant . Après une journée entière, finalement, j'ai trouvé ce qui n'allait pas.

Lors de la cartographie char-int, j'ai utilisé 

# 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 ensemble est une structure de données non ordonnée. En python, lorsqu'un ensemble est converti en une liste ordonnée, l'ordre est donné de manière aléatoire. Ainsi, mon dictionnaire char2int est randomisé à chaque fois que je rouvre python. J'ai corrigé mon code en ajoutant un sort ()

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

Cela force la conversion à un ordre fixe. 

1
David

Voici la documentation officielle de kera pour enregistrer un modèle:

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

Dans cet article l'auteur fournit deux exemples d'enregistrement et de chargement de votre modèle dans un fichier en tant que:

  • Format JSON. 
  • YAML foramt.
0
Anubhav Apurva