如何避免继承父variable_scope?如何让call_embd命名为Embedding/embedding_matrix?
1. 如何不继承父Variable Scope?
当然有办法!TensorFlow的variable_scope默认会继承父作用域的重用状态和名称前缀,但你可以通过两种方式打破这种继承:
使用绝对作用域名称:在作用域名称前加斜杠
/,TensorFlow会把它当作根作用域,完全不继承父作用域的任何属性。示例代码:with tf.variable_scope("parent_scope"): # 父作用域内的逻辑 with tf.variable_scope("/independent_scope"): # 这个作用域完全独立,与parent_scope无关 var = tf.get_variable("my_var", shape=[1])此时
var的名称是independent_scope/my_var:0,而非parent_scope/independent_scope/my_var:0。显式指定重用状态:创建
variable_scope时设置reuse参数(比如reuse=False),就能摆脱父作用域的重用状态继承。如果连名称前缀都不想继承,还是用第一种绝对作用域的方式更直接。示例:with tf.variable_scope("parent_scope"): with tf.variable_scope("child_scope", reuse=False): # 子作用域不继承父作用域的重用状态 new_var = tf.get_variable("new_var", shape=[2])
2. 在新作用域内重用embedding_matrix并让call_embd拥有Embedding/embedding_matrix名称?
假设你的embedding_matrix是在Embedding作用域下创建的,比如:
with tf.variable_scope("Embedding"): embedding_matrix = tf.get_variable("embedding_matrix", shape=[1000, 128])
这里提供两种实用方法实现你的需求:
方法一:通过张量名称直接获取
直接用tf.get_tensor_by_name()定位已有的张量,call_embd会直接复用原张量,名称自然就是Embedding/embedding_matrix:0(注意要加:0后缀,这是TensorFlow张量的默认输出索引):
def get_call_embd(): call_embd = tf.get_tensor_by_name("Embedding/embedding_matrix:0") return call_embd
这种方式无需额外作用域管理,简单直接。
方法二:通过作用域重用机制获取
进入Embedding作用域并设置reuse=True,用tf.get_variable()获取已创建的变量:
def get_call_embd(): with tf.variable_scope("Embedding", reuse=True): call_embd = tf.get_variable("embedding_matrix") return call_embd
这种方式更贴合TensorFlow的作用域管理逻辑,能清晰表达你是在重用该作用域下的变量,call_embd的名称同样是Embedding/embedding_matrix:0。
注意:如果
embedding_matrix是普通张量(不是通过tf.get_variable()创建的变量),方法一依然适用,但方法二无法生效——因为tf.get_variable()只能获取通过它创建的变量。
内容的提问来源于stack exchange,提问作者Yanghoon

