tensorflow共享变量

撰写时间: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 tf
with 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.name
print b.name
print c.name
"""
result:
compute/a:0
b:0
compute/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.name
print b.name
print c.name
"""
result:
variable_scope/name_scope/a:0
variable_scope/b:0
variable_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 tf
with 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)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值