24- 深度学习的模型保存和加载 (TensorFlow系列) (深度学习)
Posted 处女座_三月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了24- 深度学习的模型保存和加载 (TensorFlow系列) (深度学习)相关的知识,希望对你有一定的参考价值。
知识要点
keras 保存成hdf5文件, 1.保存模型和参数, 2.只保存参数
- 1.保存模型和参数
- save_model
- callback ModelCheckpoint
- 2. 只保存参数
- save_weights
- callback ModelCheckpoint save_weights_only = True
保存模型:
- 案例数据: Fashion-MNIST总共有十个类别的图像
- model.save_weights(os.path.join(logdir, 'fashion_mnist_weights_2.h5')) # 保存参数的方法
- 加载参数: model.load_weights(os.path.join(logdir, 'fashion_mnist_weight.h5'))
- 保存模型: model.save(os.path.join(logdir, 'fashion_mnist_model.h5'))
- 加载模型: model2 = keras.models.load_model(os.path.join(logdir, 'fashion_mnist_model.h5'))
- 把keras模型保存成savedmodel格式: tf.saved_model.save(model, './keras_saved_model')
一 模型保存和部署
- TFLite是为了将深度学习模型部署在移动端和嵌入式设备的工具包,可以把训练好的TF模型通过转化、部署和优化三个步骤,达到提升运算速度,减少内存、显存占用的效果。
- TFlite主要由Converter和Interpreter组成。Converter负责把TensorFlow训练好的模型转化,并输出为.tflite文件(FlatBuffer格式)。转化的同时,还完成了对网络的优化,如量化。Interpreter则负责把.tflite部署到移动端,嵌入式(embedded linux device)和microcontroller,并高效地执行推理过程,同时提供API接口给Python,Objective-C,Swift,Java等多种语言。简单来说,Converter负责打包优化模型,Interpreter负责高效易用地执行推理。
-
Fashion-MNIST总共有十个类别的图像。每一个类别由训练数据集6000张图像和测试数据集1000张图像。所以训练集和测试集分别包含60000张和10000张。测试训练集用于评估模型的性能。
-
每一个输入图像的高度和宽度均为28像素。数据集由灰度图像组成。Fashion-MNIST,中包含十个类别,分别是t-shirt,trouser,pillover,dress,coat,sandal,shirt,sneaker,bag,ankle boot。
1.1 模型创建
- 导包
# 导包
from tensorflow import keras
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
- 时尚数据导入
# 时尚数据导入
fashion_mnist = keras.datasets.fashion_mnist
(x_train_all, y_train_all), (x_test, y_test) = fashion_mnist.load_data()
x_valid, x_train = x_train_all[:5000], x_train_all[5000:]
y_valid, y_train = y_train_all[:5000], y_train_all[5000:]
- 标准化
# 标准化
from sklearn.preprocessing import StandardScaler # preprocessing 预处理
scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train.astype(np.float32).reshape(-1, 784))
x_valid_scaled = scaler.fit_transform(x_valid.astype(np.float32).reshape(-1, 784))
x_test_scaled = scaler.fit_transform(x_test.astype(np.float32).reshape(-1, 784))
- 创建模型
# 创建模型
model = keras.models.Sequential([keras.layers.Dense(512, activation = 'relu', input_shape = (784, )),
keras.layers.Dense(256, activation = 'relu'),
keras.layers.Dense(128, activation = 'relu'),
keras.layers.Dense(10, activation = 'softmax')])
model.compile(loss = 'sparse_categorical_crossentropy',
optimizer = 'adam',
metrics = ['accuracy'])
1.2 保存模型
# 保存模型
import os
logdir = './graph_def_and_weights'
if not os.path.exists(logdir):
os.mkdir(logdir)
output_model_file = os.path.join(logdir, 'fashion_mnist_weight.h5')
callbacks = [keras.callbacks.TensorBoard(logdir), # 保存地址
# 保存效果最好的模型: save_best_only
keras.callbacks.ModelCheckpoint(output_model_file,
save_best_only = True,
save_weights_only = True),
keras.callbacks.EarlyStopping(patience = 5, min_delta = 1e-3)]
history = model.fit(x_train_scaled, y_train, epochs = 10,
validation_data= (x_valid_scaled, y_valid),
callbacks = callbacks)
- 保存模型
# 保存模型
output_model_file2 = os.path.join(logdir, 'fashion_mnist_model.h5')
model.save(output_model_file2)
-
保存参数
# 另一种保存参数的方法
model.save_weights(os.path.join(logdir, 'fashion_mnist_weights_2.h5'))
- 模型评估
# evaluate 评估
model.evaluate(x_valid_scaled, y_valid) # [0.35909169912338257, 0.88919997215271]
- 模型加载
# 加载模型
model2 = keras.models.load_model(output_model_file2)
model2.evaluate(x_valid_scaled, y_valid) # [0.35909169912338257, 0.88919997215271]
二 保存模型为savemodel格式
# 把keras模型保存成savedmodel格式
tf.saved_model.save(model, './keras_saved_model')
- 读取模型
# 加载savedmodel模型
loaded_saved_model = tf.saved_model.load('./keras_saved_model')
loaded_saved_model
2.1 另一种保存
# 保存模型
import os
logdir = './graph_def_and_weights'
if not os.path.exists(logdir):
os.mkdir(logdir)
output_model_file = os.path.join(logdir, 'fashion_mnist_weight.h5')
model.load_weights(output_model_file)
三 tflite_interpreter 的使用
- 导包
from tensorflow import keras
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
import os
with open('./tflite_models/concrete_func_tf_lite', 'rb') as f:
concrete_func_tflite = f.read()
- 创建interpreter
# 创建interpreter
interpreter = tf.lite.Interpreter(model_content = concrete_func_tflite)
# 分配内存
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
- 预测数值
input_data = tf.constant(np.ones(input_details[0]['shape'], dtype = np.float32))
# 传入预测数据
interpreter.set_tensor(input_details[0]['index'], input_data)
# 执行预测
interpreter.invoke()
# 获取输出
output_results = interpreter.get_tensor(output_details[0]['index'])
print(output_results)
四 to_concrete_function
- 加载文件
# 从文件加载
loaded_keras_model = keras.models.load_model('./graph_def_and_weights/fashion_mnist_model.h5')
loaded_keras_model(np.ones((1, 784)))
- 把keras模型转化为concrete function
# 把keras模型转化为concrete function
run_model = tf.function(lambda x: loaded_keras_model(x))
keras_concrete_func = run_model.get_concrete_function(tf.TensorSpec(loaded_keras_model.inputs[0].shape,
loaded_keras_model.inputs[0].dtype))
# 使用
keras_concrete_func(tf.constant(np.ones((1, 784), dtype = np.float32)))
五 to_quantized_tflite
5.1 keras to tflite
# 从文件加载
loaded_keras_model = keras.models.load_model('./graph_def_and_weights/fashion_mnist_model.h5')
loaded_keras_model
# lite 精简版模型 # 创建转化器
keras_to_tflite_converter = tf.lite.TFLiteConverter.from_keras_model(loaded_keras_model)
keras_to_tflite_converter
# 给converter添加量化的优化 # 把32位的浮点数变成8位整数
keras_to_tflite_converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
# 执行转化
keras_tflite = keras_to_tflite_converter.convert()
# 写入指定文件
import os
if not os.path.exists('./tflite_models'):
os.mkdir('./tflite_models')
with open('./tflite_models/quantized_keras_tflite', 'wb') as f:
f.write(keras_tflite)
5.2 concrete function to tflite
# 把keras模型转化成concrete function
run_model = tf.function(lambda x: loaded_keras_model(x))
keras_concrete_func = run_model.get_concrete_function(tf.TensorSpec(loaded_keras_model.inputs[0].shape,
loaded_keras_model.inputs[0].dtype))
concrete_func_to_tflite_converter = tf.lite.TFLiteConverter.from_concrete_functions([keras_concrete_func])
concrete_func_to_tflite_converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
concrete_func_tflite = concrete_func_to_tflite_converter.convert()
with open('./tflite_models/quantized_concrete_func_tf_lite', 'wb') as f:
f.write(concrete_func_tflite)
5.3 saved_model to tflite
saved_model_to_tflite_converter = tf.lite.TFLiteConverter.from_saved_model('./keras_saved_model/')
saved_model_to_tflite_converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
saved_model_tflite = saved_model_to_tflite_converter.convert()
with open('./tflite_models/quantized_saved_model_tflite', 'wb') as f:
f.write(saved_model_tflite)
深度学习基础:7.模型的保存与加载/学习率调度
模型的保存与加载
模型的保存和加载,本质上都是针对模型的参数。
模型参数
在Pytorch中,可以使用state_dict()
查看模型的参数信息。
例如:
输入
model.state_dict()
输出
OrderedDict([('linear1.weight',
tensor([[ 0.2365, -0.1118, -0.3801, 0.0275, 0.4168],
[-0.1995, -0.1456, 0.3497, -0.0622, -0.1708],
[-0.0901, 0.0164, -0.3643, -0.1278, 0.4336],
[-0.0959, 0.4073, -0.1746, -0.1799, -0.1333]])),
('linear1.bias', tensor([-0.3999, -0.2694, 0.2703, -0.3355])),
('normalize1.weight', tensor([1., 1., 1., 1.])),
('normalize1.bias', tensor([0., 0., 0., 0.])),
('normalize1.running_mean', tensor([0., 0., 0., 0.])),
('normalize1.running_var', tensor([1., 1., 1., 1.])),
('normalize1.num_batches_tracked', tensor(0)),
('linear2.weight',
tensor([[ 0.1708, 0.4704, -0.0635, 0.2187],
[ 0.2336, -0.3569, -0.1928, -0.1566],
[ 0.4825, -0.4463, 0.3027, 0.4696],
[ 0.3953, 0.2131, 0.2226, -0.0267]])),
('linear2.bias', tensor([ 0.2516, 0.4558, -0.1608, 0.4831])),
('normalize2.weight', tensor([1., 1., 1., 1.])),
('normalize2.bias', tensor([0., 0., 0., 0.])),
('normalize2.running_mean', tensor([0., 0., 0., 0.])),
('normalize2.running_var', tensor([1., 1., 1., 1.])),
('normalize2.num_batches_tracked', tensor(0)),
('linear3.weight',
tensor([[ 0.0795, -0.3507, -0.3589, 0.1764]])),
('linear3.bias', tensor([-0.0705]))])
模型保存
torch.save(tanh_model1.state_dict(), 'best_model.pt')
- 参数1:模型参数
- 参数2:保存名称
模型加载
model.load_state_dict('best_model.pt')
学习率调度
学习率调度指的是在模型训练的过程中,动态调整学习率。我们可以通过调用Pytorch中optim
模块下的lr_scheduler
相关函数,来实现优化器中学习率的动态调整。
假设,优化器中的lr伴随模型迭代相应调整的方法如下:
l
r
=
l
r
_
l
a
m
b
d
a
(
e
p
o
c
h
)
∗
i
n
i
t
i
a
l
_
l
r
lr = lr\\_lambda(epoch) * initial\\_lr
lr=lr_lambda(epoch)∗initial_lr
并且,第一次实例化LambdaLR时epoch取值为0时,因此此时优化器的lr计算结果如下: l r 0 = 0. 5 0 ∗ 0.05 = 0.05 lr_0 = 0.5^0 * 0.05 = 0.05 lr0=0.50∗0.05=0.05
构造动态调整规则:
lr_lambda = lambda epoch: 0.5 ** epoch
完整使用实例:在第四节构造的模型上进行添加
import torch
import torch.nn as nn
import torch.optim as optim
from torch.nn import functional as F
from torch.optim import lr_scheduler
lr_lambda = lambda epoch: 0.5 ** epoch
torch.manual_seed(103)
X = torch.rand((500,20),dtype=torch.float32) * 100
y = torch.randint(low=0,high=3,size=(500,),dtype=torch.float32)
lr = 0.1 # 学习率
gamma = 0.9 # 动量
class Model(nn.Module):
def __init__(self,in_features=10,out_features=2):
super(Model,self).__init__()
self.linear1 = nn.Linear(in_features,13,bias=True)
self.linear2 = nn.Linear(13,8,bias=True)
self.output = nn.Linear(8,out_features,bias=True)
def forward(self, x):
sigma1 = torch.relu(self.linear1(x))
sigma2 = torch.sigmoid(self.linear2(sigma1))
zhat = self.output(sigma2)
return zhat
input_ = X.shape[1] #特征的数目
output_ = len(y.unique()) #分类的数目
net = Model(in_features=input_, out_features=output_) #实例化网络
criterion = nn.CrossEntropyLoss() #定义损失函数
optimizer = torch.optim.SGD(net.parameters(), lr=0.05) # 创建优化器
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda) # 创建学习率调度器
yhat = net.forward(X)
loss = criterion(yhat, y.long()) #计算损失函数
loss.backward()
optimizer.step() #走一步,更新权重w,更新动量v
optimizer.zero_grad() #清除原来储存好的,基于上一个坐标点计算的梯度,为下一次计算梯度腾出空间
scheduler.step()
以上是关于24- 深度学习的模型保存和加载 (TensorFlow系列) (深度学习)的主要内容,如果未能解决你的问题,请参考以下文章
[深度学习] Pytorch—— 多/单GPUCPU,训练保存加载模型参数问题