我有一个更理论性的问题,我没能找到答案。假设我的输入是一组数字列表:
input = [0,5,0,4,3,3,2,1]
假设第一层隐藏层由3个LSTM节点组成。现在这个列表是如何呈现给LSTM的(时间步长为8)?
我的第一个想法是:
输入时间步长1:节点1 = 0, 节点2 = 0, 节点3 = 0输入时间步长2:节点1 = 5, 节点2 = 5, 节点3 = 5...
所以每个节点在每个时间步长看到相同的输入。
我的第二个想法是:
输入时间步长1:节点1 = 0, 节点2 = 5, 节点3 = 0输入时间步长2:节点1 = 5, 节点2 = 0, 节点3 = 4...输入时间步长8:节点1 = 1, 节点2 = -, 节点3 = -
在每个时间步长,每个节点得到不同的输入,输入就像一个滑动窗口,从左到右移动通过列表。在这种情况下,列表中的每个元素(每个数字)被不等次数地呈现给LSTM。
我的最后一个想法是:
输入时间步长1:节点1 = 0, 节点2 = 5, 节点3 = 0下一个时间步长:节点1 = 4, 节点2 = 3, 节点3 = 3最后时间步长:节点1 = 2, 节点2 = 1, 节点3 = -
所以再次每个节点得到不同的输入,但这次窗口不是滑动通过列表,而是跳跃。在这种情况下,每个数字只被呈现给LSTM一次。
我猜第一个想法是正确的,但我不确定。或者完全不同?
回答:
RNN通常用于识别序列数据中的模式,即必须按顺序将序列输入到单元中才能捕捉到它。你的第一个想法并没有按顺序输入序列,因此网络无法识别任何有意义的信息,例如“下一个符号很可能比当前符号小,除非有一个0”。
在大多数情况下,输入看起来像这样:
… 其中 (x[0], x[1], ...)
是输入。
你的第二个和第三个想法的区别仅在于你如何将长数据分割成子序列,实际上这两种选项都是可能的,具体取决于数据的性质:
-
当
[0,5,0,4,3,3,2,1]
是一个大的句子时,你希望从它的所有部分捕捉规则。为此,你会将所有长度为3的子序列输入到网络中,因为任何三元组都可能是重要的。(附注:还有一种有状态RNN的变体来帮助处理这个问题,但这真的是一个技术细节) -
当
[0,5,0]
、[4,3,3]
和[2,1]
是不同的句子时,学习像[0,4,3]
这样的依赖关系没有意义,其中一个序列以前一个句子的最后一个词开始。每个句子可能是独立的,但在句子内你希望滑动通过所有大小为3的窗口。(附注:在这种情况下,有状态RNN也可能有用,例如当有一个故事时,前一个句子的含义可能会影响对当前句子的理解)。
所以最后两个猜测非常接近正确。
图片来自这篇文章,我强烈推荐阅读。