用于预测字符的 LSTM:训练循环中的单元状态和隐藏状态

LSTM for predicting characters: cell state and hidden state in the training loop

我的目标是建立一个模型来预测下一个字符。 我已经建立了一个模型,这是我的训练循环:

model = Model(input_size = 30,hidden_size = 256,output_size = len(dataset.vocab))

EPOCH = 10
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
init_states = None

for epoch in range(EPOCH):
    loss_overall = 0.0
    
    for i, (inputs,targets) in enumerate(dataloader):
        optimizer.zero_grad()
        
        pred = model.forward(inputs) 
        loss = criterion(pred, targets)
        loss.backward()
        optimizer.step() 

如您所见,我 return 仅预测模型,而不是 cell_statehidden_state。 所以替代方案是:pred,cell_state,hidden_state = model.forward(inputs)

我的问题是:我应该做人物预测任务吗? Why/why 不是吗? 一般来说:我什么时候应该 return 我的隐藏状态和细胞状态?

要理解隐藏状态,这里有 @nnnmmm from 的出色图表。

隐藏状态是(h_n, c_n),即最后一个时间步的隐藏状态。请注意您如何无法访问时间步 < t 和所有隐藏层的先前状态。如果您需要访问由多个隐藏层组成的更大 RNN 的隐藏状态,检索那些 final 隐藏状态将很有用。但是,通常您只使用一个 nn.LSTM 模块并将其 num_layers 设置为所需的值。

您不需要使用隐藏状态。如果您想从 PyTorch 论坛阅读更多关于 this thread 的信息。


回到你的另一个问题,我们以这个模型为例

rnn = nn.LSTM(input_size=10, hidden_size=256, num_layers=2, batch_first=True)

这意味着输入序列有 seq_length 个大小为 input_size 的元素。考虑到第一个维度上的 batch,它的形状变成 (batch, seq_len, input_size).

out, (h, c) = rnn(x)

如果您想要构建角色预测模型,我看到两个选项。

  • 您可以在每个时间步评估损失。考虑一个输入序列 x 及其目标 y 和 RNN 输出 out。这意味着对于每个时间步长 t,您将计算 loss(out[t], y[t])`。并且这个输入序列的总损失将在所有时间步长上取平均值。

  • 否则只需考虑最后一个时间步长的预测并计算损失:loss(out[-1], y) 其中 y 是仅包含 seq_length+1-序列的第个字符。

如果您使用 nn.CrossEntropyLoss,这两种方法都只需要一次函数调用,如您的 中所述。