首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2.2 TensorFlow变量管理

2.2 TensorFlow变量管理

作者头像
锦小年
发布2019-05-27 07:39:20
7730
发布2019-05-27 07:39:20
举报
文章被收录于专栏:锦小年的博客锦小年的博客

版权声明:本文为博主原创文章,未经博主允许不得转载。python版本为python3,实例都是经过实际验证。 https://cloud.tencent.com/developer/article/1436383

TensorFlow变量管理

- [1. 变量的使用](https://cloud.tencent.com/developer/audit/support-plan/4869455#1__1)
    - [1.1 变量的声明](https://cloud.tencent.com/developer/audit/support-plan/4869455#11__4)
    - [1.2 变量的初始值](https://cloud.tencent.com/developer/audit/support-plan/4869455#12__18)
    - [1.3 变量的初始化](https://cloud.tencent.com/developer/audit/support-plan/4869455#13__38)
    - [1.4 变量值的引用](https://cloud.tencent.com/developer/audit/support-plan/4869455#14__57)
- [2. 变量命名空间](https://cloud.tencent.com/developer/audit/support-plan/4869455#2__67)
    - [2.1 变量共享](https://cloud.tencent.com/developer/audit/support-plan/4869455#21__111)
    - [2.2 tf.name\_scope()和tf.variable\_scope()的区别](https://cloud.tencent.com/developer/audit/support-plan/4869455#22_tfname_scopetfvariable_scope_126)
- [3. 占位符和常量](https://cloud.tencent.com/developer/audit/support-plan/4869455#3__133)
    - [3.1 占位符](https://cloud.tencent.com/developer/audit/support-plan/4869455#31__134)
    - [3.2 常量](https://cloud.tencent.com/developer/audit/support-plan/4869455#32__154)
- [4. 总结](https://cloud.tencent.com/developer/audit/support-plan/4869455#4__172)
- [参考文献](https://cloud.tencent.com/developer/audit/support-plan/4869455#_175)

1. 变量的使用

相对于c语言,python语言简化了对于变量的声明以及初始化的过程,是因为python会自动根据变量初始值来选择变量类型。但是在TensorFlow中我们需要注意,变量声明和使用和c语言类似,在声明的过程中需要指明变量类型以及初始值等。

TensorFlow中的变量特指深度学习过程中,控制输入到输出映射的可以变化的数据,这些变化数据随着训练迭代的进行,不断地改变数值,不断优化,使输出的结果越来越接近于正确的结果。

1.1 变量的声明

tensorflow提供了两个变量声明的函数:tf.Variable() 和 tf.get_variable().在功能上两个都是等价的,都是声明一个变量。两者在形式上的区别是:前者只需要指明初始值,其他参数为可选参数;而后者必须指明name,shape,和初始值。前者比较简单,但是不能很好的与命名空间配合使用,后者能很方便的与命名空间配合使用。所以一般而言,推荐使用后者。

具体说说两者的区别:

tf.get_variable(“vname”)方法,在创建变量时,如果这个变量vname已经存在,直接使用这个变量,如果不存在,则重新创建;

tf.Variable()在创建变量时,一律创建新的变量,如果这个变量已存在,则后缀会增加0、1、2等数字编号予以区别。

也就是tf.Variable()不适用于变量共享,每次都会创建新的变量

典型例子:

a = tf.Variable(2.0)

weights = tf.get_variable('weights', [2,5], initializer=tf.truncated_normal_initializer(stddev=0.1))

1.2 变量的初始值

在声明变量的时候必须指明初始化该变量的方法,tensorflow提供了以下几种指明初始值的函数:

例如:

import tensorflow as tf

a = tf.get_variable('a', [2,5], initializer=tf.truncated_normal_initializer(stddev=0.1))
sess = tf.InteractiveSession()

init = tf.initialize_all_variables()
init.run()

b = sess.run(a)
print(b)

需要注意的是这里的指明初始值和后面的变量初始化函数有区别。tensorflow是符号式编程,变量的的声明只是指明了变量符号,在会话中的初始化函数才会真正的占用内存,分配数值。

1.3 变量的初始化

注意1.2中说过,前面所有在计算图中的操作都是定义计算图,并没有真正的运行。只有在会话中运行后才会真正的计算。同样,在会话中需要显式的初始化所有函数,一般采用一个函数初始化所有变量。

init = tf.initialize_all_variables()
init.run()

或者:
tf.initialize_all_variables().run()

或者:
sess.run( tf.initialize_all_variables())

当然,也可以根据需要合理的初始化变量, 例如只初始化a,b,c:

init_new = tf.initialize_variables([a,b,c])
sess.run(init_new)

1.4 变量值的引用

前面说过,tensorflow中的变量的数据结构是一个tensor,它反映的是计算,并不能直接得到计算的结果。如果要引用计算的结果,有两种方式:

sess.run(a)
或者:
a.run()    or   a.eval()

这两种方式的区别见上一节,一句话说就是没有显示指明默认图用前者,显示指明默认图后都可以使用。

2. 变量命名空间

tensorflow是深度学习框架,神经网络的一个特点是每一层之间的变量名都是重复的,比如都是:权重,偏置。每一层网络结构也都一样:cnn,fcn等,这个时候变量的命名就有很大的问题,比如30层网络的权重变量命名,总不能:

weight_1 = 
weight_2 = 
weight_3 =
...

weight_30 =  

这样管理起来很不方便。tensorflow中采用命名空间来管理变量。常用的两个函数为: tf.variable_scope(), tf.name_scope().

编写代码就是这种形式:

    with tf.variable_scope('cnn_layer1',reuse=reuse):
        weights, biases = init_variable([5,5,1,32],[32])
        cnn1_res = conv2d(x_img,weights,biases,1.0)

    # layer_2
    with tf.variable_scope('cnn_layer2',reuse=reuse):
        weights, biases = init_variable([3,3,32,64],[64])
        cnn2_res = conv2d(cnn1_res,weights, biases,1.0)

    # layer_3
    with tf.variable_scope('cnn_layer3',reuse=reuse):
        weights, biases = init_variable([3, 3, 64, 128], [128])
        cnn3_res = conv2d(cnn2_res, weights, biases, 1.0)
        cnn3_shape = cnn3_res.shape.as_list()[1:]
        h3_s = reduce(lambda x, y: x * y, cnn3_shape)
        cnn3_reshape = tf.reshape(cnn3_res,[-1,h3_s])

    # layer_4
    with tf.variable_scope('fcn1',reuse=reuse):
        weights, biases = init_variable([h3_s,5000],[5000],regularizer)
        fcn1_res = tf.nn.relu(tf.matmul(cnn3_reshape,weights)+biases)
        fcn1_dropout = tf.nn.dropout(fcn1_res,dropout)

这样不同层的时候一直可以使用weights作为2权重的变量名,因为受到tf.variable_scope()函数的约束。

tf.name_scope()和tf.variable_scope()是两个作用域,一般与两个创建/调用变量的函数tf.variable() 和tf.get_variable()搭配使用。它们搭配在一起的两个常见用途:1)变量共享,2)tensorboard画流程图时为了可视化封装变量1

2.1 变量共享

在测试网络的时候实际上是采用训练网络的结果,那么这个时候的参数必须使用训练网络的参数,这时候就涉及了变量共享的问题。一般采用这种形式:

def inference(x,reuse):
	#这里定义网络
def  train():
	#调用inference(x,False)
	inference(x,False)

def test():
	inference(x,True)

在训练的时候不共享变量,在测试的使用共享变量。

关于为什么要这么搭配使用参考文献:https://www.cnblogs.com/weizhen/p/6751792.html

2.2 tf.name_scope()和tf.variable_scope()的区别

命名域 (name scope),通过tf.name_scope 或 tf.op_scope创建;

变量域 (variable scope),通过tf.variable_scope 或 tf.variable_op_scope创建;

这两种作用域,对于使用tf.Variable()方式创建的变量,具有相同的效果,都会在变量名称前面,加上域名称。

对于通过tf.get_variable()方式创建的变量,只有variable scope名称会加到变量名称前面,而name scope不会作为前缀。

综上:tf.variable_scope()搭配tf.get_variable(“vname”)能达到变量共享,这也是推荐使用的一种方式。

3. 占位符和常量

3.1 占位符

tf.placeholder()函数定义:

def placeholder(dtype, shape=None, name=None)

dtype:表示tensorflow中的数据类型,如常用的tf.float32,tf.float64等数值类型;
shape:表示数据类型,默认的None是一个一维的数值,shape=[None,5],表示行不定,列是5;
name:张量名称;

placeholder()又叫占位符,用于声明一个张量的数据格式,告诉系统这里会有一个这种格式的张量,但是还没有给定具体数值,具体的数值要在正式运行的时候给到。占位变量是一种TensorFlow用来解决读取大量训练数据问题的机制,它允许你现在不用给它赋值,随着训练的开始,再把训练数据传送给训练网络学习2。

常用于网络的输入层输出定义,这两层是没有网络参数的更新:

X = tf.placeholder(tf.float32, shape = [None,32*32,3])

None表示该维度的大小不确定,因为我们会修改batch_size的大小,一帮我们定义为None,tensorflow会根据运行时候具体情况调整。

3.2 常量

TF中定义的常量一般为不可更改的张量,tf.constant()函数定义:

def constant(value, dtype=None, shape=None, name="Const", verify_shape=False)

value: 符合tf中定义的数据类型的常数值或者常数列表;
dtype:数据类型,可选;
shape:常量的形状,可选;
name:常量的名字,可选;
verify_shape:常量的形状是否可以被更改,默认不可更改;

例如:

a = tf.constant([1.9,3.0])

当然也还有tf.ones()、tf.zeros()等初始化张量的方法。

4. 总结

一句话总结前面提到的4个函数的关系:tf.variable_scope可以让变量有相同的命名,包括tf.get_variable得到的变量,还有tf.Variable的变量;tf.name_scope可以让变量有相同的命名,只是限于tf.Variable的变量

参考文献

1(https://blog.csdn.net/gqixf/article/details/80191918)

2(https://blog.csdn.net/dcrmg/article/details/79016107)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年10月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TensorFlow变量管理
  • 1. 变量的使用
    • 1.1 变量的声明
      • 1.2 变量的初始值
        • 1.3 变量的初始化
          • 1.4 变量值的引用
          • 2. 变量命名空间
            • 2.1 变量共享
              • 2.2 tf.name_scope()和tf.variable_scope()的区别
              • 3. 占位符和常量
                • 3.1 占位符
                  • 3.2 常量
                  • 4. 总结
                  • 参考文献
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档