隐藏单元在PyTorch中的seq2seq模型中饱和

时间:2017-10-20 07:55:36

标签: lstm recurrent-neural-network pytorch

我正在尝试在PyTorch中编写一个非常简单的机器翻译玩具示例。简单来说,我将机器翻译任务转变为这个:

  

给定随机序列([4, 8, 9 ...]),预测其元素的元素加1([5, 9, 10, ...])的序列。对象:0, 1, 2将分别用作pad, bos, eos

我在我的机器翻译任务中发现了这个玩具任务中的同样问题。为了调试,我使用非常小的数据大小n_data = 50,并发现模型甚至过度拟合这些数据。查看模型,我发现encoder/decoder 很快的隐藏状态变得饱和,即隐藏状态下的所有单位变得非常接近{ {1}}由于1/-1

tanh

此外,无论我如何调整学习速率,或将单位切换到RNN / LSTM / GRU单位,即使使用-0.8987 0.9634 0.9993 ... -0.8930 -0.4822 -0.9960 -0.9673 1.0000 -0.8007 ... 0.9929 -0.9992 0.9990 -0.9457 0.9290 -0.9260 ... -0.9932 0.9851 0.9980 ... ⋱ ... -0.9995 0.9997 -0.9350 ... -0.9820 -0.9942 -0.9913 -0.9951 0.9488 -0.8894 ... -0.9842 -0.9895 -0.9116 -0.9991 0.9769 -0.5871 ... 0.7557 0.9049 0.9881 测试样本,损失值似乎也很低。随着更多的数据,模型似乎根本不会收敛。

50

当我使用step: 0, loss: 2.313938 step: 10, loss: 1.435780 step: 20, loss: 0.779704 step: 30, loss: 0.395590 step: 40, loss: 0.281261 ... step: 480, loss: 0.231419 step: 490, loss: 0.231410 时,我可以轻松地使用seq2seq模型来填充这样的数据集,并且具有非常小的损失值。

以下是我尝试过的内容:

  1. 手动将嵌入初始化为非常小的数字;
  2. 将渐变剪裁为固定范数,如1e-2,2,3,5,10;
  3. 在计算损失时排除填充索引(通过将tensorflow添加到ignore_index)。
  4. 我所尝试的所有内容都没有帮助解决问题。

    我怎样摆脱这个?任何帮助将不胜感激。

    以下是代码,为了更好的阅读体验,它位于gist

    NLLLoss

1 个答案:

答案 0 :(得分:0)

我认为你不是在tanh的范围内操作,它会提供合理的输出,因为你的输入非常大/小,因此导致1 / -1值。例如,tanh(5)= 0.999,tanh(-5)= - 0.999。尝试将tanh可以处理的范围内的数据标准化,而不会进入极端(例如在+1到-1之间)。如果激活函数是sigmoid,最好将数据标准化为0到1之间。

Tanh