您的位置:首页 > 其它

TensorFlow 深度学习框架(7)-- 变量管理及训练模型的保存与加载

2018-03-22 10:03 701 查看

变量管理

#下面两个定义是等价的
v = tf.get_variable("v",shape = [1],initializer = tf.constant_initializer(1.0))

v = tf.Variable(tf.constant(1.0,shape = [1]),name = "v")
从以上的代码可以看出,通过 tf.Variable 和 tf.get_variable 函数创建变量的过程基本上是一样的。tf.get_variable 函数调用时提供的维度(shape)信息以及初始化方法(initializer)的参数和 tf.Variable 函数调用时提供的初始化过程中的参数也类似。TensorFlow 中提供了 7 种不同的初始化函数如下表



为了避免无意识的变量复用造成的错误问题,TensorFlow提供 tf.variable_scope 函数来生成一个上下文管理器,前向传播修改def inference(input_tensor,reuse = False):
    with tf.variable_scope('layer1',reuse = reuse):
        weights = tf.get_variable("weights",[INPUT_NODE,LAYER1_NODE],
                        initializer = tf.truncated_normal_initializer(stddev = 0.1))
        biases = tf.get_variable("biases",[LAYER1_NODE],initializer = tf.constant_initializer(0.0))
        layer1 = tf.nn.relu(tf.matmul(input_tensor,weights) + biases)
    #使用变量空间定义第二层网络
    with tf.variable_scope('layer2',reuse = reuse):
        weights = tf.get_variable("weights",[LAYER1_NODE,OUTPUT_NODE],
                        initializer = tf.truncated_normal_initializer(stddev = 0.1))
        biases = tf.get_variable("biases",[OUTPUT_NODE],initializer = tf.constant_initializer(0.0))
        layer2 = tf.matmul(layer1,weights) + biases
    #返回最后的结果
    return layer2

tensorflow 模型加载及持久化

TensorFlow 提供了一个非常简单的 API 来保存和还原一个神经网络模型,这个 API 就是 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

init_op = tf.initialize_all_variables()
saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(init_op)
    #将模型保存到 /path/to/model/model.ckpt 文件
    saver.save(sess,"/path/to/model/model.ckpt")上述代码实现了持有化一个简单的 TensorFlow 模型的功能,通过 saver.save 函数将 TensorFlow 模型保存到了 cpkt 文件中。在这个目录下会出现 3 个文件,因为TensorFlow 会将计算图的结构和图上参数取值分开保存。
第一个文件为 model.ckpt.meta ,它保存了 TensorFlow 计算图的结构
第二个文件为 model.ckpt,它保存了 TensorFlow 程序中每一个变量的取值

第三个文件为 checkpoint 文件,保存了一个目录下所有的模型文件列表
(1)仅加载变量值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:
    #加载已经保存的模型,并通过已经保存的模型中的变量来计算加法
    saver.restore(sess,"/path/to/model/model.ckpt")
    print sess.run(result)
(2)加载图和变量import tensorflow as tf
#直接加载持有化的图
saver = tf.train.import_meta_graph("/path/to/model/model.ckpt/model.ckpt.meta")
with tf.Session() as sess:
    saver.restore(sess,"/path/to/model/model.ckpt") #加载变量
    print sess.run(tf.get_default_graph().get_tensor_by_name("add:0"))
    #输出 [3.]
(3)重命名加载#这里声明的变量名称和已经保存的模型的名称不同
v1 = tf.Variable(tf.constant(1.0,shape = [1],name = "other-v1")
v2 = tf.Variable(tf.constant(2.0,shape = [1],name = "other-v2")

#如果直接使用 tf.train.Saver()来加载模型会报变量找不到的错误
#not found in checkpoint files /path/to/model/model.ckpt

#使用一个字典来重命名变量就可以加载原来的模型了。
#这个字典制定了原来名称为 v1 的变量现在加载到变量 v1 中(名称为 other-v1),名称为 v2 的变量加载到变量 v2 中
saver = tf.train.Saver({"v1":v1,"v2":v2})(4)加载滑动平均值import tensorflow as tf

v = tf.Variable(0,dtype = tf.float32,name = "v")
#在没有申明滑动平均模型时只有一个变量 v,所以下面的语句只会输出 0
for variables in tf.all_variables():
    print variables.name
ema = tf.train.ExponentialMovingAverage(0.99)
maintain_averages_op = ema.apply(tf.all_variables())
#下面的语句会输出 "v:0" 和 "v/ExponentialMovingAverage:0"
for variables in tf.all_variables():
    print variables.name

saver = tf.train.Saver()
with tf.Session() as sess:
    init_op = tf.initialize_all_variables()
    sess.run(init_op)
    
    sess.run(tf.assign(v,10))
    sess.run(maintain_averages_op)
    #保存时,TensorFlow 会将v:0 和 v/ExponentialMovingAverage:0 两个变量都存下来
    saver.save(sess,"/path/to/model/model.ckpt")
    print sess.run([v,ema.average(v)])
#这里加载上述的滑动平均值
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,"/path/to/model/model.ckpt")
    print sess.run(v) # 输出 0.0999999
#另一种加载滑动平均值的方式
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':<tensorflow.python.ops...}

saver = tf.train.Saver(ema.variables_to_restore())
with tf.Session() as sess:
    saver.restore(sess,"/path/to/model/model.ckpt")
    print sess.run(v) # 输出 0.0999999
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐