web-dev-qa-db-fra.com

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

Je me demandais s'il était possible de sauvegarder un modèle Keras partiellement formé et de poursuivre la formation après avoir chargé le modèle à nouveau.

La raison en est que je disposerai de plus de données de formation à l'avenir et que je ne souhaite pas recycler à nouveau l'ensemble du modèle.

Les fonctions que j'utilise sont:

#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: ajouté un exemple pleinement fonctionnel

Avec le premier jeu de données après 10 périodes, la perte de la dernière période sera de 0,0748 et la précision de 0,9863.

Après avoir enregistré, supprimé et rechargé le modèle, la perte et la précision du modèle formé sur le deuxième jeu de données seront respectivement de 0,1711 et 0,9504.

Est-ce causé par les nouvelles données de formation ou par un modèle complètement recyclé?

"""
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 __== '__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))
50

En fait - model.save enregistre toutes les informations nécessaires au redémarrage de la formation dans votre cas. La seule chose qui pourrait être gâchée par le rechargement du modèle est l'état de votre optimiseur. Pour vérifier cela - essayez de save et de recharger le modèle et de le former sur les données d'apprentissage.

13
Marcin Możejko

Notez que Keras a parfois des problèmes avec les modèles chargés, comme dans ici ..__ Ceci peut expliquer les cas dans lesquels vous ne partez pas de la même précision entraînée.

2
shahar_m

Le problème peut être que vous utilisez un optimiseur différent - ou des arguments différents pour votre optimiseur. Je viens d'avoir le même problème avec un modèle personnalisé pré-entrainé, en utilisant 

reduce_lr = ReduceLROnPlateau(monitor='loss', factor=lr_reduction_factor,
                              patience=patience, min_lr=min_lr, verbose=1)

pour le modèle de pré-entraînement, où le taux d'apprentissage initial commence à 0,0003 et est réduit au pré-entraînement au taux de min_learning, qui est 0,000003

Je viens de copier cette ligne dans le script, qui utilise le modèle pré-formé et qui offre des précisions vraiment mauvaises. Jusqu’à ce que j’ai remarqué que le dernier taux d’apprentissage du modèle pré-entraîné était le taux d’apprentissage minimal, c’est-à-dire 0,000003. Et si je commence avec ce taux d'apprentissage, j'obtiens exactement la même précision que le résultat du modèle pré-entraîné - ce qui est logique, à commencer par un taux d'apprentissage 100 fois plus grand que le dernier taux utilisé dans le modèle pré-entraîné. modèle entraînera un énorme dépassement de D.ieu et par conséquent une précision fortement diminuée. 

2
Wolfgang

Vous pouvez également frapper Concept Drift, voir Si vous réentraînez un modèle lorsque de nouvelles observations sont disponibles . Il y a aussi le concept d'oubli catastrophique qui est discuté par un groupe de travaux universitaires. En voici un avec MNIST Enquête empirique sur l'oubli catastrophique

0
Gustavo

Tout ce qui précède aide, vous devez reprendre le même taux d’apprentissage () que le LR lorsque le modèle et les poids ont été enregistrés. Réglez-le directement sur l'optimiseur. 

Notez que l'amélioration à partir de là n'est pas garantie, car le modèle peut avoir atteint le minimum local, qui peut être global. Il ne sert à rien de reprendre un modèle afin de rechercher un autre minimum local, à moins que vous n'entendiez augmenter le taux d'apprentissage de manière contrôlée et déplacer le modèle dans un minimum probablement meilleur non loin.

0
flowgrad