在训练完之后,将训练得到的保存下来方便下次使用,为了让训练结果可以重复使用,可以将训练模型持久化

Tensor Flow 提供了一个非常简单的API 来保存和还原一个神经网络模型。这个API 就是tf. train. Saver 类。以下代码给出了保存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

init_op=tf.global_variables_initializer()
#声明tf.train.Saver()
saver=tf.train.Saver()

with tf.Session() as sess:
  sess.run(init_op)
  #将模型保存在文件夹里
  saver.save(sess,"E:/TensorFlow-mode/learn1/midel.ckpt")

TensorFlow模型一般会存在后缀为.ckpt 的文件中。虽然以上程序只指定了一个文件路径,但是在这个文件目录下会出现三个文件。这是因为TensorFlow 会将计算图的结构和l 图上参数取值分开保存。第一个文件为model.ckpt.meta ,它保存了Ten sorFlow 计算图的结构。第二个文件为mode l.ckpt , 这个文件中保存了Te n sorFlow 程序中每一个变量的取值。最后一个文件为checkpoint 文件,这个文件中保存了一个目录下所有的模型文件列表。

给出以下程序,加载训练模型

import tensorflow as tf 

v=tf.Variable(0,dtype=tf.float32,name="v")
#在没有申明滑动平均变量模型时只有一个变量,所有一下语句只会输出“v:0”
for variables in tf.global_variables():
  print (variables.name)
ema=tf.train.ExponentialMovingAverage(0.99)
maintain_averages_op=ema.apply(tf.global_variables())
#在申请滑动变量之后tensorflow 会自动产生一个影子变量
#v/ExponentialMoving Average.于是以下语句会输出:
#v:0和v/ExponentialMoving Average:0
for variables in tf.global_variables():
  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)
  #保存时会将v:0和v/ExponentialMoving Average:0两个变量都保存下来
  saver.save(sess,'E:/TensorFlow-mode/learn1/learn1.ckpt')
  print(sess.run([v,ema.average(v)]))
  #输出[10.0, 0.099999905]

  #v=tf.Variable(0,dtype=tf.float32,mame='v')
  saver=tf.train.Saver({"v/ExponentialMovingAverage":v})
  with tf.Session() as sess:
    saver.restore(sess,"E:/TensorFlow-mode/learn1/learn1.ckpt")
    print(sess.run(v))
    #输出0.099999905

为了方便加载时重命名滑动平均变量, tf. train.ExponentialMovingAverage 类提供了variabl es to restore 函数来生成tf.train.Saver 类所需要的变量重命名字典。

import tensorflow as tf 

v=tf.Variable(0,dtype=tf.float32,name="v")
ema=tf.train.ExponentialMovingAverage(0.99)

#通过使用variables_to_restore函数可以直接生成字典
print(ema.variables_to_restore())

saver=tf.train.Saver(ema.variables_to_restore())
with tf.Session() as sess:
  saver.restore(sess,"E:/TensorFlow-mode/learn1/learn1.ckpt")
  print(sess.run(v))

使用tf.train.Saver 会保存运行TensorFlow 程序所需要的全部信息,然而有时并不需要某些信息。比如在测试或者离线预测时,只需要知道如何从神经网络的输入层经过前向传播计算得到输出层即可,而不需要类似于变量初始化、模型保存等辅助节点的信息。Tensor Flow 提供了convert variables to constants 函数,通过这个函数可以将计算图中的变量及其取值通过常量的方式保存,这样整个TensorFlow 计算
图可以统一存放在一个文件中。

import tensorflow as tf 
from tensorflow.python.framework import graph_util
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

init_op=tf.global_variables_initializer()
with tf.Session() as sess:
  sess.run(init_op)
  #导出计算图的GraphDef部分,只需要这一部分就可以完成从输入
  #层到输出层的计算过程
  graph_def=tf.get_default_graph().as_graph_def()

  #将图中的变量及其取值转化为常量,同时将图中不必要的节点去掉
  #一些系统运算也会被转化为计算图中的节点(比如变量初始化操作)。如果只关心程序中定
  #义的某些计算时,和这些计算无关的节点就没有必要导出并保存了。在下面一行代码中,最
  #后一个参数['add']给出了需要保存的节点名称。add 节点是上面定义的两个变量相加的
  #操作。注意这里给出的是计算节点的名称,所以没有后面的:0
  output_graph_def=graph_util.convert_variables_to_constants(
    sess,graph_def,['add'])
    #将导出的模型存入文件
  with tf.gfile.GFile("E:/TensorFlow-mode/learn1/combined_mode.pb","wb") as f:
    f.write(output_graph_def.SerializeToString())

通过以下程序可以直接计算定义的加法运算的结果。当只需要得到计算图中某个节点的取值时,这提供了一个更加方便的方法

import tensorflow as tf 
from tensorflow.python.platform import gfile 

with tf.Session() as sess:
  model_filename='E:/TensorFlow-mode/learn1/combined_mode.pb'
  #读取保存的模型文件,并将文件解析成对应的GraphDef Protocol Buffer
  with gfile.FastGFile(model_filename,'rb') as f:
    graph_def=tf.GraphDef()
    graph_def.ParseFromString(f.read())

  #将graph_def中保存的图加载到当前的图中,return_elements=[add:0给出了返回
  #的张量的名称。在保存的时候给出的是计算节点的名称,所以为"add"。在加载的时候给出
  #的是张量的名称,所以是add:O

  result=tf.import_graph_def(graph_def,return_elements=["add:0"])
  #输出[3.0]
  print(sess.run(result))