pytorch RNN强迫老师

Ami*_*mit 5 pytorch rnn

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
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式致电网络:

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())
Run Code Online (Sandbox Code Playgroud)

只是为了完整性,这里有我的形状x_dataoutput以及hidden

print(x_data.size(), output.size(), hidden.size())
torch.Size([32, 80]) torch.Size([32, 80, 4773]) torch.Size([1, 32, 128])
Run Code Online (Sandbox Code Playgroud)

问题2:是否有可能使用该SimpleRNN网络通过先馈送a <GO_TOKEN>并迭代直到<END_TOKEN>到达an 来逐字生成序列?我问,因为当我运行此:

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

print(output, output.sum())
Run Code Online (Sandbox Code Playgroud)

我得到output全0的和output.sum() = 0。即使在训练网络并逆向传播损失后,我也能做到这一点。有什么想法吗?

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

Oli*_*ver 6

问题1.

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

问题2。

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

问题3。

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