摘要:这篇文章将解说 TensorFlow 如何保留变量和神经网络参数,通过 Saver 保留神经网络,再通过 Restore 调用训练好的神经网络。
本文分享自华为云社区《[[Python 人工智能] 十一.Tensorflow 如何保留神经网络参数 丨【百变 AI 秀】](https://bbs.huaweicloud.com/b…)》,作者:eastmount。
一. 保留变量
通过 tf.Variable()定义权重和偏置变量,而后调用 tf.train.Saver()存储变量,将数据保留至本地“my_net/save_net.ckpt”文件中。
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 2 20:04:57 2020
@author: xiuzhang Eastmount CSDN
"""
import tensorflow as tf
import numpy as np
#--------------------------------------- 保留文件 ---------------------------------------
W = tf.Variable([[1,2,3], [3,4,5]], dtype=tf.float32, name='weights') #2 行 3 列的数据
b = tf.Variable([[1,2,3]], dtype=tf.float32, name='biases')
# 初始化
init = tf.initialize_all_variables()
# 定义 saver 存储各种变量
saver = tf.train.Saver()
# 应用 Session 运行初始化
with tf.Session() as sess:
sess.run(init)
# 保留 官网保留格局为 ckpt
save_path = saver.save(sess, "my_net/save_net.ckpt")
print("Save to path:", save_path)
“Save to path: my_net/save_net.ckpt”保留胜利如下图所示:
关上内容如下图所示:
接着定义标记变量 train,通过 Restore 操作应用咱们保留好的变量。留神,在 Restore 时须要定义雷同的 dtype 和 shape,不须要再定义 init。最初间接通过 saver.restore(sess,“my_net/save_net.ckpt”) 提取保留的变量并输入即可。
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 2 20:04:57 2020
@author: xiuzhang Eastmount CSDN
"""
import tensorflow as tf
import numpy as np
# 标记变量
train = False
#--------------------------------------- 保留文件 ---------------------------------------
# Save
if train==True:
# 定义变量
W = tf.Variable([[1,2,3], [3,4,5]], dtype=tf.float32, name='weights') #2 行 3 列的数据
b = tf.Variable([[1,2,3]], dtype=tf.float32, name='biases')
# 初始化
init = tf.global_variables_initializer()
# 定义 saver 存储各种变量
saver = tf.train.Saver()
# 应用 Session 运行初始化
with tf.Session() as sess:
sess.run(init)
# 保留 官网保留格局为 ckpt
save_path = saver.save(sess, "my_net/save_net.ckpt")
print("Save to path:", save_path)
#---------------------------------------Restore 变量 -------------------------------------
# Restore
if train==False:
# 记住在 Restore 时定义雷同的 dtype 和 shape
# redefine the same shape and same type for your variables
W = tf.Variable(np.arange(6).reshape((2,3)), dtype=tf.float32, name='weights') #空变量
b = tf.Variable(np.arange(3).reshape((1,3)), dtype=tf.float32, name='biases') #空变量
# Restore 不须要定义 init
saver = tf.train.Saver()
with tf.Session() as sess:
# 提取保留的变量
saver.restore(sess, "my_net/save_net.ckpt")
# 寻找雷同名字和标识的变量并存储在 W 和 b 中
print("weights", sess.run(W))
print("biases", sess.run(b))
运行代码,如果报错“NotFoundError: Restoring from checkpoint failed. This is most likely due to a Variable name or other graph key that is missing from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint.”,则须要重置 Spyder 即可。
最初输入之前所保留的变量,weights 为 [[1,2,3], [3,4,5]],偏置为 [[1,2,3]]。
二. 保留神经网络
那么,TensorFlow 如何保留咱们的神经网络框架呢?咱们须要把整个网络训练好再进行保留,其办法和下面相似,残缺代码如下:
"""
Created on Sun Dec 29 19:21:08 2019
@author: xiuzhang Eastmount CSDN
"""
import os
import glob
import cv2
import numpy as np
import tensorflow as tf
# 定义图片门路
path = 'photo/'
#--------------------------------- 第一步 读取图像 -----------------------------------
def read_img(path):
cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]
imgs = []
labels = []
fpath = []
for idx, folder in enumerate(cate):
# 遍历整个目录判断每个文件是不是合乎
for im in glob.glob(folder + '/*.jpg'):
#print('reading the images:%s' % (im))
img = cv2.imread(im) #调用 opencv 库读取像素点
img = cv2.resize(img, (32, 32)) #图像像素大小统一
imgs.append(img) #图像数据
labels.append(idx) #图像类标
fpath.append(path+im) #图像路径名
#print(path+im, idx)
return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
# 读取图像
fpaths, data, label = read_img(path)
print(data.shape) # (1000, 256, 256, 3)
# 计算有多少类图片
num_classes = len(set(label))
print(num_classes)
# 生成等差数列随机调整图像程序
num_example = data.shape[0]
arr = np.arange(num_example)
np.random.shuffle(arr)
data = data[arr]
label = label[arr]
fpaths = fpaths[arr]
# 拆分训练集和测试集 80% 训练集 20% 测试集
ratio = 0.8
s = np.int(num_example * ratio)
x_train = data[:s]
y_train = label[:s]
fpaths_train = fpaths[:s]
x_val = data[s:]
y_val = label[s:]
fpaths_test = fpaths[s:]
print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200
print(y_val)
#--------------------------------- 第二步 建设神经网络 -----------------------------------
# 定义 Placeholder
xs = tf.placeholder(tf.float32, [None, 32, 32, 3]) #每张图片 32*32* 3 个点
ys = tf.placeholder(tf.int32, [None]) #每个样本有 1 个输入
# 寄存 DropOut 参数的容器
drop = tf.placeholder(tf.float32) #训练时为 0.25 测试时为 0
# 定义卷积层 conv0
conv0 = tf.layers.conv2d(xs, 20, 5, activation=tf.nn.relu) #20 个卷积核 卷积核大小为 5 Relu 激活
# 定义 max-pooling 层 pool0
pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2]) #pooling 窗口为 2x2 步长为 2x2
print("Layer0:\n", conv0, pool0)
# 定义卷积层 conv1
conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu) #40 个卷积核 卷积核大小为 4 Relu 激活
# 定义 max-pooling 层 pool1
pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2]) #pooling 窗口为 2x2 步长为 2x2
print("Layer1:\n", conv1, pool1)
# 将 3 维特色转换为 1 维向量
flatten = tf.layers.flatten(pool1)
# 全连贯层 转换为长度为 400 的特征向量
fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)
print("Layer2:\n", fc)
# 加上 DropOut 避免过拟合
dropout_fc = tf.layers.dropout(fc, drop)
# 未激活的输入层
logits = tf.layers.dense(dropout_fc, num_classes)
print("Output:\n", logits)
# 定义输入后果
predicted_labels = tf.arg_max(logits, 1)
#--------------------------------- 第三步 定义损失函数和优化器 ---------------------------------
# 利用穿插熵定义损失
losses = tf.nn.softmax_cross_entropy_with_logits(labels = tf.one_hot(ys, num_classes), #将 input 转化为 one-hot 类型数据输入
logits = logits)
# 均匀损失
mean_loss = tf.reduce_mean(losses)
# 定义优化器 学习效率设置为 0.0001
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)
#------------------------------------ 第四步 模型训练和预测 -----------------------------------
# 用于保留和载入模型
saver = tf.train.Saver()
# 训练或预测
train = False
# 模型文件门路
model_path = "model/image_model"
with tf.Session() as sess:
if train:
print("训练模式")
# 训练初始化参数
sess.run(tf.global_variables_initializer())
# 定义输出和 Label 以填充容器 训练时 dropout 为 0.25
train_feed_dict = {
xs: x_train,
ys: y_train,
drop: 0.25
}
# 训练学习 1000 次
for step in range(1000):
_, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
if step % 50 == 0: #每隔 50 次输入一次后果
print("step = {}\t mean loss = {}".format(step, mean_loss_val))
# 保留模型
saver.save(sess, model_path)
print("训练完结,保留模型到{}".format(model_path))
else:
print("测试模式")
# 测试载入参数
saver.restore(sess, model_path)
print("从 {} 载入模型".format(model_path))
# label 和名称的对照关系
label_name_dict = {
0: "人类",
1: "沙滩",
2: "修建",
3: "公交",
4: "恐龙",
5: "大象",
6: "花朵",
7: "野马",
8: "雪山",
9: "美食"
}
# 定义输出和 Label 以填充容器 测试时 dropout 为 0
test_feed_dict = {
xs: x_val,
ys: y_val,
drop: 0
}
# 实在 label 与模型预测 label
predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
# 将 label id 转换为 label 名
real_label_name = label_name_dict[real_label]
predicted_label_name = label_name_dict[predicted_label]
print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
# 评估后果
print("正确预测个数:", sum(y_val==predicted_labels_val))
print("准确度为:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))
外围步骤为:
saver = tf.train.Saver()
model_path = "model/image_model"
with tf.Session() as sess:
if train:
#保留神经网络
sess.run(tf.global_variables_initializer())
for step in range(1000):
_, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
if step % 50 == 0:
print("step = {}\t mean loss = {}".format(step, mean_loss_val))
saver.save(sess, model_path)
else:
#载入神经网络
saver.restore(sess, model_path)
predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
real_label_name = label_name_dict[real_label]
predicted_label_name = label_name_dict[predicted_label]
print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
预测输入后果如下图所示,最终预测正确 181 张图片,准确度为 0.905。相比之前机器学习 KNN 的 0.500 有十分高的晋升。
测试模式
INFO:tensorflow:Restoring parameters from model/image_model
从 model/image_model 载入模型
b'photo/photo/3\\335.jpg' 公交 => 公交
b'photo/photo/1\\129.jpg' 沙滩 => 沙滩
b'photo/photo/7\\740.jpg' 野马 => 野马
b'photo/photo/5\\564.jpg' 大象 => 大象
...
b'photo/photo/9\\974.jpg' 美食 => 美食
b'photo/photo/2\\220.jpg' 修建 => 公交
b'photo/photo/9\\912.jpg' 美食 => 美食
b'photo/photo/4\\459.jpg' 恐龙 => 恐龙
b'photo/photo/5\\525.jpg' 大象 => 大象
b'photo/photo/0\\44.jpg' 人类 => 人类
正确预测个数: 181
准确度为: 0.905
点击关注,第一工夫理解华为云陈腐技术~