Tensorflow实验管理

Saver的用法

1. Saver的背景介绍

我们经常在训练完一个模型之后希望保存训练的结果,这些结果指的是模型的参数,以便下次迭代的训练或者用作测试。Tensorflow针对这一需求提供了Saver类。

  1. Saver类提供了向checkpoints文件保存和从checkpoints文件中恢复变量的相关方法。Checkpoints文件是一个二进制文件,它把变量名映射到对应的tensor值 。
  2. 只要提供一个计数器,当计数器触发时,Saver类可以自动的生成checkpoint文件。这让我们可以在训练过程中保存多个中间结果。例如,我们可以保存每一步训练的结果。
  3. 为了避免填满整个磁盘,Saver可以自动的管理Checkpoints文件。例如,我们可以指定保存最近的N个Checkpoints文件。

2. Saver的实例

下面以一个例子来讲述如何使用Saver类

1.  import tensorflow as tf  
2.  import numpy as np  

4.  x = tf.placeholder(tf.float32, shape=[None, 1])  
5.  y = 4 * x + 4  

7.  w = tf.Variable(tf.random_normal([1], -1, 1))  
8.  b = tf.Variable(tf.zeros([1]))  
9.  y_predict = w * x + b  

12.  loss = tf.reduce_mean(tf.square(y - y_predict))  
13.  optimizer = tf.train.GradientDescentOptimizer(0.5)  
14.  train = optimizer.minimize(loss)  

16.  isTrain = False  
17.  train_steps = 100  
18.  checkpoint_steps = 50  
19.  checkpoint_dir = ''  

21.  saver = tf.train.Saver()  # defaults to saving all variables - in this case w and b  
22.  x_data = np.reshape(np.random.rand(10).astype(np.float32), (10, 1))  

24.  with tf.Session() as sess:  
25.  sess.run(tf.initialize_all_variables())  
26.  if isTrain:  
27.  for i in xrange(train_steps):  
28.  sess.run(train, feed_dict={x: x_data})  
29.  if (i + 1) % checkpoint_steps == 0:  
30.  saver.save(sess, checkpoint_dir + 'model.ckpt', global_step=i+1)  
31.  else:  
32.  ckpt = tf.train.get_checkpoint_state(checkpoint_dir)  
33.  if ckpt and ckpt.model_checkpoint_path:  
34.  saver.restore(sess, ckpt.model_checkpoint_path)  
35.  else:  
36.  pass  
37.  print(sess.run(w))  
38.  print(sess.run(b))  

isTrain:用来区分训练阶段和测试阶段,True表示训练,False表示测试
train_steps:表示训练的次数,例子中使用100
checkpoint_steps:表示训练多少次保存一下checkpoints,例子中使用50
checkpoint_dir:表示checkpoints文件的保存路径,例子中使用当前路径

2.1 训练阶段

使用Saver.save()方法保存模型:

  1. sess:表示当前会话,当前会话记录了当前的变量值
  2. checkpoint_dir + 'model.ckpt':表示存储的文件名
  3. global_step:表示当前是第几步

训练完成后,当前目录底下会多出5个文件。

Tensorflow实验管理_第1张图片
打开名为“checkpoint”的文件,可以看到保存记录,和最新的模型存储位置。
Tensorflow实验管理_第2张图片

2.2测试阶段

测试阶段使用saver.restore()方法恢复变量:
  1. sess:表示当前会话,之前保存的结果将被加载入这个会话

  2. ckpt.model_checkpoint_path:表示模型存储的位置,不需要提供模型的名字,它会去查看checkpoint文件,看看最新的是谁,叫做什么。

    运行结果如下图所示,加载了之前训练的参数w和b的结果

Tensorflow实验管理_第3张图片

部分变量保存

默认情况下,saver.save()存储图形的所有变量,一般建议这样做。但是,当我们创建保存对象时,您还可以通过将它们作为列表或字典传入来选择要存储的变量。

v1 = tf.Variable(..., name='v1') 
v2 = tf.Variable(..., name='v2') 

# pass the variables as a dict: 
saver = tf.train.Saver({'v1': v1, 'v2': v2}) 

# pass them as a list
saver = tf.train.Saver([v1, v2]) 

# passing a list is equivalent to passing a dict with the variable op names # as keys
saver = tf.train.Saver({v.op.name: v for v in [v1, v2]})

这里使用了三种不同的方式来创建 saver 对象, 但是它们内部的原理是一样的。我们都知道,参数会保存到 checkpoint 文件中,通过键值对的形式在 checkpoint中存放着。如果 Saver 的构造函数中传的是 dict,那么在 save 的时候,checkpoint文件中存放的就是对应的 key-value。如下:

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver({"variable_1":v1, "variable_2": v2})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    saver.save(sess, 'test-ckpt/model-2')

我们通过官方提供的工具来看一下 checkpoint 中保存了什么

from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file

print_tensors_in_checkpoint_file("test-ckpt/model-2", None, True)
# 输出:
#tensor_name:  variable_1
#1.0
#tensor_name:  variable_2
#2.0

如果构建saver对象的时候,我们传入的是 list, 那么将会用对应 Variable 的 variable.op.name 作为 key。

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver([v1, v2])
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    saver.save(sess, 'test-ckpt/model-2')

我们再使用官方工具打印出 checkpoint 中的数据,得到

tensor_name:  v1
1.0
tensor_name:  v2
2.0

如果我们现在想将 checkpoint 中v2的值restore到v1 中,v1的值restore到v2中,我们该怎么做?
这时,我们只能采用基于 dictsaver

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver({"variable_1":v1, "variable_2": v2})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    saver.save(sess, 'test-ckpt/model-2')

save 部分的代码如上所示,下面写 restore 的代码,和save代码有点不同。

```python
import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")
#restore的时候,variable_1对应到v2,variable_2对应到v1,就可以实现目的了。
saver = tf.train.Saver({"variable_1":v2, "variable_2": v1})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    saver.restore(sess, 'test-ckpt/model-2')
    print(sess.run(v1), sess.run(v2))
# 输出的结果是 2.0 1.0,如我们所望

我们发现,其实 创建 saver对象时使用的键值对就是表达了一种对应关系:

  • save时, 表示:variable的值应该保存到 checkpoint文件中的哪个 key
  • restore时,表示:checkpoint文件中key对应的值,应该restore到哪个variable

其它

一个快速找到ckpt文件的方式

ckpt = tf.train.get_checkpoint_state(ckpt_dir)
if ckpt and ckpt.model_checkpoint_path:
    saver.restore(sess, ckpt.model_checkpoint_path)

你可能感兴趣的:(Tensorflow实验管理)