循環神經網絡實戰:GRU 對比 LSTM 的中文情感分析(三)
文章目錄
- 循環神經網絡實戰:GRU 對比 LSTM 的中文情感分析(三)
- 前言
- 數據準備(與 LSTM 相同)
- 模型搭建(GRU)
- 訓練與測試
- 可視化 Loss 曲線
- 測試與預測
- GRU vs LSTM 對比
- 總結
前言
在前兩篇文章中,我們已經學習了 RNN/LSTM/GRU 的理論基礎,并完成了一個基于 LSTM 的中文情感分析實戰項目。
那么問題來了:GRU 和 LSTM 到底哪個更好?
本篇我們將使用同樣的任務(中文情感分析),用 GRU 模型替換 LSTM,并進行訓練和測試,最后對比兩者的 速度和效果。
數據準備(與 LSTM 相同)
這里我們依然使用示例的 中文評論數據(完整項目請使用 ChnSentiCorp 數據集)。
import jieba
from torchtext.vocab import build_vocab_from_iterator
from torch.nn.utils.rnn import pad_sequence
import torchtexts = ["這部電影真的很好看", "劇情太差勁了,浪費時間", "演員表演很自然,值得推薦"]
labels = [1, 0, 1]tokenized_texts = [list(jieba.cut(t)) for t in texts]def yield_tokens(data):for tokens in data:yield tokensvocab = build_vocab_from_iterator(yield_tokens(tokenized_texts), specials=["<pad>"])
vocab.set_default_index(vocab["<pad>"])text_ids = [torch.tensor(vocab(t)) for t in tokenized_texts]
padded = pad_sequence(text_ids, batch_first=True, padding_value=vocab["<pad>"])
模型搭建(GRU)
在 LSTM 中,我們有輸入門、遺忘門和輸出門,而 GRU 更加簡潔,只保留了 更新門(update gate)和重置門(reset gate),沒有單獨的細胞狀態。
因此,GRU 參數更少,訓練更快。
PyTorch 代碼如下:
import torch.nn as nnclass SentimentGRU(nn.Module):def __init__(self, vocab_size, embed_dim, hidden_dim, num_layers, num_classes=1):super(SentimentGRU, self).__init__()self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)self.gru = nn.GRU(embed_dim, hidden_dim, num_layers, batch_first=True)self.fc = nn.Linear(hidden_dim, num_classes)self.sigmoid = nn.Sigmoid()def forward(self, x):embedded = self.embedding(x)out, _ = self.gru(embedded)out = self.fc(out[:, -1, :]) # 取最后時刻的隱藏狀態return self.sigmoid(out)
訓練與測試
定義損失函數和優化器:
import torch.optim as optimmodel = SentimentGRU(vocab_size=len(vocab), embed_dim=128, hidden_dim=256, num_layers=2)
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)labels_tensor = torch.tensor(labels, dtype=torch.float)
losses = []
訓練循環(記錄 loss):
for epoch in range(10):optimizer.zero_grad()outputs = model(padded).squeeze()loss = criterion(outputs, labels_tensor)loss.backward()optimizer.step()losses.append(loss.item())print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
可視化 Loss 曲線
import matplotlib.pyplot as pltplt.plot(losses, label="Training Loss (GRU)")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.show()
測試與預測
和 LSTM 一樣,直接輸入新評論:
def predict(text):tokens = list(jieba.cut(text))ids = torch.tensor(vocab(tokens)).unsqueeze(0)output = model(ids)return "積極" if output.item() > 0.5 else "消極"print(predict("故事很精彩"))
print(predict("導演水平太差"))
GRU vs LSTM 對比
我們來對比兩個模型:
模型 | 參數量 | 訓練速度 | 效果(準確率) | 適用場景 |
---|---|---|---|---|
LSTM | 較多 | 較慢 | 穩定,適合長期依賴 | NLP 長文本、機器翻譯 |
GRU | 較少 | 較快 | 接近甚至優于 LSTM | 短文本分類、時間序列預測 |
實驗結論:
- 在小數據集(短文本)下,GRU 的表現通常和 LSTM 不相上下,但訓練更快。
- 在大規模數據集上,LSTM 更穩定,尤其在長依賴問題上優勢明顯。
- 如果你追求 效率 → GRU 更好;
如果你追求 精度和長期記憶能力 → LSTM 更穩妥。
總結
-
本文在 中文情感分析任務 中使用了 GRU 模型,并與 LSTM 進行了對比。
-
實驗表明,GRU 訓練速度更快,效果接近 LSTM,在短文本任務中性價比更高。
-
實際應用中,可以根據 任務規模與需求 來選擇:
- 小數據集/短文本 → GRU
- 長文本/復雜依賴 → LSTM
- 追求最強性能 → Transformer (BERT, GPT 等)