一、持久化使用
1.1 模型保存
下面的tf.train.Saver中的参数max_to_keep=1, 表示模型保存的ckpt最多是一个。
saver = tf.train.Saver(tf.global_variables(), max_to_keep=1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(epoches):
if epoch % 100 == 0:
saver.save(sess, "/tmp/my_model.ckpt")
init的初始化 和 saver的顺序不重要.
对于多个epoch运算,图只初始化一次
调用save
函数,会生成三个文件:
- model.ckpt.meta
保存了TensorFlow计算图的结构 - model.ckpt
保存了TensorFlow程序中每一个变量的取值 - checkpoint
保存了一个目录下所有的模型文件列表
默认:saver以自己的命名方式保存并还原所有变量,也可以使用以下方式保存部分变量,以及实现对变量的重命名。
saver = tf.train.Saver({"weights": theta})
其中theta是name
属性, 这样声明的saver, 调用save()只会保存theta这一个变量。
1.2 模型加载
需要注意的是: 在执行阶段开始,不是使用 init 节点初始化变量,而是调用 restore() 方法, 也就是说:使用预先保存的ckpt, 不需要sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, "/tmp/my_model_final.ckpt")
如果不希望重复定义图上的运算,可以直接加载已经持久化的图。
import tensorflow as tf
# 直接加载持久化的图
saver = tf.train.import_meta_graph("/path/model.ckpt.meta")
with tf.Session() as sess:
saver.restore(sess, "/path/model.ckpt")
# 通过张量的名称来获取张量.
print(sess.run(tf.get_default_graph().get_tensor_by_name("add:0"))
1.2.1 加载最近的ckpt
tf.train.latest_checkpoint()
调用这个函数.
saver = tf.train.Saver(max_to_keep=5)
with tf.Session() as sess:
# 查找最近的结点.
model_file = tf.train.latest_checkpoint(hp.logdir)
if model_file:
saver.restore(sess, model_file)
print("load from {}".format(model_file))
else:
sess.run(tf.global_variables_initializer())
print("create")
1.3 部分变量
默认:saver以自己的命名方式保存并还原所有变量,也可以使用以下方式保存部分变量,以及实现对变量的重命名
1.3.1 保存
主要应用于变量的滑动平均上, 下面的例子使用了滑动平均
声明滑动平均模型后,会给每个变量生成一个影子变量
例如:变量v:0 的影子变量为 v/ExponentialMovingAverage:0
import tensorflow as tf
v = tf.Variable(0, dtype=tf.float32, name="v")
# 在没有声明滑动平均模型时只有一个变量v.
for variables in tf.global_variables():
# 输出 v:0
print(variables.name)
ema = tf.train.ExponentialMovingAverage(0.99)
maintain_averages_op = ema.apply(tf.global_variables())
# 声明滑动平均模型之后, 会自动生成影子变量: v/ExponentialMoving Average.
for variables in tf.global_variables():
# 输出 v:0 和 v/ExponentialMoving Average:0
print(variables.name)
saver = tf.train.Saver()
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 对变量更新赋值.
sess.run(tf.assign(v, 10))
sess.run(maintain_averages_op)
# 保存时, TensorFlow会将v:0 和 v/ExponentialMovingAverage:0 两个变量都保存下来.
saver.save(sess, "./test/model.ckpt")
print(sess.run([v, ema.average(v)]))
# [10.0, 0.09999999]
1.3.2 加载
对于使用了滑动平均的模型,变量希望使用的是 影子变量的值。 所以需要使用重命名,
滑动平均提供了variables_to_restore
方法自动生成映射字典
- 下面是手动构造映射字典的实例:
v = tf.Variable(0, dtype=tf.float32, name="v")
# 通过变量重命名将原来变量v的滑动平均值直接赋值给v
saver = tf.train.Saver({"v/ExponentialMovingAverage": v})
with tf.Session() as sess:
saver.restore(sess, "./test/model.ckpt")
print(sess.run(v))
- 下面是自动构造映射字典的实例:
v = tf.Variable(0, dtype=tf.float32, name="v")
ema = tf.train.ExponentialMovingAverage(0.99)
# 通过variables_to_restore可以直接生成所需的 字典.
print(ema.variables_to_restore())
# {'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>}
saver = tf.train.Saver(ema.variables_to_restore())
with tf.Session() as sess:
saver.restore(sess, "./test/model.ckpt")
print(sess.run(v))