1.模型的整体保存:
这是指将模型的所有东西都保存到一个文件中,包含权重值、模型配置(架构)、优化器配置 。这样,就可以为模型设置检查点,并稍后从完全相同的状态继续训练,无需访问原始代码。
在keras中保存完全可正常使用的模型非常有用,可以在tensorflow.js中加载它们,然后在网络浏览器中训练和运行它们。
keras使用HDF5标准提供基本的保存格式。
model.save('less_model.h5')
#参数为所要保存的路径,格式为h5
#上面这个直接在当前目录下新建了一个less_model的HDF5文件
如果新建了一个模型,要直接加载之前保存的模型:
new_model = tf.keras.models.load_model('less_model.h5')
可以通过查看新模型的架构来验证之前的模型加载是否成功:
new_model.summary()
并且,新模型还可以直接预测、evaluate。
2.保存模型的框架,即代码:
当只对模型的架构感兴趣,而无需保存权重值或优化器。那么可以仅保存模型的“配置”。
首先,先要得到模型的架构:
json_config = model.to_json()
#得到模型的配置数据,返回一个json数据
这个json数据保存的就是model这个模型的架构。
然后,对该模型的架构进行恢复(也可以叫做 重建):
reinitialized_model = tf.keras.models.model_from_json(json_config)
通过显示它的架构来验证:
reinitialized_model.summary()
但这仅仅是一个结构,并没有配置,也没有编译,权重也是随机初始化的。
3.保存模型的权重:
当只需要保存模型的状态(其权重值),而对模型架构不感兴趣时,可以采用这个方法。
Ⅰ.
weights = model.get_weights()
那么就得到了权重weights,它其实是一个array。
然后可以重建一个模型,加载这个权重:
reinitialized_model.set_weights(weights)
可以用以下代码来测试:
reinitialized_model.evaluate(test_image, test_label, verbose=0)
Ⅱ.
keras提供了以下方法可以把权重直接保存在磁盘上:
model.save_weights('less_weights.h5')
当重构模型之后,需要加载此权重时:
reinitialized_model.load_weights('less_weights.h5')
4.使用回调函数对模型进行保存 :
在训练期间或训练结束时自动保存检查点,可以使用经过训练的模型,而不需要重新训练该模型,或从上次暂停的地方继续训练,以防训练过程中段。
使用回调函数:tf.keras.callbacks.ModelCheckpoint
checkpoint_path = 'training_cp/cp.ckpt'
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only = True)#初始化回调函数
第一个参数为filepath,也就是要把检查点保存在哪个路径下面;
参数monitor,表示监控的是什么,比如‘val_loss’;
save_best_only = False为默认设置,若设为True,则每次所监控量的值最低时,会保存它对应的权重;
save_weights_only = False为默认设置,表示保存整个模型,若设为True就只保存权重;
save_freq='epoch’表示保存的频率,默认为每个epoch。
然后需要去创建、编译这个模型。
接着需要训练fit这个模型:
model.fit(train_image, train_labels, epochs=3, callbacks=[cp_callback])
这样在训练过程中,每个epoch结束后都会去保存权重。
当我们需要使用它时:
还是需要进行创建、编译操作,但不用训练了,我们直接去加载这些权重就可以了。
model.load_weights(checkpoint_path)
#从我们保存的路径里面去加载
这样就可以去预测了。
当然,在tf.keras.callbacks.ModelCheckpoint的设置中,也可以设置保存整个模型,加载的方式同1中所示。
5.对于自定义训练中模型的保存:
首先建立一个模型,然后初始化一个optimizer,再建立一个loss_function用来计算loss,然后建立计算loss的函数,再建立一个train_step,再添加metrics模块用来计算训练过程中loss的变化情况和test_loss的变化情况和对应的accuracy的变化情况,然后使用train_image和train_label建立dataset,让他变换一下,然后定义train函数,最后执行这个train函数。
此时需要使用tensorflow内置的保存的方法,在创建dataset之前需要去设置一个保存的目录:
cp_dir = './customtrain_cp'
#设置前缀
cp_prefix = os.path.join(cp_dir, 'ckpt')
然后初始化这个类:
checkpoint = tf.train.Checkpoint(optimizer = optimizer, model = model)
这个函数的参数是需要保存的东西。如果有很多优化器或者模型的话,参数就需要改写成optimizer1 = optimizer1’s name, optimizer2 = optimizer2’s name, …, model1 = model1’s name, model2 = model2’s name, …
在训练过程中,就可以使用checkpoint进行保存,而在自定义训练中,训练实际上是由train()函数进行的,所以train如下:
def train():
for epoch in range(5):
for(batch, (image, labels)) in enumerate(dataset):
train_step(model, images, labels)
print('Epoch{} loss is {}'.format(epoch, train_loss.result()))
print('Epoch{} Accuracy is {}'.format(epoch, train_accuracy.result()))
train_loss.reset_states()
train_accuracy.reset_states()
if (epoch + 1) %2 == 0:
checkpoint.save(file_prefix=cp_prefix)
这样可以每隔2个epoch,就进行保存。
当需要再次使用时,需要运行一下model和对应的optimizer。然后:
tf.train.latest_checkpoint(cp_dir)
此方法可以取出检查点目录下面的最新的检查点。想对这个检查点进行恢复,如下:
checkpoint.restore(tf.train.latest_checkpoint(cp_dir))
此步需要在再次使用时,又定义了checkpoint之后再运行。
可以用以下代码进行验证:
model(train_image, training= False)#不需要训练
因为是自定义循环,所以不能用evaluate去预测,可以直接调用model。
会预测出来长度为10的结果,这里面谁最大,就预测的是,因此:
tf.argmax(model(train_image, training= False), axis=-1).numpy()
再看看是实际的值:
train_label
可以将两者进行对比。
若要计算正确率,可以:
(tf.argmax(model(train_image, training= False), axis=-1).numpy()) == train_label).sum() / len(train_label)
(tf.argmax(model(train_image, training= False), axis=-1).numpy()) == train_label)
这个是一个布尔值,对其进行sum运算,求出正确个数,再除以整个样本个数。