Tensorflow笔记——tf.Variable和tf.get_variable的区别以及tf.variable_scope以及tf.name_scope异同

一、 tf.Variable和tf.get_variable的区别

在Tensorflow中有两种方法生成变量variable,tf.get_variable()和tf.Variable()
1.tf,Variable

tf.Variable(
    initial_value=None, trainable=None, validate_shape=True, caching_device=None,
    name=None, variable_def=None, dtype=None, import_scope=None, constraint=None,
    synchronization=tf.VariableSynchronization.AUTO,
    aggregation=tf.compat.v1.VariableAggregation.NONE, shape=None
)

2.tf.get_variable

tf.get_variable(name, shape=None, dtype=None, initializer=None, 
regularizer=None, trainable=True, collections=None, 
caching_device=None, partitioner=None, validate_shape=True, 
custom_getter=None)

首先有一个区别非常明显:
(1) tf.Variable() 初始化是直接传入initial_value , 我们使用的时候一般是这样子初始化的:

a = tf.Variable(initial_value=tf.random_normal(shape=[200, 100], 
stddev=0.1), trainable=True)

(2)tf.get_variable()初始化是传入一个initializer:

b = tf.get_variable(name = 'weights', shape=[200, 100], dtype=tf.float32, 
initializer=tf.random_normal_initializer(stddev=0.1))

其次使用tf.Variable时,如果检测到命名冲突,系统会自己处理。

import tensorflow as tf
w_1 = tf.Variable(3,name="w_1")
w_2 = tf.Variable(1,name="w_1")
print w_1.name
print w_2.name
#输出
#w_1:0
#w_1_1:0

使用tf.get_variable()时,系统不会处理冲突,而会报错


import tensorflow as tf

w_1 = tf.get_variable(name="w_1",initializer=1)
w_2 = tf.get_variable(name="w_1",initializer=2)
#错误信息
#ValueError: Variable w_1 already exists, disallowed. Did
#you mean to set reuse=True in VarScope?

如果想要变量共享这时就需要了解tf.name_scope与tf.variable_scope用法

二、tf.name_scope与tf.variable_scope

1.tf.variable_scope

tf.variable_scope中有个参数reuse
其实只要记住一件事情就ok了:当reuse为False或者None时(这也是默认值),同一个tf.variable_scope下面的变量名不能相同;当reuse为True时,tf.variable_scope只能获取已经创建过的变量。

如果reuse=True是,get_variable会强制共享,如果不存在,报错;reuse=Flase时,会强制创造,如果已经存在,也会报错。

#reuse=False时会报错的情况:
with tf.variable_scope('test'):
    v = tf.get_variable('v',[1],initializer=tf.constant_initializer(1.0))

with tf.variable_scope('test'):
    v1 = tf.get_variable('v',[1])

在这种情况下会报错:Variable foo/v already exists, disallowed.Did you mean to set reuse=True in Varscope?
其原因就是在命名空间test中创建了相同的变量。如果我要在test下创建一个变量v1,其name=‘v’,只需要将reuse设置为Ture就ok了。将上面第二部分代码修改为:

with tf.variable_scope('test', reuse=True):
    v1 = tf.get_variable('v',[1])
    print(v1.name)      #结果为test/v

当reuse已经设置为True时,tf.variable_scope只能获取已经创建过的变量。这个时候,在命名空间bar中创建name=‘v’的变量v3,将会报错:Variable bar/v dose not exists, diallowed. Did you mean to set reuse=None in VarScope?

with tf.variable_scope('bar', reuse=True):
    v3 = tf.get_variable('v',[1])

简而言之,reuse=False时,tf.variable_scope创建变量;reuse=True时,tf.variable_scope获取变量

如果想实现“有则共享,无则新建”的方式只需要令reuse=tf.AUTO_REUSE即可

with tf.variable_scope('scp', reuse=tf.AUTO_REUSE) as scp:    
     a = tf.get_variable('a') #无,创造
     a = tf.get_variable('a') #有,共享

当你写一个建图模块时,你不知道用户是否会共享此模块,因此你可以只用tf.variable_scope来分组模块内变量,用tf.get_variable来为共享提供可能,而不能用tf.Variable。
所以当我们需要共享变量的时候,需要使用tf.get_variable()。在其他情况下,tf.name_scope与tf.variable_scope的用法是一样的

2.tf.name_scope
除了tf.variable_scope,tf.name_scope函数也提供了命名空间管理的功能。这两个函数在大部分情况下是等价的,唯一的区别是在使用tf.get_variable函数时。
tf.get_variable函数不受tf.name_scope的影响。
首先是tf.variable_scope:

with tf.variable_scope('foo'):
    a = tf.get_variable('bar',[1])
    print(a.name)#结果为foo/bar:0

再看tf.name_scope:

with tf.name_scope('a'):
    a=tf.Variable([1])
    print(a.name)#结果为a/Variable:0

    b=tf.get_variable('b',[1])
    print(b.name)#结果为b:0

从这个结果中,我们能很清晰地看到,tf.get_variable创建的变量并不是a/b:0,而是b:0。这就表示了在tf.name_scope函数下,tf.get_variable不受其约束。

tf.get_variable()创建的变量名不受tf.name_scope的影响,即创建的变量的name没有name_scope定义的前缀。而且,在未指定共享变量时,如果重名会报错。
在这里插入图片描述
tf.Variable()会自动检测有没有变量重名,如果有则会自行处理。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值