博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
理解 tf.Variable、tf.get_variable以及范围命名方法tf.variable_scope、tf.name_scope
阅读量:6208 次
发布时间:2019-06-21

本文共 4064 字,大约阅读时间需要 13 分钟。

tensorflow提供了通过变量名称来创建或者获取一个变量的机制。通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递。

1. tf.Variable(创建变量)与tf.get_variable(创建变量 或 复用变量)

TensorFlow中通过变量名获取变量的机制主要是通过tf.get_variabletf.variable_scope实现的。

变量可以通过tf.Varivale来创建。当tf.get_variable用于变量创建时,和tf.Variable的功能基本等价。

#以下两个定义是等价的v = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))v = tf.Variable(tf.constant(name='v',shape=[1],value=1.0))

tf.get_varialbe和tf.Variable最大的区别在于:

tf.Variable的变量名是一个可选项,通过name=’v’的形式给出。但是tf.get_variable必须指定变量名。

import tensorflow as tfwith tf.name_scope("a_name_scope"):    initializer = tf.constant_initializer(value=1)    var11 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)    var21 = tf.Variable(name='var21', initial_value=[2], dtype=tf.float32)    var22 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)    var23 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)with tf.Session() as sess:    sess.run(tf.global_variables_initializer())    print(var11.name)        # var1:0    print(sess.run(var11))   # [ 1.]    print(var21.name)        # a_name_scope/var21:0    print(sess.run(var21))   # [ 2.]    print(var22.name)       # a_name_scope/var2_1:0    print(sess.run(var22))  # [ 2.1]    print(var23.name)       # a_name_scope/var2_2:0    print(sess.run(var23))  # [ 2.2]

使用tf.Variable()定义的时候,虽然name都一样(name = 'var2'),但是为了不重复变量名,Tensorflow输出的变量名并不是一样的,如var22.name与var23.name的打印    

# a_name_scope/var2_1:0 与 # a_name_scope/var2_2:0    自动添加了_1与_2

本质上var21var22var23并不是一样的变量。

而另一方面,使用tf.get_variable()定义的变量不受tf.name_scope()当中的名字所影响。 

 

 

如果想要达到重复利用变量的效果,就要使用tf.variable_scope(),并搭配tf.get_variable()这种方式产生和提取变量

不像tf.Variable()每次都会产生新的变量tf.get_variable()如果遇到了同样名字的变量时,它会单纯的提取这个同样名字的变量(避免产生新变量)。

而在重复使用的时候,一定要在代码中强调scope.reuse_variables(),否则系统将会报错,以为你只是单纯的不小心重复使用到了一个变量。

 

with tf.variable_scope("a_variable_scope") as scope:    initializer = tf.constant_initializer(value=3)    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer) #创建变量    scope.reuse_variables() #申明重复使用,一定要有    var3_reuse = tf.get_variable(name='var3',) #提取变量复用    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)    with tf.Session() as sess:    sess.run(tf.global_variables_initializer())    print(var3.name)            # a_variable_scope/var3:0    print(sess.run(var3))       # [ 3.]    print(var3_reuse.name)      # a_variable_scope/var3:0    print(sess.run(var3_reuse)) # [ 3.]    print(var4.name)            # a_variable_scope/var4:0    print(sess.run(var4))       # [ 4.]    print(var4_reuse.name)      # a_variable_scope/var4_1:0    print(sess.run(var4_reuse)) # [ 4.]

 

2. tf.get_variable与tf.variable_scope

TensorFlow中通过变量名获取变量的机制主要是通过tf.get_variable和tf.variable_scope实现的

当reuse为True时,tf.variable_scope只能获取已经创建过的变量。 

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

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

 

 

3. tf.variable_scope与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.name_scope的影响

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

转载于:https://www.cnblogs.com/clemente/p/10131696.html

你可能感兴趣的文章
学习笔记之-------UIScrollView 基本用法 代理使用
查看>>
PHP array_count_values() 函数用于统计数组中所有值出现的次数。
查看>>
PHP笔记随笔
查看>>
php原生函数应用
查看>>
C Primer+Plus(十七)高级数据表示 编程练习(二)
查看>>
dede 5.7 任意用户重置密码前台
查看>>
DRF数据验证+数据存储
查看>>
统计单词个数(划分型)
查看>>
bzoj千题计划169:bzoj2463: [中山市选2009]谁能赢呢?
查看>>
bzoj千题计划282:bzoj4517: [Sdoi2016]排列计数
查看>>
分布式系统和元数据
查看>>
个人简介
查看>>
ggplot2 theme相关设置—文本调整
查看>>
PHP中如何解决高并发
查看>>
一种解决 MacBook 里的 App Store 无法登录的问题
查看>>
任务调度及远端管理(基于Quartz.net)
查看>>
A 子类继承父类,子类的构造函数会覆盖父类的构造函数
查看>>
Ubuntu下Postgres安装与配置
查看>>
如何理解运维
查看>>
基于光线追踪的渲染中景深(Depth of field)效果的实现
查看>>