命名机制与变量共享

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