使用pytorch写一个完整的lstm模型,包括数据的训练和评估
时间: 2024-03-27 13:40:14 浏览: 66
好的,下面是一个使用PyTorch实现LSTM模型的示例代码,包括数据的训练和评估。
首先,我们需要准备数据。这里我们使用PyTorch自带的IMDB数据集,它包含了一些电影评论以及它们的标签,用于情感分析任务。我们将使用LSTM模型对这些评论进行分类,判断它们是正面的还是负面的。
``` python
import torch
import torch.nn as nn
from torchtext.datasets import IMDB
from torchtext.data import Field, LabelField, BucketIterator
# 定义Field,用于读取数据
text_field = Field(tokenize='spacy', lower=True)
label_field = LabelField(dtype=torch.float)
# 下载并划分数据集
train_data, test_data = IMDB.splits(text_field, label_field)
# 构建词汇表
text_field.build_vocab(train_data, max_size=10000, vectors="glove.6B.100d")
label_field.build_vocab(train_data)
# 构建数据迭代器
train_iterator, test_iterator = BucketIterator.splits(
(train_data, test_data), batch_size=32, device=torch.device('cuda'))
# 定义模型
class LSTMModel(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim, num_layers, bidirectional, dropout):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers=num_layers, bidirectional=bidirectional, dropout=dropout)
self.fc = nn.Linear(hidden_dim * 2 if bidirectional else hidden_dim, output_dim)
self.dropout = nn.Dropout(dropout)
def forward(self, text):
embedded = self.embedding(text)
output, (hidden, cell) = self.lstm(embedded)
hidden = self.dropout(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1) if self.lstm.bidirectional else hidden[-1,:,:])
return self.fc(hidden)
# 定义训练函数和评估函数
def train(model, iterator, optimizer, criterion):
epoch_loss = 0
epoch_acc = 0
model.train()
for batch in iterator:
optimizer.zero_grad()
predictions = model(batch.text).squeeze(1)
loss = criterion(predictions, batch.label)
acc = binary_accuracy(predictions, batch.label)
loss.backward()
optimizer.step()
epoch_loss += loss.item()
epoch_acc += acc.item()
return epoch_loss / len(iterator), epoch_acc / len(iterator)
def evaluate(model, iterator, criterion):
epoch_loss = 0
epoch_acc = 0
model.eval()
with torch.no_grad():
for batch in iterator:
predictions = model(batch.text).squeeze(1)
loss = criterion(predictions, batch.label)
acc = binary_accuracy(predictions, batch.label)
epoch_loss += loss.item()
epoch_acc += acc.item()
return epoch_loss / len(iterator), epoch_acc / len(iterator)
def binary_accuracy(predictions, labels):
rounded_preds = torch.round(torch.sigmoid(predictions))
correct = (rounded_preds == labels).float()
acc = correct.sum() / len(correct)
return acc
# 训练模型
model = LSTMModel(len(text_field.vocab), 100, 256, 1, 2, True, 0.5)
optimizer = torch.optim.Adam(model.parameters())
criterion = nn.BCEWithLogitsLoss()
model = model.to(torch.device('cuda'))
criterion = criterion.to(torch.device('cuda'))
EPOCHS = 5
for epoch in range(EPOCHS):
train_loss, train_acc = train(model, train_iterator, optimizer, criterion)
valid_loss, valid_acc = evaluate(model, test_iterator, criterion)
print(f'Epoch: {epoch+1:02}')
print(f'\tTrain Loss: {train_loss:.3f} | Train Acc: {train_acc*100:.2f}%')
print(f'\t Val. Loss: {valid_loss:.3f} | Val. Acc: {valid_acc*100:.2f}%')
```
代码中,我们使用了PyTorch的nn.Module构建了一个LSTM模型,它包含了一个嵌入层、一个LSTM层、一个线性层以及一个dropout层。我们定义了train函数和evaluate函数,用于模型的训练和评估,并且使用了PyTorch自带的BCEWithLogitsLoss作为损失函数。
在训练模型之前,我们需要使用Field和BucketIterator来读取并划分数据集。然后我们使用训练集构建词汇表,并使用GloVe预训练的词向量来初始化嵌入层。
最后,我们将模型和损失函数移动到GPU上,并使用Adam优化器训练模型。在每个epoch结束时,我们输出训练集和验证集的损失和准确率。
阅读全文