使用 pad_sequence 时如何管理隐藏状态变暗?

How to manage the hidden state dims when using pad_sequence?

尝试使用 Pytorch LSTM 架构构建文本生成模型。对于每个批次,我使用 pad_sequence 为每个序列设置最小填充,因此我有一个可变的 dims 批次 (batch_size * seq_len)。我还应用 pack_padded_seq 仅将非零(非填充)标记提供给 LSTM。但是,变量 dims batch 在将其提供给 LSTM 时抛出错误,如下所示; 预期隐藏[0] 大小 (1, 8, 16),得到 (1, 16, 16)。在这个错误中,我为每个序列提供了批处理大小 16 和 8 个标记,但是隐藏状态是 16 * 16。

我曾尝试在前向函数中创建隐藏状态,但效果不佳。我怎样才能创建隐藏状态,使其可以接受可变的 dims 批次并且不会在整个时期丢失?

class RNNModule(nn.Module):
    def __init__(self, n_vocab, seq_size, embedding_size, lstm_size):
        super(RNNModule, self).__init__()
        self.seq_size = seq_size
        self.lstm_size = lstm_size
        self.embedding, num_embeddings, embedding_dim = create_emb_layer(weight_matrix, False)        
        self.lstm = nn.LSTM(embedding_size,
                        lstm_size,
                        num_layers=flags.n_layers,
                        batch_first=True
                        )
        self.dense = nn.Linear(lstm_size, n_vocab)

    def forward(self, x,length,prev_state):

        embed = self.embedding(x)
        packed_input = db.pack_src(embed,length)
        packed_output, state = self.lstm(packed_input,prev_state)
        padded,_ = db.pad_pack(packed_output) 
        logits = self.dense(padded)
        return logits, state


    def zero_state(self, batch_size = flags.batch_size):
        return (torch.zeros(flags.n_layers, batch_size, self.lstm_size),
            torch.zeros(flags.n_layers, batch_size, self.lstm_size))


input: tensor([[  19,    9,    4,    3,   68,    8,    6,    2],
    [  19,    9,    4,    3,    7,    8,    6,    2],
    [   3,   12,   17,   10,    6,   40,    2,    0],
    [   4,    3,  109,    7,    6,    2,    0,    0],
    [ 188,    6,    7,   18,    3,    2,    0,    0],
    [   4,    3,   12,    6,    7,    2,    0,    0],
    [   6,    7,    3,   13,    2,    0,    0,    0],
    [   3,   28,   17,   69,    2,    0,    0,    0],
    [   6,    3,   12,   11,    2,    0,    0,    0],
    [   3,   13,    6,    7,    2,    0,    0,    0],
    [   3,    6,    7,   13,    2,    0,    0,    0],
    [   6,    3,   23,    7,    2,    0,    0,    0],
    [   3,   28,   10,    2,    0,    0,    0,    0],
    [   6,    3,   23,    2,    0,    0,    0,    0],
    [   3,    6,   37,    2,    0,    0,    0,    0],
    [1218,    2,    0,    0,    0,    0,    0,    0]])

零标记是填充。 嵌入大小:64 长短期记忆模型大小:16 批量大小:16

您创建的隐藏状态的大小正确,但您的输入不正确。当你用 nn.utils.rnn.pack_padded_sequence 打包时,你设置了 batch_first=False,但你的数据大小为 [batch_size, seq_len, embedding_size] 当你把它传递给包装时,所以它有 batch_size 作为第一个维度。同样对于 LSTM,您使用 batch_first=True,它适合您的数据。

你只需要通过设置 batch_first=True 来正确打包它,以匹配你的数据顺序。

rnn_utils.pack_padded_sequence(embed,length,batch_first=True)