2017-2019年计算机视觉顶会文章收录 AAAI2017-2019 CVPR2017-2019 ECCV2018 ICCV2017-2019 ICLR2017-2019 NIPS2017-2019
目录
1.保存提取ckpt文件
保存ckpt
保存得到4个文件
- checkpoint文件保存了模型文件列表
- model.ckpt.meta保存了TensorFlow计算图的结构信息
- model.ckpt保存每个变量的取值,此处文件名的写入方式会因不同参数的设置而不同
- 加载restore时的文件路径名是以checkpoint文件中的“model_checkpoint_path”值决定
# 通过tf.train.Saver类实现保存和载入神经网络模型
# 执行本段程序时注意当前的工作路径
import tensorflow as tf
v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1")
v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2")
result = v1 + v2
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
saver.save(sess, "Model/model.ckpt")
提取ckpt
# 加载TensorFlow模型的方法
import tensorflow as tf
v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1")
v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2")
result = v1 + v2
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, "./Model/model.ckpt") # 注意此处路径前添加"./"
print(sess.run(result)) # [ 3.]
# 若不希望重复定义计算图上的运算,可直接加载已经持久化的图
import tensorflow as tf
saver = tf.train.import_meta_graph("Model/model.ckpt.meta")
with tf.Session() as sess:
saver.restore(sess, "./Model/model.ckpt") # 注意路径写法
print(sess.run(tf.get_default_graph().get_tensor_by_name("add:0"))) # [ 3.]
# tf.train.Saver类也支持在保存和加载时给变量重命名
import tensorflow as tf
# 声明的变量名称name与已保存的模型中的变量名称name不一致
u1 = tf.Variable(tf.constant(1.0, shape=[1]), name="other-v1")
u2 = tf.Variable(tf.constant(2.0, shape=[1]), name="other-v2")
result = u1 + u2
# 若直接生命Saver类对象,会报错变量找不到
# 使用一个字典dict重命名变量即可,{"已保存的变量的名称name": 重命名变量名}
# 原来名称name为v1的变量现在加载到变量u1(名称name为other-v1)中
saver = tf.train.Saver({"v1": u1, "v2": u2})
with tf.Session() as sess:
saver.restore(sess, "./Model/model.ckpt")
print(sess.run(result)) # [ 3.]
2.保存提取pb文件
保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。
模型的变量都会变成固定的,导致模型的大小会大大减小,适合在手机端运行。
保存pb
import tensorflow as tf
import os
from tensorflow.python.framework import graph_util
pb_file_path = os.getcwd() #获取当前代码路径
with tf.Session(graph=tf.Graph()) as sess: #保存pb代码结构一定要在with里面写,不能写在with上面
x = tf.placeholder(tf.int32, name='x') #输入名称,此处是成败的关键
y = tf.placeholder(tf.int32, name='y') #输入名称,此处是成败的关键
b = tf.Variable(1, name='b')
xy = tf.multiply(x, y)
# 这里的输出需要加上name属性
op = tf.add(xy, b, name='op_to_store') #输出名称,此处是成败的关键
sess.run(tf.global_variables_initializer())
# convert_variables_to_constants 需要指定output_node_names,list(),可以多个
# 此处务必和前面的输入输出对应上,其他的不用管
constant_graph = graph_util.convert_variables_to_constants(
sess, sess.graph_def, ['x','y','op_to_store']) # 保存图中的变量
# 测试 OP
feed_dict = {x: 10, y: 3}
print(sess.run(op, feed_dict))
# 写入序列化的 PB 文件
with tf.gfile.FastGFile(pb_file_path+'model.pb', mode='wb') as f: #模型的名字是model.pb
f.write(constant_graph.SerializeToString())
# 输出
# INFO:tensorflow:Froze 1 variables.
# Converted 1 variables to const ops.
# 31
提取pb
import tensorflow as tf
import os
from tensorflow.python.platform import gfile
pb_file_path = os.getcwd() #获取当前代码路径
sess = tf.Session()
with gfile.FastGFile(pb_file_path + 'model.pb', 'rb') as f: #加载模型
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sess.graph.as_default()
tf.import_graph_def(graph_def, name='') # 导入计算图
# 需要有一个初始化的过程
sess.run(tf.global_variables_initializer())
# 需要先复原变量
print(sess.run('b:0'))
# 1
#下面三句,是能否复现模型的关键
# 输入
input_x = sess.graph.get_tensor_by_name('x:0') #此处的x一定要和之前保存时输入的名称一致!
input_y = sess.graph.get_tensor_by_name('y:0') #此处的y一定要和之前保存时输入的名称一致!
op = sess.graph.get_tensor_by_name('op_to_store:0') #此处的op_to_store一定要和之前保存时输出的名称一致!
ret = sess.run(op, feed_dict={input_x: 5, input_y: 5})
print(ret)
# 输出 26
试验
保存为ckpt和pb
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import math
from tensorflow.python.framework import graph_util
# 拟合y = cos(18x + 8)
# 首先从此函数中以相同步长(点与点之间在x轴上距离相同),在0<(18x+8)<2pi范围内,采样出2000个点.
x = np.linspace(-8 / 18, (2 * math.pi - 8) / 18, 2000)
# 增加一个轴,方便矩阵计算
x = x[:, np.newaxis]
y = np.cos(18 * x + 8)
# print(np.shape(y)) # (2000, 1)
# # 画图
# plt.plot(x, y)
# plt.legend(labels=['original'])
# plt.show()
# 然后利用采样的2000个点作为特征点进行三次函数拟合(三次函数形式为 y = w1 * x + w2 * x^2 + w3 * x^3 + b,
# 其中wi为可训练的权值,b为可训练的偏置值,x和y为输入的训练数据 ) 。要求使用TensorFlow实现三次函数拟合的全部流程。
# input_x,input_y
input_x = tf.placeholder(tf.float32, shape=x.shape)
input_y = tf.placeholder(tf.float32, shape=y.shape)
# 变量
w1 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w1')
w2 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w2')
w3 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w3')
b = tf.Variable(tf.zeros([1, 1]), name='b')
# 运算
t1 = tf.matmul(tf.pow(input_x, 1), w1) # tf.matmul矩阵乘;tf.multiply点乘; * 等价于 tf.multiply
t2 = tf.matmul(tf.pow(input_x, 2), w2) # [2000,1]*[1,1]
t3 = tf.matmul(tf.pow(input_x, 3), w3) # w3 * x^3
t4 = tf.matmul(tf.pow(input_x, 0), b) # b
# predict y
y_pre = tf.add_n([t1, t2, t3, t4], name='y_pre')
# 损失
loss = tf.losses.mean_squared_error(input_y, y_pre) # 回归问题多用均方误差,分类用交叉熵
# 优化器
optimizer = tf.train.AdamOptimizer(learning_rate=0.5)
# 模型训练
train_op = optimizer.minimize(loss)
# 定义输出
saver = tf.train.Saver()
# 创建会话
with tf.Session() as sess:
# 初始化
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 迭代优化
for step in range(1001):
# 记录预测值
_, Y_pre, Loss, W1, W2, W3, B = sess.run(
[train_op, y_pre, loss, w1, w2, w3, b], feed_dict={input_x: x, input_y: y})
# 打印训练进程
if step % 100 == 0:
print("After %d steps & Loss is %g" % (step, Loss))
# 打印W1, W2, W3, B
print("w1:%g" % W1)
print("w2:%g" % W2)
print("w3:%g" % W3)
print("b:%g" % B)
# 输出.ckpt文件
print('save ckpt:ckpt/fitting.ckpt')
saver.save(sess, 'ckpt/fitting.ckpt')
# 输出.pd文件,先转换成常量
# convert_variables_to_constants,需要指定output_node_names,list()
constant_graph = graph_util.convert_variables_to_constants(
sess, sess.graph_def, ['y_pre', 'w1', 'w2', 'w3', 'b']) # 保存图中的变量y_pre而不是Y_pre
# 写入pb文件,输出string
with tf.gfile.FastGFile('pb/fitting.pb', mode='wb') as f: # 要先建立文件夹pb
print('save pb:pb/fitting.pb')
f.write(constant_graph.SerializeToString()) # 转换成string
# # 画图
# p1, = plt.plot(x, y, 'b')
# p2, = plt.plot(x, Y_pre, 'r--')
# plt.legend(handles=[p1, p2], labels=['Original', 'Fitting'], )
# plt.title('Adam_lr = 0.5;step = 1000')
# plt.show()
读取ckpt文件
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import math
from tensorflow.python.framework import graph_util
# y = cos(18x + 8)
# 首先从此函数中以相同步长(点与点之间在x轴上距离相同),在0<(18x+8)<2pi范围内,采样出2000个点.
x = np.linspace(-8 / 18, (2 * math.pi - 8) / 18, 2000)
# 增加一个轴,方便矩阵计算
x = x[:, np.newaxis]
y = np.cos(18 * x + 8)
# input_x,input_y
input_x = tf.placeholder(tf.float32, shape=x.shape)
input_y = tf.placeholder(tf.float32, shape=y.shape)
# 变量
w1 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w1')
w2 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w2')
w3 = tf.Variable(tf.random_normal([1, 1], stddev=1, seed=1), name='w3')
b = tf.Variable(tf.zeros([1, 1]), name='b')
# 运算
t1 = tf.matmul(tf.pow(input_x, 1), w1) # tf.matmul矩阵乘;tf.multiply点乘; * 等价于 tf.multiply
t2 = tf.matmul(tf.pow(input_x, 2), w2) # [2000,1]*[1,1]
t3 = tf.matmul(tf.pow(input_x, 3), w3) # w3 * x^3
t4 = tf.matmul(tf.pow(input_x, 0), b) # b
y_pre = tf.add_n([t1, t2, t3, t4], name='y_pre')
# 定义输出
saver = tf.train.Saver()
# 创建会话
with tf.Session() as sess:
# 初始化
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 模型读入
saver.restore(sess, "ckpt/fitting.ckpt") # 注意路径写法
# 读取参数值
print("w1:%g" % sess.run(w1))
print("w2:%g" % sess.run(w2))
print("w3:%g" % sess.run(w3))
print("b:%g" % sess.run(b))
# 根据参数直接计算预测值
y_ckpt = sess.run(y_pre, feed_dict={input_x: x, input_y: y})
# 画图,与第一次拟合对比
p1, = plt.plot(x, y, 'b')
p2, = plt.plot(x, y_ckpt, 'r--')
plt.legend(handles=[p1, p2], labels=['Original', 'Fitting'], )
plt.title('ckpt read')
plt.show()
读取pb文件
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import math
from tensorflow.python.platform import gfile
# 采样
x = np.linspace(-8 / 18, (2 * math.pi - 8) / 18, 2000)
# 增加一个轴,方便矩阵计算
x = x[:, np.newaxis]
y = np.cos(18 * x + 8)
# print(np.shape(y)) # (2000, 1)
# input_x,input_y
input_x = tf.placeholder(tf.float32, shape=x.shape)
input_y = tf.placeholder(tf.float32, shape=y.shape)
# 创建会话
with tf.Session() as sess:
# 模型读入
with gfile.FastGFile('pb/fitting.pb', 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sess.graph.as_default()
tf.import_graph_def(graph_def, name='')
print('pb read')
# 需要有一个初始化的过程
sess.run(tf.global_variables_initializer())
# 复原变量
w1 = sess.graph.get_tensor_by_name('w1:0')
w2 = sess.graph.get_tensor_by_name('w2:0')
w3 = sess.graph.get_tensor_by_name('w3:0')
b = sess.graph.get_tensor_by_name('b:0')
# 读取参数值
print("w1:%g" % sess.run(w1))
print("w2:%g" % sess.run(w2))
print("w3:%g" % sess.run(w3))
print("b:%g" % sess.run(b))
# 很重要的一点是,pb读入的下列运算必须放在Session内,否则无法读入文件到模型!!!
# 根据读入参数,计算预测结果
# 运算
t1 = tf.matmul(tf.pow(input_x, 1), w1) # tf.matmul矩阵乘;tf.multiply点乘; * 等价于 tf.multiply
t2 = tf.matmul(tf.pow(input_x, 2), w2) # [2000,1]*[1,1]
t3 = tf.matmul(tf.pow(input_x, 3), w3) # w3 * x^3
t4 = tf.matmul(tf.pow(input_x, 0), b) # b
y_pre = tf.add_n([t1, t2, t3, t4], name='y_pre')
y_pb = sess.run(y_pre, feed_dict={input_x: x, input_y: y})
# 画图,与第一次拟合对比
p1, = plt.plot(x, y, 'b')
p2, = plt.plot(x, y_pb, 'r--')
plt.legend(handles=[p1, p2], labels=['Original', 'Fitting'], )
plt.title('pb read')
plt.show()