欢迎转载,但请务必注明原文出处及作者信息。
@author: huangyongye
@creat_date: 2017-04-26
前言: 本例子主要介绍 name_scope 和 variable_scope 的正确使用方式,学习并理解本例之后,你就能够真正读懂 TensorFlow 的很多代码并能够清晰地理解模型结构了。
之前写过一个例子了: TensorFlow入门(四) name / variable_scope 的使用 但是当时其实还对 name / variable_scope 不是非常理解。所以又学习了一番,攒了这篇博客。学习本例子不需要看上一篇,但是咱们还是从上一篇说起:
* 起因:在运行 RNN LSTM 实例代码的时候出现 ValueError。 *
在 TensorFlow 中,经常会看到这 name_scope 和 variable_scope 两个东东出现,这到底是什么鬼,到底系做咩噶!!! 在做 LSTM 的时候遇到了下面的错误:
ValueError: Variable rnn/basic_lstm_cell/weights already exists, disallowed.
然后谷歌百度都查了一遍,结果也不知是咋回事。我是在 jupyter notebook 运行的示例程序,第一次运行的时候没错,然后就总是出现上面的错误。后来才知道是 get_variable() 和 variable_scope() 搞的鬼。
=========================================================
1. 先说结论
要理解 name_scope 和 variable_scope, 首先必须明确二者的使用目的。我们都知道,和普通模型相比,神经网络的节点非常多,节点节点之间的连接(权值矩阵)也非常多。所以我们费尽心思,准备搭建一个网络,然后有了图1的网络,WTF! 因为变量太多,我们构造完网络之后,一看,什么鬼,这个变量到底是哪层的??
fig1. 引入命名空间之前 | fig2. 引入命名空间之后 |
为了解决这个问题,我们引入了 name_scope 和 variable_scope, 二者又分别承担着不同的责任:
- * name_scope: * 为了更好地管理变量的命名空间而提出的。比如在 tensorboard 中,因为引入了 name_scope, 我们的 Graph 看起来才井然有序。
- * variable_scope: * 大大大部分情况下,跟 tf.get_variable() 配合使用,实现变量共享的功能。
下面通过两组实验来探索 TensorFlow 的命名机制。
2. (实验一)三种方式创建变量: tf.placeholder, tf.Variable, tf.get_variable
2.1 实验目的:探索三种方式定义的变量之间的区别
import tensorflow as tf
# 设置GPU按需增长
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
# 1.placeholder
v1 = tf.placeholder(tf.float32, shape=[2,3,4])
print v1.name
v1 = tf.placeholder(tf.float32, shape=[2,3,4], name='ph')
print v1.name
v1 = tf.placeholder(tf.f