使用Python实现GRU网络进行中文文本分类
发布时间:2023-12-12 07:50:00
GRU(Gated Recurrent Unit)是一种循环神经网络(RNN)的变种,广泛应用于文本分类、语言模型等自然语言处理(NLP)任务中。本篇文章将使用Python实现一个简单的中文文本分类的GRU网络,并提供一个使用例子。
1. 数据预处理
首先,我们需要对输入的中文文本数据进行预处理。常见的预处理步骤包括文本分词、构建词表、对文本进行编码等。
import jieba
from collections import Counter
def preprocess(data):
# 分词
seg_data = [jieba.lcut(text) for text in data]
# 统计词频
word_counter = Counter()
for text in seg_data:
word_counter.update(text)
# 构建词表
word_vocab = ['<pad>', '<unk>'] + [word for word, _ in word_counter.most_common()]
word2idx = {word: idx for idx, word in enumerate(word_vocab)}
# 对文本进行编码
encoded_data = [[word2idx.get(word, 1) for word in text] for text in seg_data]
return encoded_data, word_vocab, word2idx
2. 模型定义与训练
使用PyTorch库定义GRU网络模型,并进行训练。
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
# 模型定义
class GRUModel(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
super(GRUModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.gru = nn.GRU(embedding_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
embedded = self.embedding(x)
output, hidden = self.gru(embedded)
hidden_last = hidden[-1]
return self.fc(hidden_last)
# 数据集定义
class TextDataset(Dataset):
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __len__(self):
return len(self.data)
def __getitem__(self, index):
return self.data[index], self.labels[index]
# 模型训练
def train(model, train_loader, optimizer, criterion):
model.train()
for inputs, labels in train_loader:
optimizer.zero_grad()
inputs = inputs.to(device)
labels = labels.to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 使用例子
if __name__ == "__main__":
# 读取数据
data = [...] # 读取中文文本数据
labels = [...] # 标签数据
# 预处理
encoded_data, word_vocab, word2idx = preprocess(data)
label2idx = {...} # 定义标签到索引的映射关系
encoded_labels = [label2idx[label] for label in labels]
# 划分训练集和测试集
train_data = encoded_data[:800]
train_labels = encoded_labels[:800]
test_data = encoded_data[800:]
test_labels = encoded_labels[800:]
# 初始化模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = GRUModel(len(word_vocab), embedding_dim=100, hidden_dim=128, output_dim=len(label2idx))
model.to(device)
# 定义优化器和损失函数
optimizer = optim.Adam(model.parameters())
criterion = nn.CrossEntropyLoss()
# 构造数据加载器
train_dataset = TextDataset(train_data, train_labels)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
# 训练模型
for epoch in range(10):
train(model, train_loader, optimizer, criterion)
# 测试模型
test_data_tensor = torch.LongTensor(test_data).to(device)
test_labels_tensor = torch.LongTensor(test_labels).to(device)
model.eval()
with torch.no_grad():
outputs = model(test_data_tensor)
_, predicted_labels = torch.max(outputs, 1)
accuracy = torch.sum(predicted_labels == test_labels_tensor) / len(test_labels_tensor)
print("Accuracy: {:.2f}%".format(accuracy * 100))
本例中的GRU网络模型采用了单层GRU结构,并在最后一个时间步处取出隐藏状态作为文本的表示。模型的输入是一个文本序列,经过embedding层嵌入后输入GRU层,并将最后一个时间步处的隐藏状态通过全连接层映射到输出类别上。
以上是使用Python实现GRU网络进行中文文本分类的简单示例。你可以根据实际需求对模型结构进行调整,并根据数据的不同特点进行数据预处理和训练过程的修改。
