【Dock】TensorFlow -- name_scope和variable_scope的用法

1.结论

要理解name_scope和variable_scope, 首先必须明确两者的使用目的。 我们都直到, 和普通模型相比,神经网络的节点非常多, 节点与节点之间的连接(权值矩阵)也非常多。所以我们费尽心思,准备搭建一个网络,然后有了图一的网络,WTF!因为变量太多,我们构造完网络之后,一看,什么鬼,这个变量到底是哪层的?
在这里插入图片描述为了解决这个问题, 我们引入了name_scope和variable_scope。两者分别承担不同的责任:

  • name_scope: 为了更好的管理变量的命名空间而提出来的,比如在tensorboard中,因为引入了name, 我们的Graph看起来才尽然有序。
  • variable_scope: 大大大部分情况下, 跟tf.get_variable()配合使用,实现变量共享的功能。

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.float32, shape = [2, 3, 4], name = 'ph')
print(v1.name)
print(type(v1))
print(v1)
运行结果
Placeholder:0
ph:0
ph_1:0
<class 'tensorflow.python.framework.ops.Tensor'>
Tensor("ph_1:0", shape=(2, 3, 4), dtype=float32)

# 2.tf.Variable()
v2 = tf.Variable([1, 2], dtype = tf.float32)
print(v2.name)
v2 = tf.Variable([1, 2], dtype = tf.float32, name = 'V')
print(v2.name)
v2 = tf.Variable([1, 2], dtype = tf.float32, name = 'V')
print(v2.name)
print(type(v2))
print(v2)
运行结果
Variable:0
V:0
V_1:0
<class 'tensorflow.python.ops.variables.Variable'>
Tensor("V_1/read:0", shape=(2,), dtype=float32)

# 3.tf.get_variable()创建变量的时候必须提供name
v3 = tf.get_variable(name = 'gv', shape = [])
print(v3.name)
v4 = tf.get_variable(name = 'gv', shape = [2])
print(v4.name)
运行结果
gv:0
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-7-29efaac2d76c> in <module>()
      2 v3 = tf.get_variable(name='gv', shape=[])
      3 print v3.name
----> 4 v4 = tf.get_variable(name='gv', shape=[2])
      5 print v4.name
此处还有一堆错误信息。。。
ValueError: Variable gv already exists, disallowed. Did you mean to set reuse=True in VarScope? Originally defined at:
...

print type(v3)
print v3
class 'tensorflow.python.ops.variables.Variable'>
Tensor("gv/read:0", shape=(), dtype=float32)

还记得有这么个函数吗? tf.trainable_variables(), 它能够将我们定义的所有的 trainable=True 的所有变量以一个list的形式返回。 very good, 现在要派上用场了。

vs = tf.trainable_variables()
print(len(vs))
for v in vs:
    print(v)
运行结果
4
Tensor("Variable/read:0", shape=(2,), dtype=float32)
Tensor("V/read:0", shape=(2,), dtype=float32)
Tensor("V_1/read:0", shape=(2,), dtype=float32)
Tensor("gv/read:0", shape=(), dtype=float32)

2.2 实验一结论

从上面的实验结论来看,这三种方式所定义的变量具有相同的类型,而且只有tf.get_variable()创建的变量之间会发生命名冲突,在实际使用中,三种创建变量方式的用途也是分工非常明确的。其中:

  • tf.placeholder()占位符。 trainable == False
  • tf.Variable() 一般变量用这种方式定义。可以选择trainable类型
  • tf.get_variable()一般都是和tf.variable_scope()配合使用,从而实现变量共享的功能。 可以选择trainable类型

3.(实验二)探索name_scope和variable_scope

实验二的目的:熟悉两种命名空间的应用场景

import tensorflow as tf
# 设置GPU按需增长
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config = config)
with tf.name_scope('nsc1'):
	v1 = tf.Variable([1], name = 'v1')
	with tf.variable_scope('vsc1'):
		v2 = tf.Variable([1], name = 'v2')
		v3 = tf.get_variable(name = 'v3', shape = [])
print('v1.name: ', v1.name)
print('v2.name: ', v2.name)
print('v3.name: ', v3.name)
运行结果
v1.name:  nsc1/v1:0
v2.name:  nsc1/vsc1/v2:0
v3.name:  vsc1/v3:0
with tf.name_scope('nsc1'):
    v4 = tf.Variable([1], name='v4')
print 'v4.name: ', v4.name
运行结果
v4.name:  nsc1_1/v4:0

tf.name_scope()并不会对tf.get_variable()创建的变量有任何影响。
tf.name_scope()主要是用量管理命名空间的,这样子让我们的整个模型更加有条理。
tf.variable_scope()的作用是为了实现变量共享,它和tf.get_variable()来完成变量的共享功能。

1.第一组, 用tf.Variable()的方式来定义。

import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config = config)

def my_image_filter():
	conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]), name = 'conv1_weights')
	conv1_biases = tf.Variable(tf.zeros([32]), name = 'conv1_biases')
	conv2_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]), name = 'conv2_weights')
	conv2_biases = tf.Variable(tf.zeros([32]), name = 'conv2_biases')
	return None

result1 = my_image_filter()
result2 = my_image_filter()
vs = tf.trainanle_variables()
print('Ther are %d train_able_variables in the Graph: '%len(vs))
for v in vs:
	print(v)
运行结果
There are 8 train_able_variables in the Graph: 
Tensor("conv1_weights/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("conv1_biases/read:0", shape=(32,), dtype=float32)
Tensor("conv2_weights/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("conv2_biases/read:0", shape=(32,), dtype=float32)
Tensor("conv1_weights_1/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("conv1_biases_1/read:0", shape=(32,), dtype=float32)
Tensor("conv2_weights_1/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("conv2_biases_1/read:0", shape=(32,), dtype=float32)

第二种方式, 用tf.get_variable()的方式

import tensorflow as tf
config = tf.ConfigProto()
config,gpu_options.allow_growth = True
sess = tf.Session(config = config)

def conv_relu(kernel_shape, bias_shape):
	weight = tf.get_variable('weights', kernel_shape, initializer = tf.random_normal_initializer())
	biases = tf.get_Variable('biases', bias_shape, initializer = tf.constant_initializer(0.0))
	return None

def my_image_filter():
	with tf.variable_scope('conv1'):
		relu1 = conv_relu([5, 5, 32 ,32], [32])
	with tf.variable_scope('conv2'):
		relu2 = conv_relu([5, 5, 32, 32], [32])

with tf.variable_scope('image_filters') as scope:
	result1 = my_image_filter()
	scope.resuse_variables()
	result2 = my_image_filter()

vs = tf.trainable_variables()
print(len(vs))
for v in vs:
	print(v)
运行结果
There are 4 train_able_variables in the Graph: 
Tensor("image_filters/conv1/weights/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("image_filters/conv1/biases/read:0", shape=(32,), dtype=float32)
Tensor("image_filters/conv2/weights/read:0", shape=(5, 5, 32, 32), dtype=float32)
Tensor("image_filters/conv2/biases/read:0", shape=(32,), dtype=float32)

3.2 实验二结论

首先我们要确立一种 Graph 的思想。在 TensorFlow 中,我们定义一个变量,相当于往 Graph 中添加了一个节点。和普通的 python 函数不一样,在一般的函数中,我们对输入进行处理,然后返回一个结果,而函数里边定义的一些局部变量我们就不管了。但是在 TensorFlow 中,我们在函数里边创建了一个变量,就是往 Graph 中添加了一个节点。出了这个函数后,这个节点还是存在于 Graph 中的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值