tensorflow pkl 模型文件 tensorflow保存模型pb_tensorflow pkl 模型文件


运行一个结构复杂的深层网络往往需要很长时间,当我们在应用模型到实际的生活中时,不可能每一次都重新训练模型。我们希望训练的结果可以复用,也就是需要将训练得到的模型持久化。

下面简单介绍通过tensorflow程序来持久化一个训练好的模型,并从持久化之后的模型文件中还原被保存的模型。简单来说就是模型的保存以及载入。

1.模型保存

下面用一个简单的例子来说明如何通过tensorflow提供的tf.train.Saver类载入模型:


import tensorflow as tf

#声明两个变量并计算他们的和
a = tf.Variable(tf.constant(1.0,shape = [1]),name = "a")
b = tf.Variable(tf.constant(2.0,shape = [1]),name = "b")
result = a + b
#声明tf.train.Saver()类
saver = tf.train.Saver()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #将模型保存到指定的文件中
    saver.save(sess,"./model/add_model.ckpt")


tensorflow pkl 模型文件 tensorflow保存模型pb_tensorflow pkl 模型文件_02

运行结果


注意:

  1. 在保存模型指定文件的时候添加了文件后缀.ckpt。其实加不加都可以的,但是最好是还加上,因为Tensorflow模型一般都是保存在以.ckpt后缀结尾的文件中;
  2. 在代码中我们指定了一个目录文件,但是目录下会出现4个文件,那是因为TensorFlow会把计算图的结构和图上变量参数取值分别保存;

下面对于目录下的4个文件进行简单的介绍:

  • add_model.ckpt.data-00000-of-00001文件是保存TensorFlow当前变量值,而add_model.ckpt.index文件中保存的是TensorFlow当前的变量名可以把他们两个文件合在一起看,他们是通过SSTable格式存储的,可以大致理解为就是一个(key,value)列表。

Tensorflow提供了tf.train.NewCheckpointReader类查看保存的变量信息,同时我们也可以使用封装好的方法来简单查看当前结构下保存的变量名以及其对应的变量值:


from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file("./model/add_model.ckpt",None,True)

'''
tensor_name:  a
[ 1.]
tensor_name:  b
[ 2.]
'''


那为什么就说这两个文件中保存的是结构中的变量名以及变量值呢?我们可以通过分别删除四个文件来进行判断:

1.如果删除add_model.ckpt.data-00000-of-00001文件,会出现下面的异常,因为没有删除add_model.ckpt.index文件,所以对应会打印出第一个变量名,但是当程序试图获取变量值的时候,发现保存变量值的文件不存在,所以此刻抛出异常:


tensorflow pkl 模型文件 tensorflow保存模型pb_tensorflow_03

删除add_model.ckpt.data-00000-of-00001文件结果

2.如果删除add_model.ckpt.index文件,会在控制台打印下面这段话:


Unsuccessful TensorSliceReader constructor: Failed to find any matching files for ./model/add_model.ckpt


3.当然删除剩下的两个文件对上面获取变量名以及变量值的程序没有任何的影响。

  • add_model.ckpt.meta文件简单来说就是保存了TensorFlow计算图的结构。TensorFlow是一个通过图的形式来表述计算的变成系统,所以TensorFlow程序中的所有计算都会被表达为计算图上的节点。TensorFlow通过元图(MetaGraph)来记录计算图中节点的信息以及运行计算图中节点所需要的元数据。TensorFlow提供了export_meta_graph函数以json格式导出,这里不展开写,只要简单记住保存了TensorFlow计算图的结构就可以了。
  • checkpoint文件保存了一个目录下所有的模型文件列表。这个文件是tf.train.Saver类自动生成且自动维护的。当某个保存的TensorFlow模型文件被删除时,这个模型所对应的文件名也会从checkpoint文件中删除。这个文件是可以直接以文本格式打开的:


tensorflow pkl 模型文件 tensorflow保存模型pb_变量名_04

checkpoint文件内容

如果我们在创建一个模型,还把模型保存到"model"路径下,


tensorflow pkl 模型文件 tensorflow保存模型pb_python_05

保存了一个新的模型,但是checkpoint文件只有一个

上面的程序默认情况下,保存了TensorFlow计算图上定义的全部变量,但有时可能只需要保存部分变量,此时保存模型的时候就需要为tf.train.Saver类提供一些参数。

比如我们在构建加法的模型中,只希望能够将保存一个变量a:


import tensorflow as tf

#声明两个变量并计算他们的和
a = tf.Variable(tf.constant(1.0,shape = [1]),name = "a")
b = tf.Variable(tf.constant(2.0,shape = [1]),name = "b")
result = a + b
#只指定变量a保存到模型中
saver = tf.train.Saver([a])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #将模型保存到指定的文件中
    saver.save(sess,"./model/add_model.ckpt")


此时查看保存变量名以及变量值的文件,也就是add_model.ckpt.data-00000-of-00001文件和add_model.ckpt.index文件:


from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file("./model/add_model.ckpt",None,True)

'''
tensor_name:  a
[ 1.]
'''


下面要精确的声明一下,对于a = tf.Variable(tf.constant(1.0,shape = [1]),name = "a")代码:

  1. a叫做变量名;
  2. name属性指定的参数叫做变量名称;


tensorflow pkl 模型文件 tensorflow保存模型pb_变量名_06

指定部分保存部分变量

指定部分保存部分变量的大致流程:

  1. 当需要保存部分变量的时候,我们传入一个元素为变量名的列表;
  2. 然后通过变量名来找到对应的变量名称以及变量值;
  3. 然后将找到的变量名称作为key,变量值为value,通过SSTable格式存储到add_model.ckpt.data-00000-of-00001和add_model.ckpt.index文件中。

这里需要注意的一点,从前面的程序中,变量名和变量名称是一致的,但是有时候可能并不一致,比如下面:


import tensorflow as tf

#声明两个变量并计算他们的和
a = tf.Variable(tf.constant(1.0,shape = [1]),name = "add_1")
b = tf.Variable(tf.constant(2.0,shape = [1]),name = "add_2")
result = a + b
#只指定变量a保存到模型中
saver = tf.train.Saver([a])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #将模型保存到指定的文件中
    saver.save(sess,"./model/add_model.ckpt")


from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file("./model/add_model.ckpt",None,True)

'''
tensor_name:  add_1
[ 1.]
'''


tensorflow pkl 模型文件 tensorflow保存模型pb_pb 保存变量文件名_07

指定部分保存部分变量

知道了变量名以及变量名称之间的关系,我们可以使用字典的形式体现这种对应关系。下面使用字典的形式颠倒两个变量:


import tensorflow as tf

#声明两个变量并计算他们的和
a = tf.Variable(tf.constant(1.0,shape = [1]),name = "add_1")
b = tf.Variable(tf.constant(2.0,shape = [1]),name = "add_2")
result = a + b
#使用对应关系
saver = tf.train.Saver({'add_1':b,'add_2':a})

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #将模型保存到指定的文件中
    saver.save(sess,"./model/add_model.ckpt")


from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file("./model/add_model.ckpt",None,True)

'''
tensor_name:  add_1
[ 2.]
tensor_name:  add_2
[ 1.]
'''


tensorflow pkl 模型文件 tensorflow保存模型pb_python_08

演示了其中一个,另一个同理

当然如果只想要保存"add_1",只需将tf.train.Saver({'add_1':b,'add_2':a})改成下面代码即可:


saver = tf.train.Saver({'add_1':b})


从上面保存变量的结果可以看出,输出了变量名称以及对应的变量值,也就是说变量名并没有被保存到文件中,所以变量名称作为唯一的标识,如果要加载变量的时候,需要通过变量名称才能够得到相应的变量值。

总结来说,保存模型的操作还是挺简单的,包含着两个部分,一个是计算图,一个是计算图上的变量:

  1. 通过tf.train.Saver类的save方法可以自动将计算图保存到.meta结尾的文件中;
  2. 通过tf.train.Saver类的save方法可以将计算图上的变量保存到add_model.ckpt.data-00000-of-00001和add_model.ckpt.index两个文件中,但是此时对tf.train.Saver类传递不同的参数实现一些高级功能:
  1. 传入以变量名为元素的列表,通过列表找到对应的变量名称对应的变量值,保存到add_model.ckpt.data-00000-of-00001和add_model.ckpt.index两个文件中;
  2. 传入{"变量名称":变量名}这样的字典形式,当然此时保存的变量名称就是字典中的key,而value值则是通过变量名找到的变量值;

只要记住保存模型时候,对于计算图上的变量来说,保存到文件中的就是类似(key,value)列表,而此时的key就是变量名称,value就是变量值。

由于篇幅限制,分成几个部分来完成:

触摸壹缕阳光:[L2]TensorFlow模型持久化~模型加载zhuanlan.zhihu.com

tensorflow pkl 模型文件 tensorflow保存模型pb_tensorflow pkl 模型文件_09


参考: 1.《TensorFlow实现Google深度学习框架》