tensorflow共享变量

来源:互联网 发布:chinanet免费连接软件 编辑:程序博客网 时间:2024/06/06 01:47

撰写时间:2017.8.11
系统环境:ubuntu14.04,tensorflow1.12
内容:主要介绍tensorflow中name_scope,variable_scope和get_variable函数的使用

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

在tensorflow中,两个函数均是用于定义命名空间。二者的区别主要在于variable_scope可以与get_variable()函数实现变量的reuse。下面通过例子讲解

tf.name_scope函数

import tensorflow as tfwith tf.name_scope("compute") as scope:    a = tf.Variable(0.1,name="a")    b = tf.get_variable("b",initializer = 1.0)    with tf.name_scope("add"):        c = tf.add(a,b)print a.nameprint b.nameprint c.name"""result:compute/a:0b:0compute/add/Add:0"""

tf.variable_scope()函数

with tf.variable_scope("variable_scope"):       with tf.name_scope("name_scope") as scope:        a = tf.Variable(0.1,name="a")        b = tf.get_variable("b",initializer = 1.0)        with tf.name_scope("add"):            c = tf.add(a,b)print a.nameprint b.nameprint c.name"""result:variable_scope/name_scope/a:0variable_scope/b:0variable_scope/name_scope/add/Add:0"""

从上面的例子可以看出,name_scope函数会忽略get_variable函数初始化的变量,即不在变量前加prefix。而variable_scope函数不会忽略。

tf.Variable()和tf.get_variable()区别

当出现同名的变量时,Variable()函数会自动进行冲突处理,而get_variables()会raise ValueError exception。下面是相关例子

tf.Variable()

#!/usr/bin/env python2# -*- coding: utf-8 -*-"""Created on Fri Aug 11 14:09:47 2017@author: lrh"""import tensorflow as tfwith tf.variable_scope("test"):    a_1 = tf.Variable(0.1,"a")    a_2 = tf.Variable(0.1,"a")print a_1.name,a_2.name"""result:test/Variable:0 test/Variable_1:0"""

a_1和a_2是名称是一样的,由于是variable定义的,所以会在变量名称后面添加“_1”作为区分。

tf.get_variable()

#!/usr/bin/env python2# -*- coding: utf-8 -*-"""Created on Fri Aug 11 14:09:47 2017@author: lrh"""with tf.variable_scope("get_variable"):    b_1 = tf.get_variable(name="b",initializer=0.1)    b_2 = tf.get_variable(name="b",initializer=0.1)print b_1.name,b_2.name"""ERROR:ValueError: Variable get_variable/b already exists, disallowed. Did you mean to set reuse=True in VarScope? Originally defined at:"""

由于系统中变量出现命名冲突,且get_variable并不会自动处理冲突,所以就会出现ERROR
这样设计的原因是为了方便共享变量的实现

tf.get_variable()和tf.variable_scope()配合实现共享变量

tf.variable()生成的变量如果想要参数共享,就需要将变量定义成全局的变量。tensorflow使用了get_variable来实现变量共享,variable_scope的命名空间会管理这些共享变量
下面举例子说明几种代码重用的方式

不同的scope中共享

with tf.variable_scope("foo"):    v = tf.get_variable("v", [1])with tf.variable_scope("foo", reuse=True):    v1 = tf.get_variable("v", [1])print v1.name"""result:foo/v:0"""错误实例:with tf.variable_scope("foo"):    v = tf.get_variable("v", [1])with tf.variable_scope("foo", reuse=True):    v1 = tf.get_variable("v1", [1])"""ERROR:ValueError: Variable foo/v1 does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?"""

需要注意的一点是:既然scope已经被定义成了reuse属性,那么在之后使用的get_variable的属性全部都要是已经定义好的不然会报错,参考上面错误实例的例子

同一个scope中共享

with tf.variable_scope("foo") as scope:    v = tf.get_variable("v",initializer=1.0)    scope.reuse_variables()    #tf.get_variable_scope().reuse_variables()    v1 = tf.get_variable("v",initializer=1.0)print v.name,v1.name

同上面一样,在设置为reuse之后,该作用于下的之后所有的get_variable所涉及的变量全部都要是共享变量。
关于tensorflow的变量共享可以参看下面的文章:【极客学院】



问题:官方文档中给的cnn的例子,为什么我在自己实现cnn的时候没有注意到共享变量这一点?关于cnn的代码是否需要考虑共享变量?
答案:在我的cnn代码中并没有涉及共享变量这个问题。以为图像的卷积操作op从头到尾也只调用了一次。不会出现官方文档中所说的

# First call creates one set of 4 variables.result1 = my_image_filter(image1)# Another set of 4 variables is created in the second call.result2 = my_image_filter(image2)

调用两次,(调用两次的意思是:在计算图中创建两个卷积的操作)所以在我们的cnn代码中不需要考虑共享变量

问题:get_variable函数的initializer参数的可能取值?
答案:该函数常用的传入参数有:name,shape,dtype,initializer,其中initializer的可能取值为:

  • tf.constant_initializer(value)
  • tf.random_uniform_initializer(a,b)
  • tf.random_normal_initializer(mean,stddev)