上次说到了 TensorFlow 从文件读取数据,这次我们来谈一谈变量共享的问题。

为什么要共享变量?我举个简单的例子:例如,当我们研究生成对抗网络GAN的时候,判别器的任务是,如果接收到的是生成器生成的图像,判别器就尝试优化自己的网络结构来使自己输出0,如果接收到的是来自真实数据的图像,那么就尝试优化自己的网络结构来使自己输出1。也就是说,生成图像和真实图像经过判别器的时候,要共享同一套变量,所以TensorFlow引入了变量共享机制。

变量共享主要涉及到两个函数: tf.get_variable(<name>, <shape>, <initializer>) 和 tf.variable_scope(<scope_name>)。

先来看第一个函数: tf.get_variable。

tf.get_variable 和tf.Variable不同的一点是,前者拥有一个变量检查机制,会检测已经存在的变量是否设置为共享变量,如果已经存在的变量没有设置为共享变量,TensorFlow 运行到第二个拥有相同名字的变量的时候,就会报错。

例如如下代码:

def my_image_filter(input_images):
conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv1_weights")
conv1_biases = tf.Variable(tf.zeros([32]), name="conv1_biases")
conv1 = tf.nn.conv2d(input_images, conv1_weights,
strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv1 + conv1_biases)

有两个变量(Variables)conv1_weighs, conv1_biases和一个操作(Op)conv1,如果你直接调用两次,不会出什么问题,但是会生成两套变量;

# First call creates one set of 2 variables.
result1 = my_image_filter(image1)
# Another set of 2 variables is created in the second call.
result2 = my_image_filter(image2)

如果把 tf.Variable 改成 tf.get_variable,直接调用两次,就会出问题了:

result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Raises ValueError(... conv1/weights already exists ...)

为了解决这个问题,TensorFlow 又提出了 tf.variable_scope 函数:它的主要作用是,在一个作用域 scope 内共享一些变量,可以有如下几种用法:

1)

with tf.variable_scope("image_filters") as scope:
result1 = my_image_filter(image1)
scope.reuse_variables() # or
#tf.get_variable_scope().reuse_variables()
result2 = my_image_filter(image2)

需要注意的是:最好不要设置 reuse 标识为 False,只在需要的时候设置 reuse 标识为 True。

2)

with tf.variable_scope("image_filters1") as scope1:
result1 = my_image_filter(image1)
with tf.variable_scope(scope1, reuse = True)
result2 = my_image_filter(image2)

通常情况下,tf.variable_scope 和 tf.name_scope 配合,能画出非常漂亮的流程图,但是他们两个之间又有着细微的差别,那就是 name_scope 只能管住操作 Ops 的名字,而管不住变量 Variables 的名字,看下例:

with tf.variable_scope("foo"):
with tf.name_scope("bar"):
v = tf.get_variable("v", [1])
x = 1.0 + v
assert v.name == "foo/v:0"
assert x.op.name == "foo/bar/add"

参考资料:

1. https://www.tensorflow.org/how_tos/variable_scope/

TF Boys (TensorFlow Boys ) 养成记(三)的更多相关文章

  1. TF Boys (TensorFlow Boys ) 养成记(三): TensorFlow 变量共享

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

  2. TF Boys (TensorFlow Boys ) 养成记(一)

    本资料是在Ubuntu14.0.4版本下进行,用来进行图像处理,所以只介绍关于图像处理部分的内容,并且默认TensorFlow已经配置好,如果没有配置好,请参考官方文档配置安装,推荐用pip安装.关于 ...

  3. TF Boys (TensorFlow Boys ) 养成记(一):TensorFlow 基本操作

    本资料是在Ubuntu14.0.4版本下进行,用来进行图像处理,所以只介绍关于图像处理部分的内容,并且默认TensorFlow已经配置好,如果没有配置好,请参考官方文档配置安装,推荐用pip安装.关于 ...

  4. TF Boys (TensorFlow Boys ) 养成记(四)

    前面基本上把 TensorFlow 的在图像处理上的基础知识介绍完了,下面我们就用 TensorFlow 来搭建一个分类 cifar10 的神经网络. 首先准备数据: cifar10 的数据集共有 6 ...

  5. TF Boys (TensorFlow Boys ) 养成记(二)

    TensorFlow 的 How-Tos,讲解了这么几点: 1. 变量:创建,初始化,保存,加载,共享: 2. TensorFlow 的可视化学习,(r0.12版本后,加入了Embedding Vis ...

  6. TF Boys (TensorFlow Boys ) 养成记(二): TensorFlow 数据读取

    TensorFlow 的 How-Tos,讲解了这么几点: 1. 变量:创建,初始化,保存,加载,共享: 2. TensorFlow 的可视化学习,(r0.12版本后,加入了Embedding Vis ...

  7. TF Boys (TensorFlow Boys ) 养成记(四):TensorFlow 简易 CIFAR10 分类网络

    前面基本上把 TensorFlow 的在图像处理上的基础知识介绍完了,下面我们就用 TensorFlow 来搭建一个分类 cifar10 的神经网络. 首先准备数据: cifar10 的数据集共有 6 ...

  8. TF Boys (TensorFlow Boys ) 养成记(六)

    圣诞节玩的有点嗨,差点忘记更新.祝大家昨天圣诞节快乐,再过几天元旦节快乐. 来继续学习,在/home/your_name/TensorFlow/cifar10/ 下新建文件夹cifar10_train ...

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

    有了数据,有了网络结构,下面我们就来写 cifar10 的代码. 首先处理输入,在 /home/your_name/TensorFlow/cifar10/ 下建立 cifar10_input.py,输 ...

随机推荐

  1. c# SqlHelper Class

    using System;using System.Collections;using System.Collections.Generic;using System.Data;using Syste ...

  2. 去掉UItableview headerview黏性(sticky)

    // 去掉UItableview headerview黏性(sticky) - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFlo ...

  3. UVAlive3486_Cells

    给一棵树,每次每次询问一个点是否是另一个点的祖先? 首先,题目的读入就有点坑爹,注意,每个节点的值是说明它下面有多少个儿子节点,直接对于每个下标保存一个值即可. 对于查询是否是祖先,我们可以对于每一个 ...

  4. sublime构建执行go程序真爽

    1.安装gosublime插件 2.直接在sublime下调试运行共程序,不用去cmd了: 选择编译系统,编译,出现下面的模拟命令行,直接执行go的命令即可,比如go run process.go,结 ...

  5. mysql基本命令(转)

    连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密码前必须没有空 ...

  6. jquery实现TODOList

    html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  7. iOS 设置navigationBar背景

    - (void)viewWillAppear:(BOOL)animated {    [superviewWillAppear:animated];    [self.navigationContro ...

  8. 【Python自动化运维之路Day6】

    1.递归思考题,阶乘 使用递归方式(函数)计算: 1*2*3*4*5*6*7*8*9*10的值 def func(num): if num==1: return 1 return num*func(n ...

  9. SQLSERVER 2012之AlwaysOn -- 一次硬件升级引发的问题

    这是上周遇到的一个案例:对已有的硬件进行升级而引发的问题,期间还触发了一个比较严重的BUG,可谓多灾多难:不过值得庆幸的是,在一连串连锁问题出现的时候,并没有出现人工操作失误(这往往是在处理故障中风险 ...

  10. golang 值得注意的地方(2则)

    golang 的语法和使用方式都非常简单明了,没有花哨的语法糖,也没有多余的关键字. 但是即使是这么简洁的语言,仍然有一些不那么直白,需要注意的地方,比如下面2点. interface 赋值 nil ...