命名机制与变量共享
Variable 变量 (一般表达参数)、Tensor(操 作输出)、操作 Operation、Placeholder 输 入都有名字
当模型复杂的时候,需要有效的命名机制: 方便、清晰
TF 中的命名机制
有效的命名机制:
起名方便 (不用从 w1 起到 w1024…)
甚至不显式写名,也能自动给个好找的名字 3. 同时避免重名带来的名字冲突
TF 采用 scope, 一种层级的命名管理机制:例:vgg16/conv1/w:0
用一级级的 scope 名字空间来管理变量
可以不用显示起名,TF 会按规则自动起名
两种 scope:tf.name_scope, tf.variable_scope 用于给名字一级一级 指定管理空间,例如:
with tf.name_scope('name_sp1') as scp1:
with tf.variable_scope('var_scp2') as scp2:
with tf.name_scope('name_scp3') as scp3:
a = tf.Variable(1, name='a') #name_sp1/var_scp2/name_scp3/a:0
tf.name_scope, tf.variable_scope 主要对 tf.get_variable 创建的变
量管理有区别,主要涉及变量重用
tf.name_scope, tf.variable_scope 管理方式的异同
对 Tensor 或 tf.Variable 创建的变量,tf.name_scope, tf.variable_scope 管理基本相同,一层层加前缀;无视 python 自带 name_scope 限制; 无视 variable_scope 的 reuse
Tensor,tf.Variable 不起名,TF 用操作名起名 (Variable,Add …+value_index (:0,:1…):tensor 第几个输出); 起重名,TF 会改为 不一样的 name(_1,_2…); 对应的 Op, 没有 value_index
with tf.name_scope('name_sp1') as scp1:
with tf.variable_scope('var_scp2') as scp2:
with tf.name_scope('name_scp3') as scp3:
a = tf.Variable(1, name='a')
print(a) #name_sp1/var_scp2/name_scp3/a:0
a1 = tf.Variable(1, name='a')
print(a1) #name_sp1/var_scp2/name_scp3/a_1:0
b=tf.Variable(1)
print(b) #name_sp1/var_scp2/name_scp3/Variable:0
c=tf.Variable(1)
print(c) #name_sp1/var_scp2/name_scp3/Variable_1:0
a_b=tf.add(a,b)
print(a_b) #name_sp1/var_scp2/name_scp3/Add:0
a_c=tf.add(a,c)
print(a_c) #name_sp1/var_scp2/name_scp3/Add_1:0
tf.name_scope, tf.variable_scope 的异,主要针对对 tf.get_variable 创建变量
tf.variable_scope 主要是配合 tf.get_variable 进行变量重用 (共享)
variable 两种创建方式:tf.Variable, tf.get_variable
设计目的不同, 创建方式不同:一个主要用于新创建,一个主要用 于重用
a=tf.Variable(initial_value=[4.], name=’var4’, dtype=tf.float32)
b=tf.get_variable(name=’var3’, shape=[1], dtype=tf.float32, initializer=initializer)
tf.Variable:initial_value(直接数值或初始化值函数) 必显式初始化; tf.get_variable:initializer(初始化算子 xxx_initilizer) 可选
创建新变量:tf.Variable:name 可重 (TF 自动别名);tf.get_variable: name 不能重
tf.get_variable:无视 name_scope, 只看 variable_scope
with tf.name_scope('name_sp1') as scp1:
with tf.variable_scope('var_scp2') as scp2:
with tf.name_scope('name_scp3') as scp3:
a = tf.Variable(1, name='a')
b = tf.get_variable('b',[1])
等同于
with tf.name_scope('name_sp1') as scp1:
with tf.variable_scope('var_scp2') as scp2:
with tf.name_scope('name_scp3') as scp3:
a = tf.Variable(1, name='a')
with tf.variable_scope('var_scp2') as scp2:
b = tf.get_variable('b',[1])
tf.get_variable 变量重用看 variable_scope 的 reuse 属性,false 则 创建新变量,name 不能重
reuse 下,tf.get_variable:根据 name 值,返回该变量,如果该name 不存在的话,则进行创建。
get_variable 重用变量需要看 variable_scope 的 reuse 属性
with tf.variable_scope('scp',reuse=True) as scp:
a = tf.get_variable('a',[1]) #报 错
reuse=True, 强制共享, 不存在共享变量,所以报错
with tf.variable_scope('scp',reuse=False) as scp:
a = tf.get_variable('a',[1])
a = tf.get_variable('a') # 报错
reuse=False, 强制创建, 已存在同名变量,报错慎用 tf.AUTOREUSE, 如果明确知道下面的变量是要重用的
with tf.variable_scope('scp',reuse=True) as scp:
a = tf.get_variable('a')
a = tf.get_variable('a') #a只 在 这 里 创 建 报 错
get_variable 第一次创建,要至少给 shape
variable_scope 的 reuse 属性另一种设置方法:
variable_scope 的 reuse 属性也可通过 scope.reuse_variable 在名字
空间内设置
import tensorflow as tf
with tf.variable_scope('foo') as scp:
aaa = tf.get_variable('aaa',[1]) bbb = tf.get_variable('bbb',[1])
scope.reuse_variable()
ccc = tf.get_variable('aaa')
print (aaa.name) #foo/aaa:0
print (bbb.name) #foo/bbb:0 print (ccc.name) #foo/aaa:0