首页 > 解决方案 > Pytorch:Dropout 层和打包序列

问题描述

(PyTorch 0.4.0)

如何将手动 dropout 层应用于打包序列(特别是在 GPU 上的 LSTM 中)?直接传递打包序列(来自 lstm 层)是行不通的,因为 dropout 层不知道如何处理它并返回一些不是打包序列的东西。传递打包序列的数据似乎应该可以工作,但会导致代码示例下方显示的属性错误。

    def __init__ (self, ....):
        super(Model1, self).__init__()
        ....
        self.drop = torch.nn.Dropout(p=0.5, inplace=False)

    def forward(self, inputs, lengths):
        pack1 = nn.utils.rnn.pack_padded_sequence(inputs, lengths, batch_first=True)
        out1, self.hidden1 = self.lstm1(pack1, (self.hidden1[0].detach(), self.hidden1[1].detach()))
        out1.data = self.drop(out1.data)

这导致:

 AttributeError: can't set attribute

反常地,我可以使它成为一个就地操作(同样,直接在数据上,而不是完整的打包序列),它在技术上可以在 CPU 上工作(即,它运行),但在 GPU 上发出警告,就地操作正在修改一个需要的梯度。这让我不相信 CPU 版本可以正常工作(是吗?它是否缺少警告?这不是我第一次发现 PyTorch 默默地做着应该标记警告的事情),无论如何 GPU 支持是重要

所以:

标签: pythonpython-3.xpytorch

解决方案


您可以使用pad_packed_sequence

def forward(self, inputs, lengths):
        pack1 = nn.utils.rnn.pack_padded_sequence(inputs, lengths, batch_first=True)
        out1, self.hidden1 = self.lstm1(pack1, (self.hidden1[0].detach(), self.hidden1[1].detach()))
        out1, _ = nn.utils.rnn.pad_packed_sequence(out1, batch_first=True) 
        out1 = self.drop(out1)

推荐阅读