【转载】 TensorFlow之name_scope/variable_scope
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013745804/article/details/80428618
————————————————
引子
前面写过一篇博文《TensorFlow学习笔记(六)》,其内容主要介绍的就是name_scope/variable_scope的使用,不过并没有明确地对这二者的使用场景进行区分,所以本文将清晰地给出name_scope / variable_scope的应用场景。
文章比较长,如果时间不够的话,那就直接看总结啦~
主要用法
我们知道,在TensorFlow中,常常会定义一堆节点,如果我们不能对此进行有效地管理,那么这些节点很可能会使我们心如乱麻,并且再也不想看这些杂乱的代码。
name_scope / variable_scope 正是为了更有效地管理节点而产生的两个操作(op)。
- name_scope:用于对变量设置命名域,从而让变量按照其关系组成一个个scope,并不会对tf.get_variable()创建的变量名字产生影响;
- variable_scope:绝大部分情形下,与tf.get_variable()配合使用,实现变量共享。
示例
我们下面举几个简单的例子:
a)利用name_scope对tf.Variable创建的变量加上命名域:
with tf.name_scope("scope_1"):
v1 = tf.Variable([1], name="v1", dtype=tf.float32)
v2 = tf.get_variable("v2", [1])
print v1
print v2
此时输出结果为:
<tf.Variable 'scope_1/v1:0' shape=(1,), dtype=float32_ref>
<tf.Variable 'v2:0' shape=(1,) dtype=float32_ref>
从这里我们可以得出下列结论:
- name_scope并不会对 tf.get_variable() 创建的变量添加命名域;
- name_scope并不能用于实现变量共享。
b)结合使用variable_scope与tf.get_variable()实现变量共享:
实验一
with tf.variable_scope("scope_1"):
v1 = tf.Variable([1], name="v1", dtype=tf.float32)
with tf.variable_scope("scope_1"):
v2 = tf.Variable([1], name="v1", dtype=tf.float32)
此时的输出结果为:
<tf.Variable 'scope_1/v1:0' shape=(1,), dtype=float32_ref>
<tf.Variable 'scope_1_1/v1:0' shape=(1,), dtype=float32_ref>
这个实验说明了tf.Variable()遇到重名变量时,将自动重命名,而不会发生冲突。在这个实验中,我们是在同一个scope中定义的同名变量,可是为什么不是修改最内层的变量名呢?也即为什么输出结果不是下面这样呢?
<tf.Variable 'scope_1/v1:0' shape=(1,), dtype=float32_ref>
<tf.Variable 'scope_1/v1_1:0' shape=(1,), dtype=float32_ref>
这是TensorFlow的一种很巧妙的手段,因为tf.Variable()被设计为提供给库编写者使用的一个接口,所以我们修改scope的话更加有利。为什么这么说?比如,我们运行下面的代码:
net = fully_connected(input_tensor, shape)
net = fully_connected(net, shape)
这个时候我们对fully_connected()函数的两次调用均没有给出scope,那这个时候我们的全连接层中的变量应该如何命名呢?这就与上面的实验情形类似了,TFLearn的fully_connected()函数是使用tf.Variable()实现的,所以一般情况下,将会使用默认的“FullyConnected”这一scope作为命名域,当我们第二次调用fully_connected()函数时,自动改变命名域为“FullyConnected_1”,而不是修改命名域内部的变量名,是不是比直接改最内层的变量名要合理许多?
那如果我们改变最内层的变量名,假设我们的函数fn()在scope中定义了“scope/v1, scope/v2”,那么,我们接下来将重命名为“scope/v1_1, scope/v2_1”,这样的话,那不是都在同一个scope中了么?到时候在TensorBoard中将显得乱七八糟~
对了,tf.Variable()在解决冲突时,总是重命名最外层的scope哟~验证如下:
with tf.variable_scope("scope_top"):
with tf.variable_scope("scope_bot"):
v1 = tf.Variable([1], name="v1", dtype=tf.float32)
with tf.variable_scope("scope_top"):
with tf.variable_scope("scope_bot"):
v2 = tf.Variable([1], name="v1", dtype=tf.float32)
vs=tf.trainable_variables()
for v in vs:
print v
此时,我们的输出为:
<tf.Variable 'scope_top/scope_bot/v1:0' shape=(1,), dtype=float32_ref>
<tf.Variable 'scope_top_1/scope_bot/v1:0' shape=(1,), dtype=float32_ref>
这样的话,如果我们调用一些基本的Layers来定义自己的Layer,比如说叫做layer_udef,且默认命名域为“Layer_Udef”,那么重复使用layer_udef时,得到的是“Layer_Udef”、“Layer_Udef_1”…这就很符合我们的预期咯。
实验二
在实验一中,我们发现使用tf.Variable()并不能获取已经定义变量,换句话说,不能达到共享变量的目的,那我们能否用tf.get_variable()函数获取tf.Variable()定义的变量呢?
with tf.variable_scope("scope_1"):
v1 = tf.Variable([1], name="v1", dtype=tf.float32)
print v1
with tf.variable_scope("scope_1", reuse=True):
v2 = tf.get_variable("v1", [1])
输出为:
<tf.Variable 'scope_1/v1:0' shape=(1,) dtype=float32_ref>
...
ValueError: Variable scope_1/v1 does not exist, or was not created with tf.get_variable().
相信大家都有疑惑,不是已经有了scope_1/v1变量么?为什么说它不存在呢?因为tf.Variable()所定义的变量并不是用于共享的,虽然它对于tf.get_variable()是可见的:
with tf.variable_scope("scope_1"):
v1 = tf.Variable([1], name="v1", dtype=tf.float32)
with tf.variable_scope("scope_1"):
v2 = tf.get_variable("v1", [1])
此时输出为:
<tf.Variable 'scope_1/v1:0' shape=(1,) dtype=float32_ref>
<tf.Variable 'scope_1/v1_1:0' shape=(1,) dtype=float32_ref>
那到底为什么tf.Variable()定义的变量不能共享呢?
这就涉及到tf.Variable()和tf.get_variable()的设计理念了:个人认为,tf.Variable()主要是为库的编写者设计,或者,我们可以用它来编写自己的需要重复定义的Layers,这样就不用操心变量之间的冲突了,这一点我们在实验一中已经说明过了。所以,当我们想要从最底层开始定义自己的层时,使用tf.Variable()吧~
实验三
说了这么多,那到底怎样才能成功地共享变量呢?
with tf.variable_scope("scope_1"):
v1 = tf.get_variable("v1", [1])
with tf.variable_scope("scope_1", reuse=True):
v2 = tf.get_variable("v1", [1])
vs = tf.trainable_variables()
for v in vs:
print v
此时我们的输出为:
<tf.Variable 'scope_1/v1:0' shape=(1,) dtype=float32_ref>
也就是说,变量“scope_1/v1”被共享咯~
总结
现将本文总结如下:
name_scope并不会对tf.get_variable()定义的变量的命名产生影响;
如果要从底层变量开始定义库函数的话,使用tf.Variable()是一种较好的选择;
tf.Variable()定义的变量并不能被共享;
如果想要实现变量共享,那就同时使用variable_scope和tf.get_variable()吧~
【转载】 TensorFlow之name_scope/variable_scope的更多相关文章
- tensorflow里面共享变量、name_scope, variable_scope等如何理解
tensorflow里面共享变量.name_scope, variable_scope等如何理解 name_scope, variable_scope目的:1 减少训练参数的个数. 2 区别同名变量 ...
- Tensorflow函数——tf.variable_scope()
Tensorflow函数——tf.variable_scope()详解 https://blog.csdn.net/yuan0061/article/details/80576703 2018年06月 ...
- tensorflow中的name_scope, variable_scope
在训练深度网络时,为了减少需要训练参数的个数(比如LSTM模型),或者是多机多卡并行化训练大数据.大模型等情况时,往往就需要共享变量.另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变 ...
- tensorflow 中 name_scope 及 variable_scope 的异同
Let's begin by a short introduction to variable sharing. It is a mechanism in TensorFlow that allows ...
- tensorflow 中 name_scope和variable_scope
import tensorflow as tf with tf.name_scope("hello") as name_scope: arr1 = tf.get_variable( ...
- Tensorflow 之 name/variable_scope 变量管理
name/variable_scope 的作用 充分理解 name / variable_scope TensorFlow 入门笔记 当一个神经网络比较复杂.参数比较多时,就比较需要一个比较好的方式来 ...
- [转载]Tensorflow 的reduce_sum()函数的axis,keep_dim这些参数到底是什么意思?
转载链接:https://www.zhihu.com/question/51325408/answer/125426642来源:知乎 这个问题无外乎有三个难点: 什么是sum 什么是reduce 什么 ...
- [图解tensorflow源码] [转载] tensorflow设备内存分配算法解析 (BFC算法)
转载自 http://weibo.com/p/1001603980563068394770 @ICT_吴林阳 tensorflow设备内存管理模块实现了一个best-fit with coales ...
- [转载]tensorflow中使用tf.ConfigProto()配置Session运行参数&&GPU设备指定
tf.ConfigProto()函数用在创建session的时候,用来对session进行参数配置: config = tf.ConfigProto(allow_soft_placement=True ...
- [转载]Tensorflow中reduction_indices 的用法
Tensorflow中reduction_indices 的用法 默认时None 压缩成一维
随机推荐
- Winform绘制圆形图
1 private void Form_Load(object sender, EventArgs e) 2 { 3 PictureBox pic = new PictureBox(); 4 pic. ...
- 如何生成war包
pom.xml <packaging>war</packaging> 引入tomcat <dependency> <groupId>org.spring ...
- 记一下 localstorage sessionStorage cookie 不同
localStorage.sessionStorage.cookie 使用整理 下面从这几方面进行梳理 存储形式 相同点 不同点 使用方法 用途 多标签之间通讯 一.存储形式 1.localStron ...
- 重学前端 - react 项目第一节:创建react 项目
重学前端 - react 项目第一节:创建react 项目 简介:之前一直使用的都是 vue 全家桶开发项目,现在在新的项目上开始使用react开发. 现在开始在重新学习一下 react 相关技术. ...
- Merry Christmas 礼物
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` Merry Christmas 礼物 日期:2020-12 ...
- 硬件开发笔记(十九):Altium Designer 21软件介绍和安装过程
前言 AD硬件设计软件之一,前面说了allego,但是allego对项目的管理.原理图生成PCB,PCB反向原理图等方面比较复杂,对于一般的硬件(非多个高速电路),选择AD能够加大的节省开发工作量 ...
- Windows下Qt5程序打包发布
Windows下Qt5程序打包发布与图标设置 原文(有删改):https://blog.csdn.net/qq_39105333/article/details/114779650 设置程序图标 默认 ...
- vue - ElementUI
关于ElementUI最好还是通过实践项目来做,来熟悉. 这只是一些ElementUI的注意事项,至此vue2的内容真的全部完结,后面将继续vue3的内容更新. 一.完整引入 一般提及什么什么UI会有 ...
- .Net Core WebApi 使用 JWT 验证身份
.h2 { background-color: rgba(78, 110, 242, 1); color: rgba(255, 255, 255, 1); padding: 10px } 一.注册身份 ...
- Centos7安装Redis详细步骤(配置开机自启)
Redis 获取redis安装包使用tar命令解压. $ tar -zxzf redis-6.2.6.tar.gz 编译和安装redis 进入redis目录,执行make编译. $ cd redis- ...