Eğitimli bir Keras modeli yükleme ve eğitime devam etme


102

Kısmen eğitilmiş bir Keras modelini kurtarmanın ve modeli tekrar yükledikten sonra eğitime devam etmenin mümkün olup olmadığını merak ediyordum.

Bunun nedeni, gelecekte daha fazla eğitim verisine sahip olacağım ve tüm modeli yeniden eğitmek istemiyorum.

Kullandığım işlevler:

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

Düzenleme 1: tamamen çalışan bir örnek eklendi

10 dönemden sonraki ilk veri kümesiyle, son dönemin kaybı 0,0748 ve doğruluk 0,9863 olacaktır.

Modeli kaydettikten, sildikten ve yeniden yükledikten sonra, ikinci veri setinde eğitilen modelin kaybı ve doğruluğu sırasıyla 0.1711 ve 0.9504 olacaktır.

Bu, yeni eğitim verilerinden mi yoksa tamamen yeniden eğitilmiş bir modelden mi kaynaklanıyor?

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

3
Test ettin mi? Bunun işe yaramaması için bir neden göremiyorum.
maz

Şimdi gördüğüm şey, model yüklendikten sonra doğruluğumun yaklaşık yüzde 10 düştüğüdür (sadece ilk çağlarda). Yeniden yükleme işe yararsa, bu elbette yeni eğitim verilerinden kaynaklanır. Ama ben sadece durumun gerçekten böyle olduğundan emin olmak istiyorum.
Wilmar van Ommeren

7
Modelinizi doğrudan model.save ile mi kaydediyorsunuz yoksa bir model kontrol noktası mı kullanıyorsunuz ( keras.io/callbacks/#example-model-checkpoints )? Model.save kullanıyorsanız, en iyisi (en düşük hata) yerine en son modeli (yani son dönemi) kaydetme şansınız olur mu? Gerçek kodu sağlayabilir misiniz?
maz

En son modelimi kurtarıyorum, en iyisini değil (bu noktaya kadar bunun mümkün olduğunu bilmiyordum). Biraz kod hazırlayacağım
Wilmar van Ommeren

3
Yani onu yeniden yükleyip aynı tren verileri üzerinde eğitime devam edemez miydiniz? Bu, sonuçların karşılaştırılabilir olması durumunda yeniden yüklemenin tamam olduğunu garanti etmelidir.
Marcin Możejko

Yanıtlar:


36

Aslında - model.savedurumunuzda eğitimi yeniden başlatmak için gereken tüm bilgileri kaydeder. Modeli yeniden yükleyerek bozulabilecek tek şey, optimize edici durumunuzdur. Bunu kontrol etmek için - savemodeli yeniden yüklemeyi ve onu eğitim verileri üzerinde eğitmeyi deneyin .


1
@Marcin: keras'ı kullanırken, modelin save()en iyi sonucunu (en düşük kayıp) veya modelin son sonucunu (son güncelleme) kaydeder mi? teşekkürler
Lion Lai

5
son Güncelleme. Model kontrol noktası geri araması, en iyisini kaydetmek içindir.
Holi

2
@Khaj Bu keras.io/callbacks/#modelcheckpoint'ten bahsediyor musunuz ? Varsayılan olarak görünür, son güncellemeyi kaydeder (en iyisini değil); en iyisi yalnızca save_best_only=Trueaçıkça ayarlanmışsa kaydedilir .
flow2k

9

Yukarıdaki cevapların çoğu önemli noktaları kapsıyordu. En son Tensorflow'u ( TF2.1veya üstünü) kullanıyorsanız, aşağıdaki örnek size yardımcı olacaktır. Kodun model kısmı Tensorflow web sitesinden alınmıştır.

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)

Lütfen modeli * .tf formatında kaydedin. Deneyimlerime göre, tanımlanmış herhangi bir custom_loss varsa, * .h5 formatı optimize edici durumunu kaydetmeyecek ve bu nedenle modeli kaldığımız yerden yeniden eğitmek istiyorsanız amacınıza hizmet etmeyecektir.

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

Bu yaklaşım, modeli kaydetmeden önce bıraktığımız eğitimi yeniden başlatacak. Başkaları tarafından belirtildiği gibi en iyi modelin ağırlıkları kazanmak ya, sen modelin ağırlıkları aşağıdaki gibi seçeneklerle keras geri aramaları fonksiyonu (ModelCheckpoint) kullanmak için gereken her devrin kaydetmek istediğiniz save_weights_only=True, save_freq='epoch've save_best_only.

Daha fazla ayrıntı için kontrol edin burada ve başka bir örnek burada .


1
güzel, bu çok umut verici görünüyor - bilgi için teşekkürler. Bu örnekte, bana, eğitim için kullanılan aynı veriler üzerinde modeli yeniden eğitiyorsunuz gibi görünüyor. eğer öyleyse, doğru yaklaşımın yeniden eğitim için yeni bir eğitim verisi alt kümesini yüklemek olacağını düşünürdüm (sürece dahil edilen yeni bilgileri yansıtmak için)?
bibzzzz

1
@bibzzzz Size katılıyorum. Çok güzel bir yorum. Performansı iyileştirmek için aynı veriler üzerinde yeniden eğitim yapıldığını göstermek istedim. Özet, modeli kaydetmeden önce durdurulduğu yerde performanstaki iyileşmeyi açıkça gösterir. Farklı veriler üzerinde yeniden eğitim almanız konusunda size tamamen katılıyorum ve daha sonra deneyeceğim. Teşekkürler!
Vishnuvardhan Janapati

1
mükemmel - bunu çok güzel bir şekilde gösterdin, teşekkürler.
bibzzzz

8

Sorun, farklı bir optimize edici veya optimize ediciniz için farklı argümanlar kullanmanız olabilir. Aynı sorunu özel bir önceden eğitilmiş modelle yaşadım.

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

orijinal öğrenme oranının 0.0003'te başladığı ve eğitim öncesi sırasında 0.000003 olan min_learning oranına düşürüldüğü önceden eğitilmiş model için

Bu satırı önceden eğitilmiş modeli kullanan ve gerçekten kötü doğruluklara sahip olan senaryoya kopyaladım. Önceden eğitilmiş modelin son öğrenme oranının minimum öğrenme oranı olduğunu fark edene kadar, yani 0.000003. Ve bu öğrenme oranıyla başlarsam, önceden eğitilmiş modelin çıktısı ile başlamak için tam olarak aynı doğrulukları elde ederim - bu, önceden eğitilmiş modelde kullanılan son öğrenme oranından 100 kat daha büyük bir öğrenme oranıyla başlamak gibi mantıklıdır. modeli, GD'nin büyük bir aşımına ve dolayısıyla büyük ölçüde azalmış doğruluklara neden olacaktır.


2

Keras'ın burada olduğu gibi bazen yüklü modellerle sorunları olduğuna dikkat edin . Bu, aynı eğitimli doğrulukla başlamadığınız durumları açıklayabilir.


1

Yukarıdakilerin tümü yardımcı olur, model ve ağırlıklar kaydedildiğinde LR ile aynı öğrenme hızından () devam etmelisiniz . Doğrudan optimize edici üzerinde ayarlayın.

Oradan iyileştirmenin garanti edilmediğini unutmayın, çünkü model global olabilecek yerel minimuma ulaşmış olabilir. Kontrollü bir şekilde öğrenme oranını artırmayı ve modeli çok uzakta olmayan, muhtemelen daha iyi bir minimuma indirmeyi amaçlamadığınız sürece, başka bir yerel minimum aramak için bir modeli devam ettirmenin bir anlamı yoktur.


Neden? Öncekinden daha küçük bir LR kullanamaz mıyım?
lte__

Aslında, devam eden eğitim daha fazla veri alırsanız sizi daha iyi bir modele götürebilir. Dolayısıyla, başka bir yerel minimumu aramak için bir modeli sürdürmenin bir anlamı vardır.
Corey Levinson

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.