我目前正在训练一个LSTM RNN用于时间序列预测。我了解到,当RNN的梯度超过某个阈值时,通常会进行梯度裁剪。然而,我不太确定这是否包括输出层。
如果我们称RNN的隐藏层为h,那么输出就是sigmoid(connected_weights*h + bias)。我知道用于确定隐藏层的权重的梯度会被裁剪,但输出层的梯度是否也一样呢?
换句话说,connected_weights的梯度在梯度裁剪中是否也被裁剪?
回答:
虽然没有什么阻止你也对它们进行裁剪,但实际上没有理由这样做。有一篇很好的论文解释了原因,在这里,我会尽量给你一个概述。
我们通过梯度裁剪试图解决的问题是梯度爆炸:假设你的RNN层是这样计算的:
h_t = sigmoid(U * x + W * h_tm1 + b)
暂时忽略非线性部分,你可以说当前状态h_t
依赖于早期状态h_{t-T}
,如h_t = W^T * h_tmT + input
。所以如果矩阵W
放大了隐藏状态,那么那个旧的隐藏状态的影响会随着时间呈指数增长。同样,当你反向传播梯度时,也会发生这种情况,导致梯度很可能会将你带到参数空间中的某个无用点。
另一方面,输出层在前向和后向传递中只应用一次,因此虽然它可能使学习变得复杂,但只会增加一个“常数”因子,与时间上的展开无关。
更技术性地说:决定你是否会遇到梯度爆炸的关键量是W
的最大特征值。如果它大于1(或小于-1,那真是有趣:-)),那么你就会遇到梯度爆炸。相反,如果它小于1,你会遭受梯度消失,使学习长期依赖变得困难。你可以在这里找到对这些现象的很好的讨论,并指向经典文献。
如果我们把sigmoid重新考虑进来,得到梯度爆炸变得更加困难,因为在通过它反向传播时,梯度至少会被4的因子所抑制。但如果你有一个大于4的特征值,你还是会有冒险:-) 仔细初始化是相当重要的,第二篇论文提供了一些提示。使用tanh
,在零附近几乎没有抑制,而ReLU只是将梯度传播,因此这些更容易发生梯度爆炸,因此对初始化和梯度裁剪敏感。
总的来说,LSTM比普通RNN有更好的学习特性,尤其是在处理梯度消失方面。尽管根据我的经验,梯度裁剪通常也是必要的。
编辑:何时裁剪?就在权重更新之前,即你进行不变的反向传播。问题是梯度裁剪有点像肮脏的hack。你仍然希望你的梯度尽可能精确,所以你最好不要在反向传播中间扭曲它。只是当你看到梯度变得非常大时,你会说嗯,这闻起来不对。我最好迈出一小步。裁剪是一种简单的方法来做到这一点(可能只有梯度的一些元素爆炸,而其他元素仍然表现良好且有信息)。对于大多数工具包来说,你无论如何都没有选择,因为反向传播是原子性发生的。