在tensorflow中用光束搜索实现注意

在tensorflow中用光束搜索实现注意,tensorflow,Tensorflow,我已经编写了自己的代码,参考了精彩的教程,根据我在课堂注意力模型中的理解,在使用注意力和光束搜索时,我无法获得结果。假设这样的话,_build_decoder_cell函数为推理模式创建单独的解码单元和注意力包装器(我认为这是不正确的,无法找到解决办法) 当我在训练后调用beam\u sample\u id时,我没有得到正确的结果 我的猜测是,我们应该使用相同的注意力包装器,但这是不可能的,因为我们必须使用tile_序列来进行波束搜索 如有任何见解/建议,将不胜感激 我还在他们的主存储库中为此创

我已经编写了自己的代码,参考了精彩的教程,根据我在课堂注意力模型中的理解,在使用注意力和光束搜索时,我无法获得结果。假设这样的话,_build_decoder_cell函数为推理模式创建单独的解码单元和注意力包装器(我认为这是不正确的,无法找到解决办法)

当我在训练后调用beam\u sample\u id时,我没有得到正确的结果

我的猜测是,我们应该使用相同的注意力包装器,但这是不可能的,因为我们必须使用tile_序列来进行波束搜索

如有任何见解/建议,将不胜感激


我还在他们的主存储库中为此创建了一个问题

我不确定你说的“我无法获得结果”是什么意思,但我假设你的模型没有利用在培训期间学到的知识

如果是这样的话,那么首先你需要知道它是关于变量共享的,你需要做的第一件事是去掉训练和推断之间不同的变量范围,相反,你需要使用一些东西,比如

移除

with tf.name_scope("Training"):
with tf.name_scope("Inference"):
和使用:

with tf.variable_scope("myScope"):
然后取下

with tf.name_scope("Training"):
with tf.name_scope("Inference"):
并改用

with tf.variable_scope("myScope" , reuse=True):
同样在你的
开头和之后使用tf.variable\u scope(“myScope”)

这将确保您的推理变量和训练变量具有相同的签名并共享

当我遵循你提到的同一个教程时,我已经测试了这一点,在我写这篇文章时,我的模型仍在训练中,但我可以看到,随着我们的讨论,精确度在提高,这表明解决方案也应该适用于你

谢谢

您可以使用
tf.cond()
在训练和推理阶段之间创建不同的路径:

def get_tile_batch(enc_output, source_sequence_length, enc_state, useBeamSearch):
    enc_output = tf.contrib.seq2seq.tile_batch(enc_output, multiplier=useBeamSearch)
    source_sequence_length = tf.contrib.seq2seq.tile_batch(source_sequence_length, multiplier=useBeamSearch)
    enc_state = tf.contrib.seq2seq.tile_batch(enc_state, multiplier=useBeamSearch)
    return enc_output, source_sequence_length, enc_state

## for beam search: at training stage, use tile_batch multiplier = 1,
## at infer stage, use tile_batch multiplier = useBeamSearch
## tile_batch is just duplicate every sample in a batch,
## so it'll change batch_size to batch_size * useBeamSearch at runtime once batch_size was determined
enc_output, source_sequence_length, enc_state = tf.cond(
    self.on_infer, # is inference stage?
    lambda: get_tile_batch(enc_output, source_sequence_length, enc_state, useBeamSearch=useBeamSearch),
    lambda: get_tile_batch(enc_output, source_sequence_length, enc_state, useBeamSearch=1)
)

# attention mechanism
attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(num_units=rnn_size, memory=enc_output, memory_sequence_length=source_sequence_length)
dec_cell = tf.contrib.seq2seq.AttentionWrapper(dec_cell, attention_mechanism)
## for beam search: change batch_size to batch_size * useBeamSearch at infer stage
decoder_initial_state = tf.cond(
    self.on_infer, # is inference stage?
    lambda: dec_cell.zero_state(batch_size=batch_size * useBeamSearch, dtype=tf.float32),
    lambda: dec_cell.zero_state(batch_size=batch_size * 1, dtype=tf.float32)
)
enc_state = decoder_initial_state.clone(cell_state=enc_state)

是的,我无法使用在训练过程中学习到的权重用于我的方法。tf.name_scope()在版本1.3中没有参数“reuse”,您的意思必须是tf.variable_scope()。我通过创建两个单独的图形进行训练和推理来解决此方法,在@dnnavn在中指向我后,他声称只有通过单独的图形才能实现,我需要尝试。同时,如果您成功尝试,请发表评论。再次感谢,我可以看到您已将此答案标记为correct,你有没有改变在你的数据上测试它?