我想知道是否可以保存部分训练有素的凯拉斯模型并在再次加载模型后继续训练。
这样做的原因是我将来会有更多的培训数据,而我不想再次重新训练整个模型。
我使用的功能是:
#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。
这是由新的培训数据引起的还是完全重新训练的模型?
"""
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更改为模型拟合中的时期。导入和基本模型函数是:
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
实际上-model.save
在您的情况下保存了重新启动培训的所有信息。重新加载模型唯一可以破坏的是您的优化器状态。要检查一下 - 尝试使用save
并重新加载模型并在培训数据上进行训练。
以上大多数答案涵盖了重要点。如果您使用的是最近的TensorFlow(TF2.1
或更高版本),则以下示例将为您提供帮助。代码的模型部分来自TensorFlow网站。
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格式将无法保存优化器状态,因此,如果您想从我们离开的位置重新训练该模型。
# 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回调函数(modelscheckpoint),以及诸如 save_weights_only=True
, save_freq='epoch'
和 save_best_only
。
有关更多详细信息,请在此处查看另一个示例。
问题可能是您使用其他优化器或对优化器的不同参数。我使用
的自定义预估计模型也遇到了同样的问题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过冲,因此精确降低了。
请注意,Keras有时会出现已加载模型的问题,如此处。这可能解释了您不会从相同训练的准确性开始的情况。
您可能还会碰到概念漂移,请参见您在可用的新观测值时是否重新训练模型。还有一个灾难性遗忘的概念,其中一堆学术论文讨论了。这是对灾难性遗忘的MNIST实证研究
上面的所有帮助,您必须从与LR相同的学习率()简历(保存模型和权重时)。将其直接设置在优化器上。
请注意,没有保证的改进,因为该模型可能已经达到了本地最低限度,这可能是全球性的。除非您打算以受控的方式提高学习率并将模型推向可能不远的更好的最低限度。
如果您使用的是TF2,请使用新的SAVED_MODEL方法(格式PB)。这里和这里可用的更多信息。
model.fit(x=X_train, y=y_train, epochs=10,callbacks=[model_callback])#your first training
tf.saved_model.save(model, save_to_dir_path) #save the model
del model #to delete the model
model = tf.keras.models.load_model(save_to_dir_path)
model.fit(x=X_train, y=y_train, epochs=10,callbacks=[model_callback])#your second training
用保存模型训练模型是完全可以的。我用相同的数据培训了保存的模型,发现它具有良好的准确性。此外,每个时期的时间都少了。
这是代码有一个外观:
from keras.models import load_model
model = load_model('/content/drive/MyDrive/CustomResNet/saved_models/model_1.h5')
history=model.fit(train_gen,validation_data=valid_gen,epochs=5)