一图看懂tensorflow模型存储和恢复

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/LEEANG121/article/details/102589483

一图看懂tensorflow模型存储和恢复

一图讲解

每次跟随教程进行深度学习模型训练过程中,都要把下载数据,搭建模型,训练模型,预测的过程走一遍,尤其是我们针对同一个数据进行不同方向学习的时候,我们要把一个相同的模型来回跑数次,大量的时间写重复的代码会极大的降低我们的学习积极性,那么如何将我们计算好的模型封装起来,下次遇到相同情况直接调用呢?下面我将结合tensorflow教程,详细的讲述这一过程。

在这里插入图片描述
一图讲解:
从上图可以看出来,我们要想省去重复计算模型的步骤,可以将中间的计算模型封装保存。
保存策略有两个:
1,仅封装权重、偏置,每次需要重新载入数据、建立相同框架结构模型,然后直接将权重参数加载进入模型,进行预测;对应函数为:tf.keras.callbacks.ModelCheckpoint()
2,封装整个模型,下次使用直接调用模型。对应函数为:model.save()

下面代码详细介绍存储过程

仅保存权重和偏置

代码借鉴自tensorflow官方教程
https://tensorflow.google.cn/tutorials/keras/save_and_load
导入tensorflow和依赖项

from __future__ import absolute_import, division, print_function, unicode_literals
import os
import tensorflow as tf
from tensorflow import keras
print(tf.__version__)
2.0.0

下载数据集

(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]   #为了达到快速计算的目的,仅取前1000个数据
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28*28)/255.0   #对数据进行归一化处理
test_images = test_images[:1000].reshape(-1, 28*28)/255.0

定义模型

#定义一个序列模型
def create_model():
  model = tf.keras.models.Sequential([
    keras.layers.Dense(512, activation = 'relu', input_shape=(784,)),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
  ])
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])
  return model
#创建模型实例
model = create_model()

#显示模型结构
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 512)               401920    
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                5130      
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0
_________________________________________________________________

※※训练期间保持模型※※
创建一个只在训练期间保存权重的 tf.keras.callbacks.ModelCheckpoint 回调:

checkpoint_path = "Lee_1/cp.ckpt"    #‘Lee_1’ 是建立在执行文件的相同文件目录下的文件夹,该命令将文件路径给到对象checkpoint_path
checkpoint_dir = os.path.dirname(checkpoint_path)  #设定检测路径

#创建一个保存模型权重的回调,里面的参数包括:文件的存储路径,保存的数据种类,显示的内容
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path, save_weights_only = True,
                                                 verbose = 1)
#使用新的回调训练模型
model.fit(train_images,
          train_labels,
          epochs = 10,
          validation_data = (test_images, test_labels),
          callbacks = [cp_callback] #通过回调训练
# 这可能会生成与保存优化程序状态相关的警告。
# 这些警告(以及整个笔记本中的类似警告)是防止过时使用,可以忽略。
Train on 1000 samples, validate on 1000 samples
Epoch 1/10
832/1000 [=======================>......] - ETA: 0s - loss: 1.2203 - accuracy: 0.6370 
Epoch 00001: saving model to Lee_1/cp.ckpt #Lee_1是新生成的文件夹,位于执行文件同一目录下
1000/1000 [==============================] - 1s 909us/sample - loss: 1.1273 - accuracy: 0.6700 - val_loss: 0.7261 -    val_accuracy: 0.7830
Epoch 2/10
800/1000 [=======================>......] - ETA: 0s - loss: 0.4441 - accuracy: 0.8800
Epoch 00002: saving model to Lee_1/cp.ckpt
1000/1000 [==============================] - 0s 163us/sample - loss: 0.4224 - accuracy: 0.8860 - val_loss: 0.5240 - val_accuracy: 0.8370
Epoch 3/10
800/1000 [=======================>......] - ETA: 0s - loss: 0.2870 - accuracy: 0.9225
Epoch 00003: saving model to Lee_1/cp.ckpt
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

创建一个新的未经训练的模型。仅恢复模型的权重时,必须具有与原始模型具有相同网络结构的模型。由于模型具有相同的结构,您可以共享权重,尽管它是模型的不同实例。
现在重建一个新的未经训练的模型,并在测试集上进行评估。未经训练的模型将在机会水平(chance levels)上执行(准确度约为10%):

#创建模型
model = create_model()   #这个文件时在jupyter note里面接续上面的指令继续建立的,因此可以直接创建文件
# 若新打开任务创建文件,首先需要重新导入数据,其次建立同样的网络结构,然后加载权重参数

#评估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print('Untrained model, accuracy: {:5.2f}%'.format(100*acc))
1000/1 - 0s - loss: 2.4277 - accuracy: 0.0760
Untrained model, accuracy:  7.60%

现在从之前保存的checkpoint加载权重并重新评估

#加载权重
model.load_weights(checkpoint_path) #同上,这里加载了训练好的权重参数

#重新评估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print('Untrained model, accuracy: {:5.2f}%'.format(100*acc))
1000/1 - 0s - loss: 0.4564 - accuracy: 0.8760
Restored model, accuracy: 87.60%

模型的保存方法

手动保存权重

#保存权重
model.save_weights('./checkpoints/my_checkpoint')

#创建模型
model = create_model()

#加载权重
model.load_weights('./checkpoint/my_checkpoint')

#评估模型
loss,acc = model.evaluate(test_images,  test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))

手动保存整个模型
Keras 可以使用 HDF5 标准提供基本保存格式。出于我们的目的,可以将保存的模型视为单个二进制blob:

#创建一个模型
model = create_model()
#训练模型
model.fit(train_images, train_labels, epoch = 5)
#将整个模型保存为HDF5文件
model.save('my_model.h5')   #这里我将保持的文件移动到了'E:/个人文件/学习/文件读取/my_model.h5'

使用模型

#加载模型,相同模型,相同权重及优化方法
new_model = keras.models.load_model('E:/个人文件/学习/文件读取/my_model.h5')
#显示网络结构
new_model.summary()
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_10 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_5 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_11 (Dense)             (None, 10)                5130      
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0

评估

loss, acc = new_model.evaluate(test_images,  test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1 - 0s - loss: 0.4956 - accuracy: 0.8640
Restored model, accuracy: 86.40%

这项技术可以保存一切:
权重
模型配置(结构)
优化器配置
Keras 通过检查网络结构来保存模型。目前,它无法保存 Tensorflow 优化器(调用自 tf.train)。使用这些的时候,您需要在加载后重新编译模型,否则您将失去优化器的状态。

tips
上面创建模型和加载模型的代码都是延续之前的代码继续编写,因此可以直接调用。若新建立任务,需要根据实际情况重新加载数据并创建网络结构(网络结构必须一样)

猜你喜欢

转载自blog.csdn.net/LEEANG121/article/details/102589483
今日推荐