给出CNN-LSTM模型的完整代码
时间: 2023-08-20 07:44:18 浏览: 191
好的,以下是一个简单的CNN-LSTM模型的完整代码,用于文本分类任务:
```
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
class TextDataset(Dataset):
def __init__(self, data, labels, vocab):
self.data = data
self.labels = labels
self.vocab = vocab
def __len__(self):
return len(self.data)
def __getitem__(self, index):
x = [self.vocab[word] for word in self.data[index].split()]
y = self.labels[index]
return torch.tensor(x), torch.tensor(y)
class CNNLSTM(nn.Module):
def __init__(self, vocab_size, embed_size, num_filters, filter_sizes, hidden_size, num_layers, output_size, dropout):
super(CNNLSTM, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_size)
self.convs = nn.ModuleList([nn.Conv1d(in_channels=embed_size, out_channels=num_filters, kernel_size=fs) for fs in filter_sizes])
self.lstm = nn.LSTM(input_size=num_filters*len(filter_sizes), hidden_size=hidden_size, num_layers=num_layers, dropout=dropout, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
self.dropout = nn.Dropout(dropout)
def forward(self, x, lengths):
x = self.embedding(x)
x = x.permute(0, 2, 1)
x = [self.dropout(nn.functional.relu(conv(x))) for conv in self.convs]
x = [nn.functional.max_pool1d(conv, conv.shape[2]).squeeze(2) for conv in x]
x = torch.cat(x, dim=1)
x = pack_padded_sequence(x, lengths, batch_first=True, enforce_sorted=False)
h0 = torch.zeros(2, x.batch_sizes[0], self.lstm.hidden_size).to(x.device)
c0 = torch.zeros(2, x.batch_sizes[0], self.lstm.hidden_size).to(x.device)
output, (hidden, cell) = self.lstm(x, (h0, c0))
output, _ = pad_packed_sequence(output, batch_first=True)
output = self.dropout(hidden[-1])
output = self.fc(output)
return output
vocab_size = 10000
embed_size = 300
num_filters = 100
filter_sizes = [3, 4, 5]
hidden_size = 256
num_layers = 2
output_size = 2
dropout = 0.5
model = CNNLSTM(vocab_size, embed_size, num_filters, filter_sizes, hidden_size, num_layers, output_size, dropout)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
train_dataset = TextDataset(train_data, train_labels, vocab)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
for epoch in range(10):
running_loss = 0.0
for batch_x, batch_y in train_loader:
lengths = [len(seq) for seq in batch_x]
batch_x = nn.utils.rnn.pad_sequence(batch_x, batch_first=True)
optimizer.zero_grad()
outputs = model(batch_x, lengths)
loss = criterion(outputs, batch_y)
loss.backward()
optimizer.step()
running_loss += loss.item()
print('Epoch: %d, Loss: %.4f' % (epoch+1, running_loss/len(train_loader)))
```
这个模型包含一个CNN模块和一个LSTM模块,用于提取文本的特征。CNN模块使用一维卷积层来提取文本中的n-gram特征,并将不同大小的卷积核得到的特征拼接在一起。LSTM模块使用双向LSTM来对文本进行建模,并输出最后一个时刻的隐藏状态作为文本的表示。最后,将文本的表示输入一个全连接层,输出分类结果。
阅读全文