Tensorflow 1.11.0 在尝试使用 scope.reusevariables() 重用 cudnnGRU 变量时抛出错误
Tensorflow 1.11.0 throws an error when trying to reuse cudnnGRU variables with scope.reusevariables()
我正在通过使用 tf.contrib.cudnn_rnn.CudnnGRU()
作为编码器来实现编码器-解码器 rnn,我发现了一个问题:
我想重用这些变量,这样我就可以创建相同的模型,但将它与其他数据一起使用,简单来说,这就是重现我的问题的代码:
tf.reset_default_graph()
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
with tf.variable_scope('model') as scope:
model_1 = create_model()
rnn_out_1, rnn_state_1 = model_1(x)
scope.reuse_variables()
model_2 = create_model()
rnn_out_2, rnn_state_2 = model_2(x)
这将引发以下错误:
Variable model/cudnn_gru_1/opaque_kernel does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
所以第二个模型试图找到 model/cudnn_gru_1/opaque_kernel
变量但找不到它,因为它应该寻找 model/cudnn_gru/opaque_kernel:0
.
问题是我不知道为什么会这样,因为按照 Variables tensorflow 参考似乎没问题。另一方面,我也尝试以不同的方式编写它,因为 tensorflow 文档指出我上面的实现和我接下来展示的实现实际上是一样的:
tf.reset_default_graph()
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
with tf.variable_scope('model'):
model_1 = create_model()
rnn_out_1, rnn_state_1 = model_1(x)
with tf.variable_scope('model', reuse=True):
model_2 = create_model()
rnn_out_2, rnn_state_2 = model_2(x)
第二种方法确实有效(或者至少我认为是有效的)。所以我真的不知道我在第一个实现中做错了什么,我也不确定两个实现是否应该做同样的事情(我认为他们应该这样做)。
那么有谁能帮我弄清楚我做错了什么或我无法正确理解的事情吗?
提前致谢
CudnnGRU 看起来像 keras 风格的模型对象。所以你应该重用这个对象来在层之间共享参数,比如
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
model = create_model()
rnn_out_1, rnn_state_1 = model(x)
rnn_out_2, rnn_state_2 = model(x)
不知道为什么只有第二种方式运行正确。
编辑
我发现 CudnnGRU 在其当前变量范围内为其变量创建唯一的变量名。
第一种方式model_2创建一个像cudnn_gru_1这样的新名称,使其名称独一无二。另一方面,在第二种方式中,您创建了一个新的变量范围,因此 model_2 的唯一变量名称与 model_1.
的唯一变量名称相匹配
您可以在Layer._set_scope() (tensorflow\python\layers\base.py#L150) 中找到为什么CudnnGRU 使变量名称唯一。 Layer class 使用 default_name 参数为其变量创建一个新的变量范围(在这种情况下范围是 None),因此它的名称变得唯一。
我正在通过使用 tf.contrib.cudnn_rnn.CudnnGRU()
作为编码器来实现编码器-解码器 rnn,我发现了一个问题:
我想重用这些变量,这样我就可以创建相同的模型,但将它与其他数据一起使用,简单来说,这就是重现我的问题的代码:
tf.reset_default_graph()
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
with tf.variable_scope('model') as scope:
model_1 = create_model()
rnn_out_1, rnn_state_1 = model_1(x)
scope.reuse_variables()
model_2 = create_model()
rnn_out_2, rnn_state_2 = model_2(x)
这将引发以下错误:
Variable model/cudnn_gru_1/opaque_kernel does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
所以第二个模型试图找到 model/cudnn_gru_1/opaque_kernel
变量但找不到它,因为它应该寻找 model/cudnn_gru/opaque_kernel:0
.
问题是我不知道为什么会这样,因为按照 Variables tensorflow 参考似乎没问题。另一方面,我也尝试以不同的方式编写它,因为 tensorflow 文档指出我上面的实现和我接下来展示的实现实际上是一样的:
tf.reset_default_graph()
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
with tf.variable_scope('model'):
model_1 = create_model()
rnn_out_1, rnn_state_1 = model_1(x)
with tf.variable_scope('model', reuse=True):
model_2 = create_model()
rnn_out_2, rnn_state_2 = model_2(x)
第二种方法确实有效(或者至少我认为是有效的)。所以我真的不知道我在第一个实现中做错了什么,我也不确定两个实现是否应该做同样的事情(我认为他们应该这样做)。 那么有谁能帮我弄清楚我做错了什么或我无法正确理解的事情吗?
提前致谢
CudnnGRU 看起来像 keras 风格的模型对象。所以你应该重用这个对象来在层之间共享参数,比如
def create_model():
return tf.contrib.cudnn_rnn.CudnnGRU(num_layers=1, num_units=100,
direction='unidirectional')
# (time, batch_size, num_inputs)
x = tf.random_normal((100, 16, 100))
model = create_model()
rnn_out_1, rnn_state_1 = model(x)
rnn_out_2, rnn_state_2 = model(x)
不知道为什么只有第二种方式运行正确。
编辑
我发现 CudnnGRU 在其当前变量范围内为其变量创建唯一的变量名。
第一种方式model_2创建一个像cudnn_gru_1这样的新名称,使其名称独一无二。另一方面,在第二种方式中,您创建了一个新的变量范围,因此 model_2 的唯一变量名称与 model_1.
的唯一变量名称相匹配您可以在Layer._set_scope() (tensorflow\python\layers\base.py#L150) 中找到为什么CudnnGRU 使变量名称唯一。 Layer class 使用 default_name 参数为其变量创建一个新的变量范围(在这种情况下范围是 None),因此它的名称变得唯一。