变量名字由两部分组成:scope/变量name。

name 参数才是对象的唯一标识。

1、tf.name_scope()

Graph中保存着一个属性_name_stack(string类型),_name_stack的值保存着当前的name_scope的名字,在这个图中创建的对象Variable、Operation、Tensor的名字之前都加上了这个前缀。

#它的主要目的是为了更加方便地管理参数命名。
# 与 tf.Variable() 结合使用。简化了命名

with tf.name_scope('conv1') as scope:
weights1 = tf.Variable([1.0, 2.0], name='weights')
bias1 = tf.Variable([0.3], name='bias')

# 下面是在另外一个命名空间来定义变量的

with tf.name_scope('conv2') as scope:
weights2 = tf.Variable([4.0, 2.0], name='weights')
bias2 = tf.Variable([0.33], name='bias')

# 所以,实际上weights1 和 weights2 这两个引用名指向了不同的空间,不会冲突

print (weights1.name)
print (weights2.name) 输出:
conv1/weights:0
conv2/weights:0

********************************************************************

# 注意,这里的 with 和 python 中其他的 with 是不一样的
# 执行完 with 里边的语句之后,这个 conv1/ 和 conv2/ 空间还是在内存中的。这时候如果再次执行上面的代码
# 就会再生成其他命名空间(执行完上面的代码,接着执行这里的,上面的空间还在内存中)

with tf.name_scope('conv1') as scope:
weights1 = tf.Variable([1.0, 2.0], name='weights')
bias1 = tf.Variable([0.3], name='bias')
with tf.name_scope('conv2') as scope:
weights2 = tf.Variable([4.0, 2.0], name='weights')
bias2 = tf.Variable([0.33], name='bias')
print (weights1.name)
print (weights2.name) 输出:
conv1_1/weights:0
conv2_1/weights:0

注意,tf.Variable再次命名相同变量时(本来又要产生 conv1/weights:0  conv2/weights:0),结果这里产生了(conv1_1/weights:0 conv2_1/weights:0),所以这就是tf.Variable()的一个特性,遇到同名时,产生一个新的,并不共享。

2、 tf.variable_scope

Graph中维护一个collection,这个collection中的 键_VARSCOPE_KEY对应一个 [current_variable_scope_obj],保存着当前的variable_scope。使用 get_variable() 创建变量的时候,就从这个collection 取出 current_variable_scope_obj,通过这个 variable_scope创建变量。

tf.variable_scope() 主要结合 tf.get_variable() 来使用,实现变量共享。

如果tf.variable_scope函数使用参数reuse=None或者reuse=False创建上下文管理器,则tf.get_variable函数可以创建新的变量。但不可以创建已经存在的变量即为同名的变量。

如果tf.variable_scope函数使用参数reuse=True创建上下文管理器,则tf.get_variable函数可以使用已在当前空间定义的变量赋值来创建变量。但不可以使用不存在的变量来创建。

# 这里是正确的打开方式~~~可以看出,name 参数才是对象的唯一标识

with tf.variable_scope('v_scope') as scope1:
Weights1 = tf.get_variable('Weights', shape=[2, 3])
bias1 = tf.get_variable('bias', shape=[3])

# 下面来共享上面已经定义好的变量
# note: 在下面的 scope 中的变量必须已经定义过了,才能设置 reuse=True,否则会报错

with tf.variable_scope('v_scope', reuse=True) as scope2:
Weights2 = tf.get_variable('Weights')
Weights3 = tf.get_variable('Weights', [2,3]) #shape如果不同会报错
print (Weights2.name)
print (Weights3.name) 输出
v_scope/Weights:0
v_scope/Weights:0

# 可以看到这两个引用名称指向的是同一个内存对象

*********************************************************************

# 注意, bias1 的定义方式
with tf.variable_scope('v_scope') as scope1:
Weights1 = tf.get_variable('Weights', shape=[2, 3])
bias1 = tf.Variable([0.52], name='bias')
# 下面来共享上面已经定义好的变量
# note: 在下面的 scope 中的get_variable()变量必须已经定义过了,才能设置 reuse=True,否则会报错
with tf.variable_scope('v_scope', reuse=True) as scope2:
Weights2 = tf.get_variable('Weights')
bias2 = tf.Variable([0.53], name='bias')
print (Weights1.name)
print (Weights2.name)
print (bias1.name)
print (bias2.name) 输出:
v_scope / Weights:0
v_scope / Weights:0
v_scope / bias:0
v_scope_1 / bias:0

使用tf.get_variable发现之前有定义好的的该变量,则进行权值共享。

而bias1 = tf.Variable([0.52], name='bias')发现之前定义好的名字,则重新定一个新的,并没有共享权值。

tf.get_variable_scope() :获取当前scope

tf.get_variable_scope().reuse_variables() 共享变量

3、对比

简单来说name_scope是给Op_name加前缀的,variable_scope是给变量variable_name和Op_name加前缀的.作用域在使用Tensorboard对Graph对象进行可视化的时候很有帮助,作用域会把一些Op划分到较大的语句块当中.使用tensorboard可视化数据流图的时候,每个作用域都对自己的Op进行封装,从而获得更好的可视化效果.

  • 如果在 tf.name_scope() 环境下分别使用 tf.get_variable() 和 tf.Variable(),两者的主要区别在于
    • tf.get_variable() 创建的变量名不受 name_scope 的影响;
    • tf.get_variable() 创建的变量,name 属性值不可以相同;tf.Variable() 创建变量时,name 属性值允许重复(底层实现时,会自动引入别名机制)
  • 此外 tf.get_variable() 与 tf.Variable() 相比,多了一个 initilizer (初始化子)可选参数;
    • tf.Variable() 对应地多了一个 initial_value 关键字参数,也即对于 tf.Variable 创建变量的方式,必须显式初始化;

name_scope

with tf.name_scope("ns") as ns:
b = tf.Variable(1.0, name='b')
w = tf.get_variable("w", shape=[2,10],dtype=tf.float32)
a = tf.add(b, [3],name='a')
print ns
print b.name
print w.name
print a.name
输出:
ns /
ns / b:0
w:0
ns / a:0

*********************************************************************

with tf.name_scope("ns") as ns:
with tf.name_scope("ns1") as ns1:
b1 = tf.Variable(0, name='b1')
w1 = tf.get_variable("w1", shape=[10], dtype=tf.float32)
a1 = tf.add(b1, [3], name='a1')
print ns1
print b1.name
print w1.name
print a1.name 输出:
ns/ns1/
ns/ns1/b1:0
w1:0
ns/ns1/a1:0

*********************************************************************

with tf.name_scope("ns") as ns:
with tf.variable_scope("vs1") as vs1:
b2 = tf.Variable(0, name='b2')
w2 = tf.get_variable("w2", shape=[2])
a2 = tf.add(b2, [3], name='a2')
print vs1
print vs1.name
print b2.name
print w2.name
print a2.name 输出:
<tensorflow.python.ops.variable_scope.VariableScope object at 0x42fe790>
vs1
ns/vs1/b2:0
vs1/w2:0
ns/vs1/a2:0

*********************************************************************

with tf.name_scope("ns") as ns:
with tf.name_scope(None) as n1:
b3 = tf.Variable(2.0, name='b3')
w3 = tf.get_variable("w3", shape=[2])
a3 = tf.add(b3, [3], name='a3')
print n1
print b3.name
print w3.name
print a3.name 输出: b3:0
w3:0
a3:0

variable_scope

注意事项

1. 在 variable_scope 里面的 variable_scope 会继承上面的 reuse 值,即上面一层开启了 reuse ,则下面的也跟着开启。但是不能人为的设置 reuse 为 false ,只有退出 variable_scope 才能让 reuse 变为 false:

2、当在某一 variable_scope 内使用别的 scope 的名字时,此时不再受这里的等级关系束缚,直接与使用的 scope 的名字一样:

with tf.variable_scope("vs") as vs:
b = tf.Variable(1.0, name='b')
w = tf.get_variable("w", shape=[2, 10], dtype=tf.float32)
a = tf.add(b, [3], name='a')
print vs
print vs.name
print b.name
print w.name
print a.name 输出:
<tensorflow.python.ops.variable_scope.VariableScope object at 0x46ee610>
vs
vs/b:0
vs/w:0
vs/a:0

*********************************************************************

with tf.variable_scope("vs") as vs:
with tf.name_scope("ns1") as ns1:
b1 = tf.Variable(0, name='b1')
w1 = tf.get_variable("w1", shape=[10], dtype=tf.float32)
a1 = tf.add(b1, [3], name='a1')
print ns1
print b1.name
print w1.name
print a1.name 输出:
vs/ns1/
vs/ns1/b1:0
vs/w1:0
vs/ns1/a1:0

*********************************************************************

with tf.variable_scope("vs") as vs:
with tf.variable_scope("vs1") as vs1:
b2 = tf.Variable(0, name='b2')
w2 = tf.get_variable("w2", shape=[2])
a2 = tf.add(b2, [3], name='a2')
print vs1
print vs1.name
print b2.name
print w2.name
print a2.name 输出:
<tensorflow.python.ops.variable_scope.VariableScope object at 0x4b1e310>
vs/vs1
vs/vs1/b2:0
vs/vs1/w2:0
vs/vs1/a2:0

*********************************************************************

with tf.variable_scope("vs") as vs:
with tf.name_scope(None) as n1:
b3 = tf.Variable(2.0, name='b3')
w3 = tf.get_variable("w3", shape=[2])
a3 = tf.add(b3, [3], name='a3')
print n1
print b3.name
print w3.name
print a3.name 输出: b3:0
vs/w3:0
a3:0

总结:

1、使用tf.Variable()的时候,tf.name_scope()和tf.variable_scope() 都会给 Variable 和 op 的 name属性加上前缀。

2、使用tf.get_variable()的时候,tf.name_scope()就不会给 tf.get_variable()创建出来的Variable加前缀。

tensorflow-作用域的更多相关文章

  1. 学习笔记TF048:TensorFlow 系统架构、设计理念、编程模型、API、作用域、批标准化、神经元函数优化

    系统架构.自底向上,设备层.网络层.数据操作层.图计算层.API层.应用层.核心层,设备层.网络层.数据操作层.图计算层.最下层是网络通信层和设备管理层.网络通信层包括gRPC(google Remo ...

  2. 二、Tensorflow的作用域和图

    作用域主要用来不用重复定义变量,另外就是用与画图 import tensorflow as tf ''' 可视化 tf.summary.scalar 添加一个标量 tf.summary.audio 添 ...

  3. 『TensorFlow』线程控制器类&变量作用域

    线程控制器类 线程控制器原理: 监视tensorflow所有后台线程,有异常出现(主要是越界,资源循环完了)时,其should_stop方法就会返回True,而它的request_stop方法则用于要 ...

  4. tensorflow变量作用域(variable scope)

    举例说明 TensorFlow中的变量一般就是模型的参数.当模型复杂的时候共享变量会无比复杂. 官网给了一个case,当创建两层卷积的过滤器时,每输入一次图片就会创建一次过滤器对应的变量,但是我们希望 ...

  5. 4、TensorFlow基础(二)常用API与变量作用域

    1.图.操作和张量 TensorFlow 的计算表现为数据流图,所以 tf.Graph 类中包含一系列表示计算的操作对象(tf.Operation),以及在操作之间流动的数据 — 张量对象(tf.Te ...

  6. tensorflow的变量作用域

    一.由来 深度学习中需要使用大量的变量集,以往写代码我们只需要做全局限量就可以了,但在tensorflow中,这样做既不方便管理变量集,有不便于封装,因此tensorflow提供了一种变量管理方法:变 ...

  7. tensorflow中使用变量作用域及tf.variable(),tf,getvariable()与tf.variable_scope()的用法

    一 .tf.variable() 在模型中每次调用都会重建变量,使其存储相同变量而消耗内存,如: def repeat_value(): weight=tf.variable(tf.random_no ...

  8. Tensorflow 变量的共享

    https://github.com/chenghuige/tensorflow-exp/blob/master/examples/sparse-tensor-classification/ tens ...

  9. TF Boys (TensorFlow Boys ) 养成记(三)

    上次说到了 TensorFlow 从文件读取数据,这次我们来谈一谈变量共享的问题. 为什么要共享变量?我举个简单的例子:例如,当我们研究生成对抗网络GAN的时候,判别器的任务是,如果接收到的是生成器生 ...

  10. [tensorflow in a nutshell] tensorflow简明教程 (第一部分)

    原文链接: https://medium.com/@camrongodbout/tensorflow-in-a-nutshell-part-one-basics-3f4403709c9d#.31jv5 ...

随机推荐

  1. OneZero第五周第一次站立会议(2016.4.18)

    1. 时间: 13:00--13:15  共计15分钟. 2. 成员: X 夏一鸣 * 组长 (博客:http://www.cnblogs.com/xiaym896/), G 郭又铭 (博客:http ...

  2. psql -- PostgreSQL 交互终端

    psql --  PostgreSQL 交互终端 用法:psql [option...] [dbname [username]] 描述:psql 是一个以终端为基础的 PostgreSQL 前端.它允 ...

  3. Easy-UI开发总结

    Easy-UI开发总结 jQuery EasyUI 简介 jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面插件. 什么是 jQuery EasyUI jQuery Ea ...

  4. Spring之配置文件中引入其它配置文件

    <beans> ... <!--引入其它配置文件--> <import resource="classpath:com/helloworld/beans.xml ...

  5. ESLint的使用

    ESLint是在ECMAScript/JavaScript代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误.在许多方面,它和JSLint.JSHint相似,除了少数的例外: ESL ...

  6. Java 8新特性之Stream(八恶人-3)

    “You John Ruth The Hangman” 绞刑者鲁斯·约翰 “When the Hangman catches you, you hang.”当被绞刑者抓住了,你肯定会被绞死 一.基本介 ...

  7. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  8. 将句子表示为向量(上):无监督句子表示学习(sentence embedding)

    1. 引言 word embedding技术如word2vec,glove等已经广泛应用于NLP,极大地推动了NLP的发展.既然词可以embedding,句子也应该可以(其实,万物皆可embeddin ...

  9. 浅谈跨平台框架 Flutter 的优势与结构

    作者:个推iOS工程师 伊泽瑞尔 一.背景 目前,移动开发技术主要分为原生开发和跨平台开发两种.其中,原生应用是指在某个特定的移动平台上,使用平台所支持的开发工具和语言,直接调用系统提供的API所开发 ...

  10. pyspider框架的599证书问题

    使用PySpider 框架出现错误 HTTP 599: SSL certificate problem: unable to get local issuer certificate,如下 HTTP ...