Tensorflow基础知识---共享管理(name_scope()和variable_scope()的区别)

写在前面

工作之余,学习tensorflow已经有一段时间了,时间总是零零碎碎,期间也用tensorflow搭建过一些框架,但是代码都是在参考别人的基础上实现的,随着对模型的深入,开始自己写代码框架,在写的过程中发现自己的基础不是很扎实,特别是对Tensorflow的一些基础的api并不是完全领会,当初只是知道别人是这么用的,所以我也跟着用了。现在自己的定义的时候发现他们之间的差别不是很清楚,所以还是得静下心来把这些基础知识弄清楚。

tf.Variable() & tf.get_variable()

在了解tf.name_scope() & tf.variable_scope()的之间的区别的时候,我们的先需要了解Tensorflow中的变量的定义。

代码1

import tensorflow as tf

var1 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)

initializer = tf.constant_initializer(value=1)
var3 = tf.get_variable(name='var3', initializer=initializer, shape=[1], dtype=tf.float32)
var4 = tf.get_variable(name='var4', initializer=initializer, shape=[1], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name)
    print(sess.run(var1))
    print(var2.name)
    print(sess.run(var2))

    print(var3.name)
    print(sess.run(var3))
    print(var4.name)
    print(sess.run(var4))

运行结果:

var1:0
[1.]
var2:0
[2.]
var3:0
[1.]
var4:0
[1.]

在保持其他代码不变的情况下,我们把name修改成相同的之后,运行代码

代码2

import tensorflow as tf

var1 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
var2 = tf.Variable(name='var1', initial_value=[2], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name)
    print(sess.run(var1))
    print(var2.name)
    print(sess.run(var2))

输出结果

var1:0
[1.]
var1_1:0
[2.]

代码3

import tensorflow as tf

initializer = tf.constant_initializer(value=1)
var3 = tf.get_variable(name='var3', initializer=initializer, shape=[1], dtype=tf.float32)
var4 = tf.get_variable(name='var3', initializer=initializer, shape=[1], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)
    print(sess.run(var3))
    print(var4.name)
    print(sess.run(var4))

输出结果

ValueError: Variable var3 already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:

  File "<ipython-input-2-02038677e4f2>", line 7, in <module>
    var3 = tf.get_variable(name='var3', initializer=initializer, shape=[1], dtype=tf.float32)
  File "/home/jerry/workshop/virtualenv/tensor_jupyer/local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2878, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "/home/jerry/workshop/virtualenv/tensor_jupyer/local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2818, in run_ast_nodes
    if self.run_code(code, result):

tf.name_scope() & tf.variable_scope()

那么如何使用共享变量呢,Tensorflow给出了两个作用域函数,tf.name_scope()和tf.variable_scope()函数,同样我们先看一组对比。

import tensorflow as tf
# 1
var1 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
var2 = tf.Variable(name='var1', initial_value=[2], dtype=tf.float32)
# 2
with tf.variable_scope('var_scope1'):
    var3 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
    var4 = tf.Variable(name='var1', initial_value=[2], dtype=tf.float32)
# 3    
with tf.name_scope('name_scope1'):
    var5 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
    var6 = tf.Variable(name='var1', initial_value=[2], dtype=tf.float32)
# 4
with tf.variab_scope('var_scope2'):
    var7 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
# 5
with tf.name_scope('name_scope2'):
    var8 = tf.Variable(name='var1', initial_value=[1], dtype=tf.float32)
# 6
initializer = tf.constant_initializer(value=1)
with tf.variable_scope('var_scope3', reuse=tf.AUTO_REUSE):
    var9 = tf.get_variable(name='var', initializer=initializer, shape=[1], dtype=tf.float32)
    var10 = tf.get_variable(name='var', initializer=initializer, shape=[1], dtype=tf.float32)
# 7    
with tf.name_scope('name_scope3'):
    var11 = tf.get_variable(name='var1', initializer=initializer, shape=[1], dtype=tf.float32)
    var12 = tf.get_variable(name='var', initializer=initializer, shape=[1], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name)
    print(sess.run(var1))
    print(var2.name)
    print(sess.run(var2))

    print(var3.name)
    print(sess.run(var3))
    print(var4.name)
    print(sess.run(var4))

    print(var5.name)
    print(sess.run(var5))
    print(var6.name)
    print(sess.run(var6))

    print(var7.name)
    print(sess.run(var7))
    print(var8.name)
    print(sess.run(var8))

    print(var9.name)
    print(sess.run(var9))
    print(var10.name)
    print(sess.run(var10))

    print(var11.name)
    print(sess.run(var11))
    print(var12.name)
    print(sess.run(var12))

输出结果

var1:0
[1.]
var1_1:0
[2.]

var_scope1/var1:0
[1.]
var_scope1/var1_1:0
[2.]

name_scope1/var1:0
[1.]
name_scope1/var1_1:0
[2.]

var_scope2/var1:0
[1.]

name_scope2/var1:0
[1.]

var_scope3/var:0
[1.]
var_scope3/var:0
[1.]

var1_2:0
[1.]
var:0
[1.]


关于Tensorflow的命名机制

参考文献

tensorflow 基础:tf.get_variable()和tf.Variable()的区别
tensorflow学习笔记(二十三):variable与get_variable
tensorflow学习笔记(十五): variable scope
tf.variable_scope和tf.name_scope的用法
TF Boys (TensorFlow Boys ) 养成记(三): TensorFlow 变量共享
tensorflow变量管理
tensorflow学习笔记(十七):name&variable scope
tensorflow里面name_scope, variable_scope等如何理解?