2017-03-08 28 views
24

訓練された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 __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)) 
+2

テストしましたか?私はそれが働かない理由はないと思う。 – maz

+0

私が今見ているのは、モデルを読み込んだ後の精度が約10%低下することです(最初のエポックでのみ)。再ロードが機能する場合、これはもちろん新しいトレーニングデータによって引き起こされます。しかし、私はちょうどこれが本当に事実であることを確実にしたい。 –

+5

モデルをmodel.saveに直接保存しているのですか、モデルチェックポイント(https://keras.io/callbacks/#example-model-checkpoints)を使用していますか? model.saveを使用している場合は、最新のモデル(つまり、最後のエポック)を最良のもの(最低エラー)ではなく保存する可能性はありますか?実際のコードを提供できますか? – maz

答えて

9

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

+0

@Marcin:ケラス 'save()'を使用すると、モデルの最良の結果(最低損失)またはモデルの最終結果(最終更新)が保存されますか?ありがとうございました –

+0

最終更新。モデルチェックポイントコールバックは、最良のものを保存するためのものです。 – Khaj

2

ケラスには、hereのように、読み込みモデルに問題があることがあります。 これは、同じ訓練された精度から開始しない場合を説明します。

-1

異なるオプティマイザを使用しているか、オプティマイザに異なる引数を使用している可能性があります。私は、元の学習率は0.0003で始まり、事前にトレーニング中にそれは0.000003

あるmin_learning率に低減されるpretrainedモデル、のために

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

を使用して、カスタムpretrainedモデルと同じ問題を持っていました

私は、あらかじめ訓練されたモデルを使用し、実際には不正確さを持つスクリプトにその行をコピーしました。私は、事前学習モデルの最後の学習率が最小学習率、すなわち0.000003であることに気付くまで、その学習率から始めれば、事前訓練されたモデルの出力と同じ正確さが得られます。これは、事前訓練されたモデルで使用された最後の学習率の100倍の学習率から始まりますモデルはGDの巨大なオーバーシュートをもたらし、ひいては大幅に減少した精度になる。

関連する問題