Laden Sie ein trainiertes Keras-Modell und setzen Sie das Training fort

95

Ich habe mich gefragt, ob es möglich ist, ein teilweise trainiertes Keras-Modell zu speichern und das Training fortzusetzen, nachdem das Modell erneut geladen wurde.

Der Grund dafür ist, dass ich in Zukunft mehr Trainingsdaten haben werde und nicht das gesamte Modell erneut trainieren möchte.

Die Funktionen, die ich benutze, sind:

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

Bearbeiten 1: voll funktionsfähiges Beispiel hinzugefügt

Mit dem ersten Datensatz nach 10 Epochen beträgt der Verlust der letzten Epoche 0,0748 und die Genauigkeit 0,9863.

Nach dem Speichern, Löschen und erneuten Laden des Modells beträgt der Verlust und die Genauigkeit des im zweiten Datensatz trainierten Modells 0,1711 bzw. 0,9504.

Wird dies durch die neuen Trainingsdaten oder durch ein komplett neu trainiertes Modell verursacht?

"""
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))
Wilmar van Ommeren
quelle
3
Hast du es getestet? Ich sehe keine Gründe dafür, nicht zu funktionieren.
Maz
Was ich jetzt sehe, ist, dass meine Genauigkeit nach dem Laden des Modells (nur in den ersten Epochen) um etwa 10 Prozent abnimmt. Wenn das Nachladen funktioniert, wird dies natürlich durch die neuen Trainingsdaten verursacht. Aber ich möchte nur sicherstellen, dass dies tatsächlich der Fall ist.
Wilmar van Ommeren
6
Speichern Sie Ihr Modell direkt mit model.save oder verwenden Sie einen Modellprüfpunkt ( keras.io/callbacks/#example-model-checkpoints )? Wenn Sie model.save verwenden, besteht die Möglichkeit, dass Sie das neueste Modell (dh die letzte Epoche) anstelle des besten (niedrigster Fehler) speichern? Können Sie tatsächlichen Code bereitstellen?
Maz
Ich speichere mein neuestes Modell, nicht das beste (bis zu diesem Punkt wusste ich nicht, dass dies möglich ist). Ich werde einen Code vorbereiten
Wilmar van Ommeren
3
Könnten Sie das nicht neu laden und mit denselben Zugdaten weiter trainieren? Dies sollte Ihnen versichern, dass das Nachladen in Ordnung ist, wenn die Ergebnisse vergleichbar wären.
Marcin Możejko

Antworten:

36

Eigentlich - model.savespeichert alle Informationen, die für den Neustart des Trainings in Ihrem Fall erforderlich sind. Das einzige, was durch das Neuladen des Modells beeinträchtigt werden könnte, ist Ihr Optimierungsstatus. Um dies zu überprüfen, versuchen Sie, das saveModell neu zu laden und es auf Trainingsdaten zu trainieren.

Marcin Możejko
quelle
1
@Marcin: Speichert es bei Verwendung von Keras save()das beste Ergebnis (geringster Verlust) des Modells oder das letzte Ergebnis (letzte Aktualisierung) des Modells? danke
Lion Lai
4
letztes Update. Der Model Checkpoint Callback dient zum Speichern des besten.
Holi
2
@Khaj Beziehen Sie sich auf diesen keras.io/callbacks/#modelcheckpoint ? Standardmäßig wird das letzte Update gespeichert (nicht das beste). Das beste wird nur gespeichert, wenn save_best_only=Truees explizit festgelegt ist.
flow2k
7

Das Problem könnte sein, dass Sie einen anderen Optimierer verwenden - oder andere Argumente für Ihren Optimierer. Ich hatte gerade das gleiche Problem mit einem benutzerdefinierten vorab trainierten Modell

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

für das vorab trainierte Modell, bei dem die ursprüngliche Lernrate bei 0,0003 beginnt und während des Vortrainings auf die min_learning-Rate reduziert wird, die 0,000003 beträgt

Ich habe diese Zeile gerade in das Skript kopiert, das das vorab trainierte Modell verwendet und wirklich schlechte Genauigkeiten erzielt hat. Bis ich bemerkte, dass die letzte Lernrate des vorab trainierten Modells die minimale Lernrate war, dh 0,000003. Und wenn ich mit dieser Lernrate beginne, erhalte ich zunächst genau die gleichen Genauigkeiten wie die Ausgabe des vorab trainierten Modells - was sinnvoll ist, da ich mit einer Lernrate beginne, die 100-mal höher ist als die zuletzt im vorab trainierten Lernrate Das Modell führt zu einem großen Überschwingen der GD und damit zu stark verringerten Genauigkeiten.

Wolfgang
quelle
5

Die meisten der oben genannten Antworten deckten wichtige Punkte ab. Wenn Sie den neuesten Tensorflow ( TF2.1oder höher) verwenden, hilft Ihnen das folgende Beispiel. Der Modellteil des Codes stammt von der Tensorflow-Website.

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)

Bitte speichern Sie das Modell im * .tf-Format. Wenn Sie nach meiner Erfahrung einen benutzerdefinierten Verlust definiert haben, speichert das * .h5-Format den Optimierungsstatus nicht und erfüllt daher nicht Ihren Zweck, wenn Sie das Modell von der Stelle, an der wir abgereist sind, neu trainieren möchten.

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

Dieser Ansatz startet das Training dort neu, wo wir es verlassen haben, bevor das Modell gespeichert wird. Wie bereits von anderen erwähnt, wenn Sie Gewichte der beste Modell speichern möchten oder Sie Gewichte Modell benötigen Sie jede Epoche speichern keras Rückrufe Funktion (ModelCheckpoint) mit Optionen wie zu verwenden save_weights_only=True, save_freq='epoch'und save_best_only.

Weitere Details finden Sie hier und ein weiteres Beispiel hier .

Vishnuvardhan Janapati
quelle
1
schön, das sieht sehr vielversprechend aus - danke für die info. In diesem Beispiel scheint es mir, als würden Sie das Modell mit denselben Daten umschulten, die für das Training verwendet wurden. Wenn ja, hätte ich gedacht, dass der richtige Ansatz darin besteht, eine neue Teilmenge von Trainingsdaten zu laden, um sie weiterzubilden (um die neuen Informationen widerzuspiegeln, die in den Prozess eingeführt werden)?
bibzzzz
1
@bibzzzz Stimme dir zu. Sehr guter Kommentar. Ich wollte eine Umschulung derselben Daten demonstrieren, um die Leistung zu verbessern. Das Wesentliche zeigt deutlich eine Verbesserung der Leistung, wenn sie vor dem Speichern des Modells gestoppt wurde. Ich würde Ihnen voll und ganz zustimmen, verschiedene Daten neu zu trainieren und werde es später versuchen. Vielen Dank!
Vishnuvardhan Janapati
ausgezeichnet - Sie haben dies sehr schön demonstriert, danke.
Bibzzzz
2

Beachten Sie, dass Keras manchmal Probleme mit geladenen Modellen hat, wie hier . Dies könnte Fälle erklären, in denen Sie nicht mit der gleichen trainierten Genauigkeit beginnen.

shahar_m
quelle
1

Alles oben Genannte hilft, Sie müssen mit derselben Lernrate () wie der LR fortfahren, als das Modell und die Gewichte gespeichert wurden. Stellen Sie es direkt auf dem Optimierer ein.

Beachten Sie, dass eine Verbesserung von dort nicht garantiert werden kann, da das Modell möglicherweise das lokale Minimum erreicht hat, das global sein kann. Es macht keinen Sinn, ein Modell fortzusetzen, um nach einem anderen lokalen Minimum zu suchen, es sei denn, Sie möchten die Lernrate auf kontrollierte Weise erhöhen und das Modell in ein möglicherweise besseres Minimum in der Nähe bringen.

flowgrad
quelle
Warum ist das so? Kann ich kein kleineres LR als zuvor verwenden?
lte__
Wenn Sie mehr Daten erhalten, können Sie durch Weiterbildung zu einem besseren Modell gelangen. Es ist also sinnvoll, ein Modell fortzusetzen, um nach einem anderen lokalen Minimum zu suchen.
Corey Levinson