Tensorflow 1.11.0在尝试使用范围.可重用性()

2024-05-15 02:18:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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}$

第二种方法实际上是有效的(或者至少我认为是这样)。所以我真的不知道在第一个实现中我做错了什么,我也不确定两个实现是否应该做相同的事情(我认为他们应该这样做)。 那么,有没有人能帮我弄清楚我做错了什么或者我不能正确理解的事情吗?在

提前谢谢


Tags: 模型modeltfcreatewith编码器contribkernel
1条回答
网友
1楼 · 发布于 2024-05-15 02:18:40

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使用一个新名称,比如cudn_gru__1,使其名称独一无二。另一方面,在第二种方法中,您创建了一个新的变量范围,因此模型2的唯一变量名与模型1的唯一变量名匹配。在

您可以找到为什么CudnnGRU在Layer中使用唯一的变量名。\u set_scope()(tensorflow\python\layers\底座py#L150). Layer类使用默认的\u name参数为其变量创建一个新的变量范围(在本例中scope为None),因此它的名称变得唯一。在

相关问题 更多 >

    热门问题