深度学习 - 模型的保存、读取、重置及添加检查点

这里写自定义目录标题

  • 保存 / 读取整个模型(保留模型架构+权重+优化器配置)
  • 提取模型架构(舍弃权重,及优化器)
  • 提取 / 保存模型权重
  • 在训练期间保存检查点

本片使用 Keras中的fashion_mnist图片数据集

import numpy as np
import matplotlib.pyplot as plt

import tensorflow as tf
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(train_image, train_label), (test_image, test_label) = fashion_mnist.load_data()

# 我们希望把数据集中所有的图片从2维数据,变为3维的数据(增加通道个数)
# 使得通道个数为1(黑白图片)
train_image = np.expand_dims(train_image, axis=-1)

test_image = np.expand_dims(test_image, axis=-1)

然后再随便建立一个卷积神经网络模型,并且把它训练出来

model = tf.keras.Sequential()  # 顺序模型

model.add(
   tf.keras.layers.Conv2D(32, (3, 3), input_shape = train_image.shape[1:], activation='relu'))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))

model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(10, activation='softmax'))

# 优化器(和之前的一样)
model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['acc'])
             
model_fit = model.fit(train_image, train_label, epochs=3)
>>>
Train on 60000 samples
Epoch 1/3
60000/60000 [==============================] - 21s 353us/sample - loss: 0.7068 - acc: 0.7603
Epoch 2/3
60000/60000 [==============================] - 20s 342us/sample - loss: 0.4756 - acc: 0.8349
Epoch 3/3
60000/60000 [==============================] - 20s 340us/sample - loss: 0.4215 - acc: 0.8530

计算正确率

# verbose: 是否打印进度条(0表示不打印,1表示打印)
model.evaluate(test_image, test_label, verbose=0)
# [loss,acc]
>>>[0.4381512819290161, 0.8452]

保存 / 读取整个模型(保留模型架构+权重+优化器配置)

随取随用,调用后既可以继续训练优化,也可以直接用来预测

保存

model.save('21,fashion_mnist图片数据模型(架构+权重+优化器配置).h5')

在这里插入图片描述
读取

load_model = tf.keras.models.load_model('21,fashion_mnist图片数据模型(架构+权重+优化器配置).h5')

可以看出,模型是训练好的,保留了权重

load_model.evaluate(test_image, test_label, verbose=0)
# 可以看出,上边保存的模型保留了权重
>>>[0.4381512819290161, 0.8452]

提取模型架构(舍弃权重,及优化器)

提取模型的框架

json_config = model.to_json()
json_config
>>>'{"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "batch_input_shape": [null, 28, 28, 1], "dtype": "float32", "filters": 32, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "GlobalAveragePooling2D", "config": {"name": "global_average_pooling2d", "trainable": true, "dtype": "float32", "data_format": "channels_last"}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 10, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "keras_version": "2.2.4-tf", "backend": "tensorflow"}'

重建模型:此时的re_model是没有的优化器和权重值的,无法计算正确率或进行预测

# 重建模型(舍弃之前的权重和优化器)
re_model = tf.keras.models.model_from_json(json_config)

要重新构建优化器,才可以进行准去率的计算(此时才是完整的模型)

re_model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['acc'])

可以看出此时模型的正确率只有0.0668,是因为此时的权重值还是随机的,需要提供数据进行训练,提高正确率

re_model.evaluate(test_image, test_label, verbose=0)
# 可以看出正确率很低,因为重建的模型均使用随机初始化权重,还需要重新训练才可以进行预测
>>>[18.993981338500976, 0.0668]

提取 / 保存模型权重

提取权重值

weights = model.get_weights()

使用权重值
这里将经过训练的权重,套用在重置的模型上,可以看出,又恢复了原来的准确率

# 调用经过重置的模型,并且使用上边的权重
re_model.set_weights(weights)
re_model.evaluate(test_image, test_label, verbose=0)
# 可以看出,正确率明显提升
>>>[0.4381512819290161, 0.8452]

存储权重值

model.save_weights('21,fashion_mnist图片数据模型(仅权重).h5')

在这里插入图片描述

读取权重值,并放入re_model模型

re_model.load_weights('21,fashion_mnist图片数据模型(仅权重).h5')

总结
若只保存权重:

  • 则通过 new_model.load_weights(path),将权重添加的新的模型中(若新的模型没有优化器,则只可用于预测)

若保存了整个模型:

  • 则通过 new_model = tf.keras.models.load_model(path) 读取整个模型

在训练期间保存检查点

在训练期间或训练结束时自动保存检查点;
以便于,之后使用经过训练的模型,而无需重新训练模型,或从上次暂停的地方继续训练(有效的防止训练过程中断)。

回调函数:tf.keras.callbacks.ModelCheckpoint()

参数说明:

  • filepath:字符串,保存模型文件的路径。
  • monitor:要监视的数量。
  • verbose:详细模式,0或1。
  • save_best_only:如果“save_best_only=True”,则只保存最牛逼的那个。
  • mode:{auto,min,max}之一。如果“save_best_only=True”,则决定覆盖当前保存文件是基于最大化或者最小化监控量。对于“val_acc”,这个应为“max”,对于“val\u loss”,则应为“min”。
  • save_weights_only:如果为True,则仅保存模型的权重(model.save_weights(filepath)),否则保存完整模型(model.save(filepath))。
  • save_freq:‘epoch’或整数。使用“epoch”时,回调保存每个时代之后的模型。使用整数时,回调将保存一个批次结束时的模型,在该批次中,有如此多的样品被发现最后一次保存。请注意,如果保存未与时间对齐,则监控指标可能不太可靠(它可能反映为只有一批,因为每个历元都会重置指标)。默认为“epoch”
path = '21,回调函数保存的模型/train'
cp_callback = tf.keras.callbacks.ModelCheckpoint(path,
                                                 save_weight_only = True)

只需要给训练语句中的callbacks参数传入刚在设置好的回调函数,就会在训练时存储模型

model.fit(train_image, train_label, epochs=3, callbacks=[cp_callback])
>>>Train on 60000 samples
Epoch 1/3
59968/60000 [============================>.] - ETA: 0s - loss: 0.7375 - acc: 0.7549WARNING:tensorflow:From /opt/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
INFO:tensorflow:Assets written to: 21,回调函数保存的模型/train/assets
60000/60000 [==============================] - 21s 357us/sample - loss: 0.7375 - acc: 0.7550
Epoch 2/3
59904/60000 [============================>.] - ETA: 0s - loss: 0.4797 - acc: 0.8321INFO:tensorflow:Assets written to: 21,回调函数保存的模型/train/assets
60000/60000 [==============================] - 21s 352us/sample - loss: 0.4796 - acc: 0.8321
Epoch 3/3
59872/60000 [============================>.] - ETA: 0s - loss: 0.4196 - acc: 0.8543INFO:tensorflow:Assets written to: 21,回调函数保存的模型/train/assets
60000/60000 [==============================] - 21s 351us/sample - loss: 0.4194 - acc: 0.8543
<tensorflow.python.keras.callbacks.History at 0x7fd34488a950>

截屏2020-09-15 下午9.57.33.png

你可能感兴趣的:(tensorflow,深度学习)