web-dev-qa-db-ja.com

トレーニング済みのKerasモデルを読み込んでトレーニングを続行する

部分的にトレーニングされたKerasモデルを保存し、モデルを再度ロードした後にトレーニングを続行することが可能かどうか疑問に思いました。

この理由は、今後さらにトレーニングデータが得られるため、モデル全体を再度トレーニングしたくないためです。

私が使用している機能は次のとおりです。

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

編集1:完全に機能する例を追加

10エポック後の最初のデータセットでは、最後のエポックの損失は0.0748で、精度は0.9863です。

モデルを保存、削除、および再読み込みした後、2番目のデータセットでトレーニングされたモデルの損失と精度は、それぞれ0.1711と0.9504になります。

これは、新しいトレーニングデータまたは完全に再トレーニングされたモデルが原因ですか?

"""
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))
59

実際-model.saveは、あなたのケースでトレーニングを再開するために必要なすべての情報を保存します。モデルのリロードによって損なわれる可能性があるのは、オプティマイザーの状態だけです。それを確認するには、saveを試してモデルをリロードし、トレーニングデータでトレーニングします。

19
Marcin Możejko

問題は、異なるオプティマイザーを使用している可能性があるか、オプティマイザーへの異なる引数を使用している可能性があります。を使用して、カスタムの事前学習済みモデルで同じ問題が発生しました

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

事前学習済みモデルの場合、元の学習率は0.0003から始まり、事前学習中にmin_learning率(0.000003)に減少します。

その行を、事前に訓練されたモデルを使用するスクリプトにコピーしただけで、非常に悪い精度が得られました。事前学習済みモデルの最後の学習率が最小学習率、つまり0.000003であることに気付くまで。そして、その学習率で開始すると、事前学習済みモデルの出力とまったく同じ精度が得られます-これは、事前学習済みで使用された最後の学習率の100倍の学習率で開始するので理にかなっていますこのモデルでは、Gdの大きなオーバーシュートが発生するため、精度が大幅に低下します。

4
Wolfgang

here のように、Kerasにはロードされたモデルに問題がある場合があることに注意してください。これは、同じ訓練された精度から始めない場合を説明するかもしれません。

2
shahar_m

上記のすべてが助けになりますmustモデルと重みが保存されたときにLRと同じ学習率()から再開します。オプティマイザーで直接設定します。

モデルがグローバルである可能性があるローカル最小値に達している可能性があるため、そこからの改善は保証されないことに注意してください。制御された方法で学習率を上げ、モデルを遠くない範囲でより良い最小値にナッジするつもりでない限り、別のローカル最小値を検索するためにモデルを再開する意味はありません。

1
flowgrad

また、コンセプトドリフトにヒットしている可能性があります。 を参照してください。新しい観測値が利用可能になったときにモデルを再トレーニングする必要があります 。壊滅的な忘却の概念もありますが、これは多くの学術論文で議論されています。 MNISTの1つ 壊滅的な忘却の実証的調査

0
Gustavo