版权声明:本文为博主原创文章,遵循 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_scopetf.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_scopetf.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的更多相关文章

  1. tensorflow里面共享变量、name_scope, variable_scope等如何理解

    tensorflow里面共享变量.name_scope, variable_scope等如何理解 name_scope, variable_scope目的:1 减少训练参数的个数. 2 区别同名变量 ...

  2. Tensorflow函数——tf.variable_scope()

    Tensorflow函数——tf.variable_scope()详解 https://blog.csdn.net/yuan0061/article/details/80576703 2018年06月 ...

  3. tensorflow中的name_scope, variable_scope

    在训练深度网络时,为了减少需要训练参数的个数(比如LSTM模型),或者是多机多卡并行化训练大数据.大模型等情况时,往往就需要共享变量.另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变 ...

  4. tensorflow 中 name_scope 及 variable_scope 的异同

    Let's begin by a short introduction to variable sharing. It is a mechanism in TensorFlow that allows ...

  5. tensorflow 中 name_scope和variable_scope

    import tensorflow as tf with tf.name_scope("hello") as name_scope: arr1 = tf.get_variable( ...

  6. Tensorflow 之 name/variable_scope 变量管理

    name/variable_scope 的作用 充分理解 name / variable_scope TensorFlow 入门笔记 当一个神经网络比较复杂.参数比较多时,就比较需要一个比较好的方式来 ...

  7. [转载]Tensorflow 的reduce_sum()函数的axis,keep_dim这些参数到底是什么意思?

    转载链接:https://www.zhihu.com/question/51325408/answer/125426642来源:知乎 这个问题无外乎有三个难点: 什么是sum 什么是reduce 什么 ...

  8. [图解tensorflow源码] [转载] tensorflow设备内存分配算法解析 (BFC算法)

    转载自 http://weibo.com/p/1001603980563068394770   @ICT_吴林阳 tensorflow设备内存管理模块实现了一个best-fit with coales ...

  9. [转载]tensorflow中使用tf.ConfigProto()配置Session运行参数&&GPU设备指定

    tf.ConfigProto()函数用在创建session的时候,用来对session进行参数配置: config = tf.ConfigProto(allow_soft_placement=True ...

  10. [转载]Tensorflow中reduction_indices 的用法

    Tensorflow中reduction_indices 的用法 默认时None 压缩成一维

随机推荐

  1. Visual Studio(VS)常用快捷键整理

    ​ 前言 在使用Visual Studio编写代码时,使用快捷键能够提高编码效率,作为程序员,我们有必要记住一些比较常用的快捷键.这篇文章将记录我自己比较常用的快捷键,并根据我的使用情况,更新常用快捷 ...

  2. 算法金 | 一文彻底理解机器学习 ROC-AUC 指标

    ​ 大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 在机器学习和数据科学的江湖中,评估模型的好坏是非常关键的一环.而 ROC(Rece ...

  3. [DP] DP优化总结

    写在前面 $ DP $,是每个信息学竞赛选手所必会的算法,而 $ DP $ 中状态的转移又显得尤为关键.本文主要从状态的设计和转移入手,利用各种方法对朴素 $ DP $ 的时间复杂度和空间复杂度进行优 ...

  4. NumPy 舍入小数、对数、求和和乘积运算详解

    舍入小数 在 NumPy 中,主要有五种方法来舍入小数: 截断 去除小数部分,并返回最接近零的浮点数.使用 trunc() 和 fix() 函数. 示例: import numpy as np arr ...

  5. flutter 环境搭配 (一)

    首先下载flutter SDK Flutter中文网 官网 (p2hp.com 选择下载 SDK 解压后 ,添加到环境变量中. 配置国内镜像, PUB_HOSTED_URL=https://pub.f ...

  6. poj1338 ugly number 题解 打表

    类似的题目有HDU1058 humble number(翻译下来都是丑陋的数字). Description Ugly numbers are numbers whose only prime fact ...

  7. 国内外公共 DNS调研

    结论 国内可以在以下DNS选择:114DNS.阿里DNS.(阿里请联系我,给我广告费^_^) 国外可以在以下DNS选择:谷歌DNS.1.1.1.1 DNS.Cisco Umbrella DNS. 国内 ...

  8. 基于MCU的SD卡fat文件系统读写移植

    背景 https://blog.csdn.net/huang20083200056/article/details/78508490 SD卡(Secure Digital Memory Card)具有 ...

  9. 莫名其妙的bug——Segmentation fault

    vscode出现Segmentation fault异常,但是没有问题报错(如上) 先说原因:cout << dp[m]; m没有输入,一个空定义(空指针) 难受啊,有一次cf因为这个bu ...

  10. day02模板与配置

    一.WXML模板语法 1.1 数据绑定 绑定内容 跟vue差不多,在页面的js文件定义到data里面 然后通过插值语法用在wxml中即可 绑定属性 直接写上插值语法,没有: 三元运算 生成一个十以内的 ...