我使用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
。在
问题是我不知道为什么会发生这种情况,因为通过遵循变量tensorflow引用,似乎没问题。另一方面,我也试着用不同的方式来写它,因为tensorflow doc声明我上面的实现和我接下来展示的实现实际上是一样的:
^{pr2}$第二种方法实际上是有效的(或者至少我认为是这样)。所以我真的不知道在第一个实现中我做错了什么,我也不确定两个实现是否应该做相同的事情(我认为他们应该这样做)。 那么,有没有人能帮我弄清楚我做错了什么或者我不能正确理解的事情吗?在
提前谢谢
CudnnGRU看起来像keras风格的模型对象。所以你应该重用这个对象在层之间共享参数,比如
我不知道为什么只有第二条路是正确的。在
编辑
我发现CudnnGRU在其当前变量范围内为其变量指定唯一的变量名。在
第一种方法是model_2使用一个新名称,比如cudn_gru__1,使其名称独一无二。另一方面,在第二种方法中,您创建了一个新的变量范围,因此模型2的唯一变量名与模型1的唯一变量名匹配。在
您可以找到为什么CudnnGRU在Layer中使用唯一的变量名。\u set_scope()(tensorflow\python\layers\底座py#L150). Layer类使用默认的\u name参数为其变量创建一个新的变量范围(在本例中scope为None),因此它的名称变得唯一。在
相关问题 更多 >
编程相关推荐