tensorflow学习笔记(五):模型参数的保存和读取saver


文章目录

  • 一、Tensorflow模型
  • 二、保存模型
  • 三、模型数据的读取
  • 四、其他保存和读取方法


在深度学习中,经常会听到”预训练“、”保存模型“、”加载模型“等词,实际上就是在模型训练完成之后,将模型及其训练得到的参数保存下来,下次再来直接调用,或者上次得到的数据上再次训练(预训练)。

一、Tensorflow模型

所谓的Tensorflow模型,是指训练得到的网络参数的网络设计或图形和值。因此,Tensorflow模型有两个主要的文件:

  • Meta graph:这是一个协议缓冲区,它保存了完整的Tensorflow图形;即所有变量、操作、集合等。该文件以.meta作为扩展名,如下:
model.ckpt.meta
  • Checkpoint file::这个文件是以.ckpt为后缀的,是个二进制的文件,里面保存了.meta文件中对应变量或者tensor或者操作等等的值。但是现在变成了三个文件,分别是以.index 和.data为后缀的两个文件加上一个checkpoint文件。其中.data文件保存了我们训练的变量的值;checkpoint 文件仅仅记录最新保存的模型是哪个,如下:
checkpoint
model.ckpt.data-00000-of-00001
model.ckpt.index

二、保存模型

在深度学习中,往往训练需要很长的时间,而每次要用模型的时候不可能重新在训练一次,所以要把模型保存起来。在tensorflow中如果想保存graph和参数的值,我们需要用到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")
    

将定义的float32型的2*3的矩阵保存在当前路径的"Model"文件夹中,4个文件如下:
tensorflow学习笔记(五):模型参数的保存和读取saver_第1张图片

三、模型数据的读取

现在开始读取上一步保存的模型参数。有两种方法:
1)、自己写一个一模一样的网络出来,如下:

#########加载方法一:

#重新定义相同的dtype和shape
import tensorflow as tf

v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1")
v2 = tf.Variable(tf.constant(1.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.]

这里的输出,并不是自己生产的[2.0],所以是加载的上一步保存的结果[3.0]。并且,定义的W和b的名称name=“v1”,name="v2"必须和之前保持一致,否则无法读取。

2)、直接引入meta文件中保存的网络graph,如下:

#加载方法二:若不希望重复定义计算图上的运算,可直接加载已经持久化的图

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.]

四、其他保存和读取方法

1)、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)、保存滑动平均模型,如下:


import tensorflow as tf
 
v = tf.Variable(0, dtype=tf.float32, name="v")
for variables in tf.global_variables():
    print(variables.name)         #输出:   v:0
 
ema = tf.train.ExponentialMovingAverage(0.99)
maintain_averages_op = ema.apply(tf.global_variables())
for variables in tf.global_variables():
    print(variables.name)    # 输出:     v:0
                             #输出:      v/ExponentialMovingAverage:0
 
saver = tf.train.Saver()
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(tf.assign(v, 10))
    sess.run(maintain_averages_op)
    saver.save(sess, "Model/model_ema.ckpt")
    print(sess.run([v, ema.average(v)]))     #输出:  [10.0, 0.099999905]

然后通过变量重命名直接读取变量的滑动平均值,如下:


import tensorflow as tf
 
v = tf.Variable(0, dtype=tf.float32, name="v")
saver = tf.train.Saver({"v/ExponentialMovingAverage": v})
 
with tf.Session() as sess:
    saver.restore(sess, "./Model/model_ema.ckpt")
    print(sess.run(v))     # 输出:    0.0999999
    

3)、通过tf.train.ExponentialMovingAverage的variables_to_restore()函数获取变量重命名字典,如下:


import tensorflow as tf

v = tf.Variable(0, dtype=tf.float32, name="v")
# 注意此处的变量名称name一定要与已保存的变量名称一致
ema = tf.train.ExponentialMovingAverage(0.99)
print(ema.variables_to_restore())
# {'v/ExponentialMovingAverage': }
# 此处的v取自上面变量v的名称name="v"

saver = tf.train.Saver(ema.variables_to_restore())

with tf.Session() as sess:
    saver.restore(sess, "./Model/model_ema.ckpt")
    print(sess.run(v))       #输出     0.0999999

4)、通过convert_variables_to_constants函数将计算图中的变量及其取值通过常量的方式保存于一个文件中


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

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # 导出当前计算图的GraphDef部分,即从输入层到输出层的计算过程部分
    graph_def = tf.get_default_graph().as_graph_def()
    output_graph_def = graph_util.convert_variables_to_constants(sess,graph_def, ['add'])

    with tf.gfile.GFile("Model/combined_model.pb", 'wb') as f:
        f.write(output_graph_def.SerializeToString())
        

5)、载入包含变量及其取值的模型


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

with tf.Session() as sess:
    model_filename = "Model/combined_model.pb"
    with gfile.FastGFile(model_filename, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

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

你可能感兴趣的:(tensorflow实战)