我的目标是对句子进行多类分类 . 我的RNN(LSTM或GRU)的输入是可变长度序列的批量输入(使用Glove嵌入进行索引) . 此输入右侧用零填充 . 我的GRU RNN重新定义的转发是:

def last_timestep(self, unpacked, lengths):
    # Index of the last output for each sequence
    idx = (lengths - 1).view(-1, 1).expand(unpacked.size(0), unpacked.size(2)).unsqueeze(1)
    return unpacked.gather(1, idx).squeeze()

def forward(self, x, lengths, **kwargs):
    """Forward propagation of activations"""

    if self.gpu:
        x = Variable(x).cuda()
        lengths = Variable(lengths).cuda()
    else:
        x = Variable(x)
        lengths = Variable(lengths)

    # batch_size = int(x.size()[0])
    # h_0 = Variable(torch.zeros(self.total_layers, batch_size, self.hidden_size)).cuda()

    # Embed and pack the padded sequence
    embs = self.embeddings(x)
    packed = pack_padded_sequence(embs, list(lengths.data), batch_first=True)
    out_packed, _ = self.gru(packed)
    out_unpacked, _ = pad_packed_sequence(out_packed, batch_first=True)
    out_last = self.last_timestep(out_unpacked, lengths)
    output = self.lin(out_last)
    return output

至于培训,我正在使用CrossEntropyLoss . 但是,当我测试预测时,无论句子输入如何,它总是预测同一个类 . 此外,RNN的最终输出(可变输出)几乎相同!经过仔细检查,我发现问题出现在反向传播中 .

对于许多参数,梯度非常非常低(大约10 ^ -3且一些低得多) . 而且,我不确定包装或填料是否有帮助?我已经尝试运行代码而没有任何打包(只是在填充输入上向前运行)并得到相同的输出,这让我相信我在打包和解包时做错了 . 我真的很感激任何帮助 . 谢谢!