tensorflow框架学习 (六)—— tensorflow命名空间

一、tensorflow命名空间

 

1、什么是命名空间

  命名空间可以看成是一个集合,我们可以在里面创建变量,里面存放着的变量就是它的元素。例如我们定义一个命名空间命名为space,然后定义变量V1、V2,则我们就创建了一个有变量V1、V2的命名空间。不同命名空间的变量互不影响。

 

2、命名空间的作用:

  在训练深度网络时,为了减少需要训练参数的个数(比如LSTM模型),或者是多机多卡并行化训练大数据、大模型等情况时,往往就需要共享变量。另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变量和操作,如何避免这些变量名和操作名的唯一不重复,同时维护一个条理清晰的graph非常重要。

 

3、如何创建命名空间

  利用tf.Variable_scope(name,reuse=False), tf.name_scope(name) 创建上下文处理器的方式来创建,然后可以在上下文处理器中用tf.Variable或者tf.get_variable来创建变量,如:

import tensorflow as tf

#创建命名空间并创建变量
with tf.variable_scope(name_or_scope='s1'):
    v1=tf.get_variable(name='v1',initializer=tf.ones([1,1]))

with tf.name_scope(name='s2'):
    v2=tf.Variable(tf.ones([1,1]),name='v2')

v3=tf.get_variable(name='v3',initializer=tf.ones([1,1]))

#输出变量名
print(v1.name)
print(v2.name)
print(v3.name)

  输出结果为:

s1/v1:0
s2/v2:0
v3:0

  可以发现在print在命名空间中的变量的时候会有对应的命名空间的前缀“s1/”,如果不在命名空间中则没有前缀。

4、在命名空间创建变量时的问题

 

  (一)、tf.Variable_scope(name,reuse=False)、 tf.name_scope(name) 创建的上下文管理器用tf.Variable与tf.get_variable创建变量的时候如下区别:

  1. tf.Variable_scope可以同时作用于tf.Variable与tf.get_variable,为其创建的变量归属到tf.Variable_scope指定名称的命名空间;而tf.name_scope只能作用于tf.Variable,对tf.get_variable不起作用。
  2. tf.Variable_scope(name,reuse=False)可以创建新的命名空间也可以调用之前创建的命名空间;而tf.name_scope只能创建新的命名空间,因为它之作用与tf.Variable,而tf.Variable会对命名空间的重名做处理。
import tensorflow as tf


#创建命名空间并创建变量
with tf.variable_scope(name_or_scope='s1',reuse=False):
    v1 = tf.Variable(initial_value=tf.zeros([1,1]),name='v1')
    v2 = tf.get_variable(name='v2', shape=[1,1])

with tf.name_scope(name='s2'):
    v3 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v3')
    v4=tf.get_variable(name='v4',shape=[1,1])

#用同名的命名空间创建新的变量
with tf.variable_scope(name_or_scope='s1',reuse=False):
    v5 = tf.get_variable(name='v5', shape=[1,1])
    v6 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v6')

with tf.name_scope(name='s2'):
    v7 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v7')

#输出变量名
print('不同点1:')
print('tf.variable_scope创建的命名空间s1')
print(v1.name)
print(v2.name)
print('tf.name_scope创建的命名空间s2')
print(v3.name)
print(v4.name)
print('=============================================')
print('不同点2:')
print('tf.variable_scope创建的重名命名空间s1')
print(v5.name)
print(v6.name,'     #这里是s1_1二不是s1是由于tf.Variable处理命名空间重名造成的')
print('tf.name_scope创建的重名命名空间s2')
print(v7.name)

  输出结果为:

不同点1:
tf.variable_scope创建的命名空间s1
s1/v1:0
s1/v2:0
tf.name_scope创建的命名空间s2
s2/v3:0
v4:0
=============================================
不同点2:
tf.variable_scope创建的重名命名空间s1
s1/v5:0
s1_1/v6:0      #这里是s1_1二不是s1是由于tf.Variable处理命名空间重名造成的
tf.name_scope创建的重名命名空间s2
s2_1/v7:0

 

  (二)、tf.Variable与tf.get_variable创建变量的时候如下区别:

  1. tf.Variable每次都是新建一个变量,无论是在什么情况下;而tf.get_variable当tf.Variable_scope的参数reuse=Flase时只能创建新变量,否则报错,当reuse=True的时候只能调用原来的变量,否则报错。
  2. tf.Variable创建的变量如果和之前的变量重名,会自动处理避免重名,包括命名空间重名和变量重名;而tf.get_variable创建变量不会自动处理重名,若创建新变量的时候重名会报错,原因参考上一条。
  3. 在tf.Variable_scope创建的双下文管理器中,即使tf.Variable_scope调用的是曾经创建的命名空间,tf.Variable的命名空间的前缀也会做重名处理,而tf.get_variable则会与上一次创建的命名空间前缀保持一致,这样说比较难懂,一会看代码。
import tensorflow as tf

#不同点1:
# 创建命名空间并创建变量
with tf.variable_scope(name_or_scope='s1', reuse=False):
    v1 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v1')
    v2 = tf.get_variable(name='v2', shape=[1, 1])
    try:
        v2_ = tf.get_variable(name='v2', shape=[1, 1])
    except:
        print('reuse=False,tf.get_variable创建新变量时命名不能重复')

with tf.variable_scope(name_or_scope='s1', reuse=True):
    v4 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v4')
    try:
        v_new = tf.get_variable(name='v_new', shape=[1, 1])
    except:
        print('reuse=True,tf.get_variable不能创建新变量')

print('不同点1:')
print(v1.name)
print(v2.name)
print(v4.name, '     #由于前后命名空间重名,所以tf.Variable自动处理了命名空间重名')


#不同点2与3:
# 创建命名空间并用tf.Variable创建同名变量
with tf.name_scope('s2'):
    v5 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v5')
    v5_1 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v5')

# 创建同名命名空间并用tf.Variable创建同名变量
with tf.name_scope('s2'):
    v5_2 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v5')

# 创建同名命名空间并用tf.Variable创建同名变量
with tf.name_scope('s3'):
    v5_3 = tf.Variable(initial_value=tf.zeros([1, 1]), name='v5')

print('==========================================================================')
print('不同点2与3:')
print(v5.name)
print(v5_1.name,'       #同一上下文处理器创建的同名空间同名变量只处理变量重名')
print(v5_2.name,'       #不同上下文处理器创建的同名空间同名变量只处理命名空间重名')
print(v5_3.name,'       #不同命名空间同名变量互不影响')

  输出结果:

reuse=False,tf.get_variable创建新变量时命名不能重复
reuse=True,tf.get_variable不能创建新变量
不同点1:
s1/v1:0
s1/v2:0
s1_1/v4:0      #由于前后命名空间重名,所以tf.Variable自动处理了命名空间重名
==========================================================================
不同点2:
s2/v5:0
s2/v5_1:0        #同一上下文处理器创建的同名空间同名变量只处理变量重名
s2_1/v5:0        #不同上下文处理器创建的同名空间同名变量只处理命名空间重名
s3/v5:0        #不同命名空间同名变量互不影响

 

posted @ 2019-08-13 17:12  我不是高斯分布  阅读(371)  评论(0编辑  收藏  举报