Appearance
情感分析(RNN版)
一、概述
这个章节我们用循环神经网络来做情感分析,因为之前的 IMDb 电影评论数据集不算大,所以我们用预训练好的词向量(比如 GloVe)来表示每个词,这样可以减少模型的过拟合。我们会用双向循环神经网络来编码文本,最后把文本转换成 "积极" 或 "消极" 的分类结果。
二、模型原理:用双向循环神经网络表示文本
我们的模型是一个双向循环神经网络(BiRNN),结构很简单:
嵌入层:把每个词转换成预训练好的 GloVe 向量,相当于用别人在大数据上训练好的词的语义表示,不用自己从零训练。
双向循环神经网络编码器:用双向的长短期记忆网络(LSTM)来读文本,它会从左到右和从右到左各读一遍文本,这样能同时考虑文本的上下文信息。然后把初始时间步和最终时间步的隐状态连起来,作为整个文本的表示。
全连接输出层:把文本的表示转换成两个输出,对应 "积极" 和 "消极" 两个类别。
简单来说,就是先把词变成有语义的向量,然后让网络从正反两个方向读文本,把文本的信息浓缩成一个向量,最后判断这个文本是好评还是差评。
三、代码实现
1. 定义双向循环神经网络模型
我们定义一个BiRNN类,包含嵌入层、双向 LSTM 编码器和全连接输出层:
python
import torch
from torch import nn
from d2l import torch as d2l
class BiRNN(nn.Module):
def __init__(self, vocab_size, embed_size, num_hiddens, num_layers, **kwargs):
super(BiRNN, self).__init__(**kwargs)
# 嵌入层,把词索引转换成词向量
self.embedding = nn.Embedding(vocab_size, embed_size)
# 双向LSTM编码器,embed_size是输入的词向量维度,num_hiddens是隐藏单元数
self.encoder = nn.LSTM(embed_size, num_hiddens, num_layers=num_layers, bidirectional=True)
# 全连接层,因为双向LSTM的初始和最终隐状态连起来是4*num_hiddens维度,输出2个类别
self.decoder = nn.Linear(4 * num_hiddens, 2)
def forward(self, inputs):
# 先把输入的词索引转换成词向量,inputs形状是(批量大小, 词数)
embeddings = self.embedding(inputs.T) # 转置成(词数, 批量大小, 词向量维度)
# 用双向LSTM编码,得到所有时间步的隐状态
outputs, _ = self.encoder(embeddings)
# 把初始时间步和最终时间步的隐状态连起来,作为文本的表示
encoding = torch.cat((outputs[0], outputs[-1]), dim=1)
# 输出分类结果
outs = self.decoder(encoding)
return outs2. 初始化模型
我们创建一个有 2 个隐藏层的双向循环神经网络,词向量维度设为 100,隐藏单元数设为 100:
python
# 假设vocab是之前处理好的词表
embed_size, num_hiddens, num_layers = 100, 100, 2
net = BiRNN(len(vocab), embed_size, num_hiddens, num_layers)然后我们需要初始化模型的参数,比如用 Xavier 初始化,让参数的分布更合理,方便训练。
3. 训练模型
我们用 Adam 优化器,学习率设为 0.01,训练 5 个轮次:
python
lr, num_epochs = 0.01, 5
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss()
# train_iter和test_iter是之前处理好的IMDb数据集迭代器
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, d2l.try_all_gpus())四、实验结果
训练完成后,我们可以看到:
训练准确率大概在 0.929 左右,测试准确率大概在 0.851 左右
我们可以用训练好的模型预测文本的情感,比如:
输入 "this movie is so great",模型会预测是 "positive"(积极)
输入 "this movie is so bad",模型会预测是 "negative"(消极)
五、小结
我们可以用预训练好的词向量来表示文本里的词,这样能减少小数据集上的过拟合。
双向循环神经网络可以很好地表示文本,它会同时考虑文本的上下文信息,把初始和最终时间步的隐状态连起来作为文本的整体表示,最后用全连接层输出分类结果。
(注:文档部分内容可能由 AI 生成) 源地址