循环神经网络(RNN)中文情感分类项目详解(附完整代码解析)
TextRNN.py模块功能数据预处理与划分TextRNN.pyLSTM 模型定义训练与验证逻辑main.py程序入口,整合运行使用预训练词向量(如腾讯词向量);双向 LSTM 捕捉上下文语义;模型提前停止机制;自动保存验证集最优模型;模块化清晰,易于复用。通过本项目,你能完整理解一个RNN(LSTM)文本情感分类系统的构建流程,从数据预处理到模型保存,全程使用 PyTorch 实现。🧩 建议扩
📘 本文带你一步步解析一个基于 PyTorch 的中文情感分类项目,使用 双向 LSTM(TextRNN) 模型,对微博情感数据进行训练和预测。
文章重点在于:代码讲解 + 实践流程 + 模型结构说明,非常适合初学者上手循环神经网络项目。
🧠 一、RNN 原理简述
在自然语言处理中,文本是一种序列数据,词与词之间存在上下文依赖。
普通的神经网络(如全连接层)无法捕捉到“时间顺序关系”,而 循环神经网络(RNN) 则可以通过“隐藏状态(Hidden State)”在不同时间步之间传递信息,从而具备记忆能力。
RNN 的核心公式为:
![]()
其中:
-
xt:当前输入(词向量)
-
ht−1:上一个隐藏状态(模型的记忆)
-
ht:当前隐藏状态
-
f:激活函数(如 tanh 或 ReLU)
但是,普通 RNN 在长文本中容易出现梯度消失问题,无法学习到远距离依赖。
为此,本项目采用 LSTM(长短期记忆网络),通过“输入门、遗忘门、输出门”控制信息流动,使模型既能记住重要信息,又能忘掉无关内容。
🧩 二、项目总体结构
项目目录如下:
├── load_dataset.py # 数据加载与预处理
├── TextRNN.py # LSTM 模型定义
├── train_eval_test.py # 模型训练与验证逻辑
├── main.py # 主程序入口
任务目标:
通过 LSTM 模型,对微博数据集的文本进行情感分类(喜悦、愤怒、厌恶、低落)。
📂 三、代码详解
✅ 1. 数据加载与预处理(load_dataset.py)
这一部分负责把原始的 CSV 数据转为可供模型训练的数值形式。
🔹 主要功能:
-
读取微博文本及情感标签;
-
将文字切分成字;
-
转换为索引(使用词典);
-
长度统一(填充或截断);
-
划分训练、验证、测试集。
代码片段:
UNK, PAD = '<UNK>', '<PAD>'
def load_dataset(path, pad_size=70):
contents = []
vocab = pkl.load(open('simplifyweibo_4_moods.pkl', 'rb'))
tokenizer = lambda x: [y for y in x]
with open(path, 'r', encoding='UTF-8') as f:
for line in tqdm(f):
label = int(line[0])
content = line[2:].strip()
token = tokenizer(content)
if len(token) < pad_size:
token.extend([PAD] * (pad_size - len(token)))
else:
token = token[:pad_size]
words_line = [vocab.get(word, vocab.get(UNK)) for word in token]
contents.append((words_line, label, len(token)))
random.shuffle(contents)
🔹 数据划分:
train_data = contents[: int(len(contents) * 0.8)]
dev_data = contents[int(len(contents) * 0.8): int(len(contents) * 0.9)]
test_data = contents[int(len(contents) * 0.9):]
🔹 数据迭代器类:
DatasetIterater 用于将数据批量(batch)送入模型:
x = torch.LongTensor([_[0] for _ in datas]).to(self.device)
y = torch.LongTensor([_[1] for _ in datas]).to(self.device)
return (x, seq_len), y
✅ 2. 模型定义(TextRNN.py)
这是整个项目的核心部分,定义了 LSTM 网络结构。
🔹 网络结构:
self.embedding = nn.Embedding.from_pretrained(embedding_pretrained,
padding_idx = n_vocab - 1, freeze=False)
self.lstm = nn.LSTM(embed, 128, 3, bidirectional=True, batch_first=True, dropout=0.3)
self.fc = nn.Linear(128 * 2, num_classes)
解释:
-
Embedding 层:把文字索引转成词向量;
-
LSTM 层:三层双向 LSTM,隐藏单元 128;
-
全连接层:将 LSTM 输出映射到情感类别(4 类)。
🔹 前向传播:
def forward(self, x):
x, _ = x
out = self.embedding(x)
out, _ = self.lstm(out)
out = self.fc(out[:, -1, :]) # 取最后一个时间步
return out
✅ 注意:这里使用双向 LSTM,输出维度为
128 * 2。
取最后时刻的隐藏状态作为句子表示,用于情感分类。
✅ 3. 模型训练与验证(train_eval_test.py)
这一部分包括训练循环和验证逻辑。
🔹 验证函数:
def evaluate(class_list, model, data_iter, test=False):
model.eval()
with torch.no_grad():
for texts, labels in data_iter:
outputs = model(texts)
loss = F.cross_entropy(outputs, labels)
predic = torch.max(outputs.data, 1)[1].cpu().numpy()
计算准确率:
acc = metrics.accuracy_score(labels_all, predict_all)
🔹 训练函数:
def train(model, train_iter, dev_iter, test_iter, class_list):
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(20):
for i, (trains, labels) in enumerate(train_iter):
outputs = model(trains)
loss = F.cross_entropy(outputs, labels)
loss.backward()
optimizer.step()
每 100 个 batch 打印一次训练与验证结果:
if dev_loss < dev_best_loss:
torch.save(model.state_dict(), 'TextRNN.ckpt')
并启用早停机制防止过拟合:
if total_batch - last_improve > 10000:
print("No optimization for a long time, auto-stopping...")
✅ 4. 主程序入口(main.py)
负责整合所有模块并启动训练。
🔹 设置设备和随机种子:
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
np.random.seed(1)
torch.manual_seed(1)
torch.backends.cudnn.deterministic = True
🔹 加载数据与模型:
vocab, train_data, dev_data, test_data = load_dataset.load_dataset('simplifyweibo_4_moods.csv')
train_iter = load_dataset.DatasetIterater(train_data, 128, device)
embedding_pretrained = torch.tensor(np.load('embedding_Tencent.npz')["embeddings"].astype('float32'))
🔹 启动训练:
model = TextRNN.Model(embedding_pretrained, len(vocab), embed, num_classes).to(device)
train(model, train_iter, dev_iter, test_iter, class_list)
📊 四、运行与效果
训练时控制台会输出:
Epoch [5/20]
Iter: 100, Train Loss: 0.59, Train Acc: 78.50%, Val Loss: 0.45, Val Acc: 84.20%
Iter: 200, Train Loss: 0.38, Train Acc: 86.70%, Val Loss: 0.35, Val Acc: 88.00%
训练完成后,模型文件会保存为:
TextRNN.ckpt
在测试集上运行 evaluate(..., test=True) 可以得到完整的分类报告。
🏁 五、总结与亮点
| 模块 | 功能 |
|---|---|
load_dataset.py |
数据预处理与划分 |
TextRNN.py |
LSTM 模型定义 |
train_eval_test.py |
训练与验证逻辑 |
main.py |
程序入口,整合运行 |
项目亮点:
-
使用预训练词向量(如腾讯词向量);
-
双向 LSTM 捕捉上下文语义;
-
模型提前停止机制;
-
自动保存验证集最优模型;
-
模块化清晰,易于复用。
🚀 六、结语
通过本项目,你能完整理解一个 RNN(LSTM)文本情感分类系统 的构建流程,从数据预处理到模型保存,全程使用 PyTorch 实现。
🧩 建议扩展方向:
尝试 GRU、Transformer 替换 LSTM;
添加 Attention 机制;
微调预训练词向量;
增加情感可视化或混淆矩阵分析。
更多推荐
所有评论(0)