教师用 pytorch RNN 强制

Posted

技术标签:

【中文标题】教师用 pytorch RNN 强制【英文标题】:Teacher forcing with pytorch RNN 【发布时间】:2018-04-15 03:02:26 【问题描述】:

pytorch 教程通过定义输入层和隐藏层以及手动将隐藏层反馈回网络以记住状态,很好地说明了一个简单的 RNN。这种灵活性让您可以非常轻松地执行教师强制。

问题 1:在使用原生 nn.RNN() 模块时如何执行教师强制(因为一次性输入整个序列)?简单的 RNN 网络示例如下:

class SimpleRNN(nn.Module):

    def __init__(self, vocab_size,
                 embedding_dim,
                 batch_sz,
                 hidden_size=128,
                 nlayers=1,
                 num_directions=1,
                 dropout=0.1):

        super(SimpleRNN, self).__init__()

        self.batch_sz = batch_sz
        self.hidden_size = hidden_size

        self.encoder = nn.Embedding(vocab_size, embedding_dim)
        self.rnn = nn.RNN(embedding_dim, hidden_size, nlayers, dropout=0.5)
        self.decoder = nn.Linear(hidden_size, vocab_size)

    def init_hidden(self):
        return autograd.Variable(torch.zeros(nlayers, batch_sz, hidden_size)).cuda()

    def forward(self, inputs, hidden):

        # -- encoder returns:
        # -- [batch_sz, seq_len, embed_dim]
        encoded = self.encoder(inputs) 
        _, seq_len, _ = encoded.size()

        # -- rnn returns:
        # -- output.size() = [seq_len, batch_sz, hidden_sz]
        # -- hidden.size() = [nlayers, batch_sz, hidden_sz]
        output, hidden = self.rnn(encoded.view(seq_len, batch_sz, embedding_dim), hidden)

        # -- decoder returns:
        # -- output.size() = [batch_sz, seq_len, vocab_size]
        output = F.log_softmax(decoder(output.view(batch_sz, seq_len, self.hidden_size)))

        return output, hidden

我可以在哪里调用网络:

model = SimpleRNN(vocab_size, embedding_dim, batch_sz).cuda()
x_data, y_data = get_sequence_data(train_batches[0])
output, hidden = model(x_data, model.init_hidden())

为了完整起见,这里是我的x_dataoutputhidden的形状:

print(x_data.size(), output.size(), hidden.size())
torch.Size([32, 80]) torch.Size([32, 80, 4773]) torch.Size([1, 32, 128])

问题 2:是否可以使用这个 SimpleRNN 网络然后逐字生成序列,首先给它一个 <GO_TOKEN> 并迭代直到一个 <END_TOKEN>到达了?我问是因为当我运行这个时:

x_data = autograd.Variable(torch.LongTensor([[word2idx['<GO>']]]), volatile=True).cuda()
output, hidden = model(x_data, model.init_hidden(1))

print(output, output.sum())

我得到一个全为 0 的 outputoutput.sum() = 0。即使在训练网络并反向传播损失之后我也得到了这个。任何想法为什么?

问题 3:如果不是非常低效,是否可以逐字训练SimpleRNN 网络,类似于显示的 pytorch 教程(此处)[http://pytorch.org/tutorials/intermediate/char_rnn_classification_tutorial.html](尽管他们在那里逐个字符地训练)。

【问题讨论】:

【参考方案1】:

问题 1。

在这种情况下,教师强制是隐式执行的,因为您的 x_data 是 [seq_len, batch_size] 它会将 seq_len 中的每个项目作为输入提供,而不使用实际输出作为下一个输入。

问题 2。

您的 model.init_hidden 不接受任何输入,但是看起来您正在尝试添加批量大小,也许您可​​以检查一下,其他一切似乎都很好。虽然您需要对输出执行 max() 或 multinomial() 才能将其反馈回来。

问题 3。

是的,你可以这样做,是的,它非常低效。这是 CUDNN LSTM 内核的限制

【讨论】:

以上是关于教师用 pytorch RNN 强制的主要内容,如果未能解决你的问题,请参考以下文章

用RNN & CNN进行情感分析 - PyTorch

Pytorch_循环神经网络RNN

Pytorch Note38 RNN 做图像分类

手把手写深度学习——Pytorch+RNN自动生成邓紫棋风格歌词

手把手写深度学习——Pytorch+RNN自动生成邓紫棋风格歌词

PyTorch建立RNN相关模型