首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >加载经过训练的Keras模型并继续训练

加载经过训练的Keras模型并继续训练
EN

Stack Overflow用户
提问于 2017-03-08 16:07:58
回答 7查看 100.5K关注 0票数 123

我想知道是否有可能保存一个部分训练的Keras模型,并在再次加载该模型后继续训练。

这样做的原因是,我将来会有更多的训练数据,我不想再次重新训练整个模型。

我使用的函数是:

代码语言:javascript
复制
#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。

在保存、删除和重新加载模型后,在第二个数据集上训练的模型的损失和准确率将分别为0.1711和0.9504。

这是由新的训练数据还是完全重新训练的模型引起的?

代码语言:javascript
复制
"""
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: tensorflow.keras备注

对于tensorflow.keras,在模型拟合中将参数nb_epochs更改为epochs。imports和basemodel函数是:

代码语言:javascript
复制
import numpy
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import load_model


numpy.random.seed(7)

def baseline_model():
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2017-03-08 19:45:28

实际上- model.save在您的案例中保存了重新开始培训所需的所有信息。唯一可能被重新加载模型破坏的是您的优化器状态。要检查这一点-请尝试save并重新加载模型,并在训练数据上对其进行训练。

票数 45
EN

Stack Overflow用户

发布于 2020-04-06 13:37:38

上面的大多数答案都涵盖了重要的几点。如果您使用的是最新的Tensorflow (TF2.1或更高版本),那么下面的示例将对您有所帮助。代码的模型部分来自Tensorflow网站。

代码语言:javascript
复制
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)

请将模型保存为*.tf格式。根据我的经验,如果您定义了任何custom_loss,*.h5格式将不会保存优化器状态,因此,如果您想要从我们离开的地方重新训练模型,将不会达到您的目的。

代码语言:javascript
复制
# 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)

这种方法将在保存模型之前从我们离开的地方重新开始训练。正如其他人所提到的,如果你想保存最佳模型的权重,或者你想保存每个时期的模型权重,你需要使用keras回调函数(ModelCheckpoint)以及save_weights_only=Truesave_freq='epoch'save_best_only等选项。

更多详细信息,请查看here和另一个示例here

票数 25
EN

Stack Overflow用户

发布于 2017-12-28 23:53:37

问题可能是您使用了不同的优化器-或者优化器的参数不同。我用一个自定义的预训练模型也遇到了同样的问题,使用

代码语言:javascript
复制
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的巨大超调,从而导致精度严重下降。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42666046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档