教师强制使用pytorch RNN

时间:2017-11-02 14:33:05

标签: 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

我可以通过以下方式呼叫网络:

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教程(此处)[{{3 (虽然他们在那里逐个训练)。

1 个答案:

答案 0 :(得分:2)

问题1。

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

问题2。

你的model.init_hidden不接受任何输入,但看起来你正试图添加批量大小,也许你可以检查一下,其他一切似乎都没问题。虽然您需要在输出上执行max()或multinomial(),然后才能反馈它。

问题3。

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

相关问题