我正在编写基于NMT教程代码的Seq2Seq代码。(https://github.com/tensorflow/nmt)
我已经将解码器的输出投影仪修改为完全连接的图层,而不仅仅是教程代码中的线性投影仪。 通过定义以下自定义Layer类:
customlayer.pyhttps://github.com/kami93/ntptest/blob/master/customlayer.py
然后像这样初始化自定义图层:
with tf.variable_scope("decoder/output_layer"):
output_layer = customlayer.FCLayers(
[256]*2 + [757],
activation = tf.nn.relu,
is_decoder_output=True,
residual=True,
kernel_initializer=initializer,
trainable=True)
然后将该层作为BeamSearchDecoder的output_layer,就像这样
my_decoder = tf.contrib.seq2seq.BeamSearchDecoder(
cell=cell,
embedding=embedding_decoder,
start_tokens=start_tokens,
end_token=end_token,
initial_state=decoder_initial_state,
beam_width=beam_width,
output_layer=output_layer)
最后得到像这样的输出sample_id
outputs, final_context_state, _ = tf.contrib.seq2seq.dynamic_decode(
my_decoder,
maximum_iterations=maximum_iterations,
output_time_major=time_major,
swap_memory=True,
scope=decoder_scope)
sample_id = outputs.predicted_ids
问题出在这里。
因为我的自定义图层的最后一个输出维度是&#34; 757&#34;,我希望sample_id应该是自定义图层输出的argmax id的索引,它应该在[0,756]之间。< / p>
但是,返回的实际sample_id介于[1,757]之间(即&#34;我的预期sample_id + 1&#34;将被返回)。
在https://github.com/tensorflow/tensorflow/blob/r1.5/tensorflow/contrib/seq2seq/python/ops/beam_search_decoder.py检查tf.contrib.seq2seq.BeamSearchDecoder的实际代码 ... 有&#34; _beam_search_step&#34;的实施在&#34; 510和#34;之间的界限上和&#34;第652行&#34;,
在第545行,vacab_size收集为757。
vocab_size = logits.shape[-1].value or array_ops.shape(logits)[-1]
在第577行,在所有嵌套的&#34; K * 757&#34;中确定具有顶部K(波束宽度)softmax概率的指数。假设
next_beam_scores, word_indices = nn_ops.top_k(scores_flat, k=next_beam_size)
在第595行,实际指数由模运算计算。
raw_next_word_ids = math_ops.mod(word_indices, vocab_size,
name="next_beam_word_ids")
next_word_ids = math_ops.to_int32(raw_next_word_ids)
因此,我认为[1,757]之间的索引应该作为sample_id返回,这一点毫无意义。至少由于757的模运算,它严格返回[0,756]之间的值,我认为永远不应该返回757的sample_id。但我实际上是在接受它。
有人可以建议我为什么要获取[1,757]的样本ID,而不是[0,756]?