Seq2Seq模型学习几次迭代后仅输出EOS令牌(<\ s>)

noe*_*oel 5 python lstm tensorflow recurrent-neural-network seq2seq

我正在使用NMT创建在康奈尔电影对话语料库上受过训练的聊天机器人。

我的代码部分来自https://github.com/bshao001/ChatLearnerhttps://github.com/chiphuyen/stanford-tensorflow-tutorials/tree/master/assignments/chatbot

在训练过程中,我打印了从批处理中馈送到解码器的随机输出答案,以及我的模型预测观察到学习进度的相应答案。

我的问题:仅经过约4次训练,该模型就学会了在<\s>每个时间步输出EOS令牌()。即使训练继续进行,它也始终将其输出作为其响应(由logits的argmax确定)。该模型偶尔会偶尔输出一系列周期作为其答案。

我还在训练过程中打印了前10个logit值(不仅是argmax),以查看其中是否存在正确的单词,但这似乎是在预测词汇中最常见的单词(例如i,you,?,。 )。在培训期间,即使是前10个字词也没有太大变化。

我已经确保正确计算编码器和解码器的输入序列长度,并相应地添加了SOS(<s>)和EOS(也用于填充)令牌。我还在损失计算中执行屏蔽

这是一个示例输出:

训练迭代1:

Decoder Input: <s> sure . sure . <\s> <\s> <\s> <\s> <\s> <\s> <\s> 
<\s> <\s>
Predicted Answer: wildlife bakery mentality mentality administration 
administration winston winston winston magazines magazines magazines 
magazines
Run Code Online (Sandbox Code Playgroud)

...

训练迭代4:

Decoder Input: <s> i guess i had it coming . let us call it settled . 
<\s> <\s> <\s> <\s> <\s>
Predicted Answer: <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> 
<\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s>
Run Code Online (Sandbox Code Playgroud)


再经过几次迭代后,它只依靠预测EOS(很少出现周期)

我不确定是什么原因导致了此问题,并且已经在此问题上停留了一段时间。任何帮助将不胜感激!

更新:我让它训练了十万次迭代,但它仍然仅输出EOS(偶尔出现)。经过几次迭代后,训练损失也不会减少(从一开始就保持在47左右)

Hao*_*ung 0

最近我也在研究seq2seq模型。我以前遇到过你的问题,就我而言,我通过更改损失函数来解决它。

你说你用面膜,所以我猜你tf.contrib.seq2seq.sequence_loss和我一样用的。

我改为tf.nn.softmax_cross_entropy_with_logits,并且它可以正常工作(并且计算成本更高)。

(编辑 05/10/2018。请原谅,我需要编辑,因为我发现我的代码中有一个严重的错误)

tf.contrib.seq2seq.sequence_losslogits 如果 , ,的形状正确的话targets,可以很好地工作。mask正如官方文档中定义的: tf.contrib.seq2seq.sequence_loss

loss=tf.contrib.seq2seq.sequence_loss(logits=decoder_logits,
                                      targets=decoder_targets,
                                      weights=masks) 

#logits:  [batch_size, sequence_length, num_decoder_symbols]  
#targets: [batch_size, sequence_length] 
#weights: [batch_size, sequence_length] 
Run Code Online (Sandbox Code Playgroud)

嗯,即使形状不符合,它仍然可以工作。但结果可能很奇怪(很多#EOS #PAD...等)。

由于decoder_outputs、 和decoder_targets可能具有所需的相同形状(在我的例子中, mydecoder_targets具有形状[sequence_length, batch_size])。所以尝试使用tf.transpose来帮助你重塑张量。