pytorch 中 num_layers = 2 的 1 个 LSTM 和 2 个 LSTM 之间的区别

Posted

技术标签:

【中文标题】pytorch 中 num_layers = 2 的 1 个 LSTM 和 2 个 LSTM 之间的区别【英文标题】:Difference between 1 LSTM with num_layers = 2 and 2 LSTMs in pytorch 【发布时间】:2018-08-19 20:01:54 【问题描述】:

我是深度学习的新手,目前正在使用 LSTM 进行语言建模。我正在查看 pytorch 文档并被它弄糊涂了。

如果我创建一个

nn.LSTM(input_size, hidden_size, num_layers) 

其中 hidden_​​size = 4 和 num_layers = 2,我想我会有这样的架构:

op0    op1 ....
LSTM -> LSTM -> h3
LSTM -> LSTM -> h2
LSTM -> LSTM -> h1
LSTM -> LSTM -> h0
x0     x1 .....

如果我这样做

nn.LSTM(input_size, hidden_size, 1)
nn.LSTM(input_size, hidden_size, 1)

我认为网络架构与上面的完全一样。我错了吗?如果是,这两者有什么区别?

【问题讨论】:

【参考方案1】:

多层 LSTM 更好地称为堆叠 LSTM,其中多层 LSTM 相互堆叠。

你的理解是正确的。以下两种堆叠 LSTM 的定义相同。

nn.LSTM(input_size, hidden_size, 2)

nn.Sequential(OrderedDict([
    ('LSTM1', nn.LSTM(input_size, hidden_size, 1),
    ('LSTM2', nn.LSTM(hidden_size, hidden_size, 1)
]))

在这里,输入被馈送到 LSTM 的最低层,然后最低层的输出被转发到下一层,依此类推。请注意,最低 LSTM 层的输出大小和 LSTM 层的其余输入大小为hidden_size

但是,您可能已经看到人们通过以下方式定义堆叠 LSTM:

rnns = nn.ModuleList()
for i in range(nlayers):
    input_size = input_size if i == 0 else hidden_size
    rnns.append(nn.LSTM(input_size, hidden_size, 1))

人们有时使用上述方法的原因是,如果您使用前两种方法创建堆叠 LSTM,则无法获得每个单独层的隐藏状态。查看 LSTM 在 PyTorch 中返回的内容。

因此,如果您想拥有中间层的隐藏状态,则必须将每个单独的 LSTM 层声明为单个 LSTM,并通过循环来模拟多层 LSTM 操作。例如:

outputs = []
for i in range(nlayers):
    if i != 0:
        sent_variable = F.dropout(sent_variable, p=0.2, training=True)
    output, hidden = rnns[i](sent_variable)
    outputs.append(output)
    sent_variable = output

最后,outputs 将包含每个 LSTM 层的所有隐藏状态。

【讨论】:

感谢您的澄清。您知道每种方法的优缺点是什么吗? @user3828311 你能在这个主题上发布另一个关于 SO 的问题吗?那我可以回答了。 只是想知道你能否澄清outputs这个词?它是否也包括单元状态或只是隐藏状态? 为了澄清,“最底层的输出被转发到下一层,依此类推”,这实际上意味着取上一层的隐藏状态(乘以dropout)下一层的输入,参考官方文档。

以上是关于pytorch 中 num_layers = 2 的 1 个 LSTM 和 2 个 LSTM 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

python - 如何在pytorch上实现stacked rnn (num layers > 1)?

PyTorch-LSTM

将 GRU 层从 PyTorch 转换为 TensorFlow

PyTorch GRU 中隐藏状态的层顺序返回

Pytorch中LSTM和Normal RNN的一些不同之处

解码器 LSTM Pytorch 的图像字幕示例输入大小