我正在尝试实现一个LSTM网络,用于预测句子中的下一个单词。这是我第一次构建神经网络,对于我在互联网上找到的所有信息感到困惑。
我尝试使用以下架构:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
class WordLSTM(nn.Module):
def __init__(self, vocabulary_size, embedding_dim, hidden_dim):
super().__init__()
# Word embeddings
self.encoder = nn.Embedding(vocabulary_size, embedding_dim)
# LSTM input dim is embedding_dim, output dim is hidden_dim
self.lstm = nn.LSTM(embedding_dim, hidden_dim)
# Linear layer to map hidden states to vocabulary space
self.decoder = nn.Linear(hidden_dim, vocabulary_size)
def forward(self, sentence):
encoded = self.encoder(sentence)
output, _ = self.lstm(
encoded.view(len(sentence), 1, -1))
decoded = self.decoder(output)
word_scores = F.softmax(decoded, dim=1)
return word_scores[-1].view(1, -1)
我已经创建了一个包含数据集中所有句子的字典,每个单词都使用其在字典中对应的索引进行编码。它们后面跟着一个编码的下一个单词(目标向量)。以下是我正在尝试使用的一系列训练示例:
[tensor([39]), tensor([13698])],
[tensor([ 39, 13698]), tensor([11907])],
[tensor([ 39, 13698, 11907]), tensor([70])]
在训练过程中,我每次只处理一句话,因此我的批量大小始终为1。
NUM_EPOCHS = 100
LEARNING_RATE = 0.0005
rnn = WordLSTM(vocab_size, 64, 32)
optimizer = optim.SGD(rnn.parameters(), lr=LEARNING_RATE)
for epoch in range(NUM_EPOCHS):
training_example = generate_random_training_example(training_ds)
optimizer.zero_grad()
for sentence, next_word in training_example:
output = rnn(sentence)
loss = F.cross_entropy(output, next_word)
loss.backward()
optimizer.step()
print(f"Epoch: {epoch}/{NUM_EPOCHS} Loss: {loss:.4f}")
然而,当我开始训练时,损失值随时间变化不会改变:
Epoch: 0/100 Loss: 10.3929
Epoch: 1/100 Loss: 10.3929
Epoch: 2/100 Loss: 10.3929
Epoch: 3/100 Loss: 10.3929
Epoch: 4/100 Loss: 10.3929
Epoch: 5/100 Loss: 10.3929
Epoch: 6/100 Loss: 10.3929
我已经尝试过将
optimizer.zero_grad()
和optimizer.step()
放到不同的位置,但是也没有帮助。
在这种情况下可能有什么问题呢?我是以错误的方式计算损失,还是以错误的格式传递张量呢?