动手学深度学习:用预训练 GloVe 词向量与双向 RNN 实现 IMDb 情感分析
发布时间:2026/10/1 17:38:11来源:尧图网络
人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载情感分析是文本分类的典型任务给定一段可变长度的文本判断其情感倾向为“积极”还是“消极”。本篇文章以《动手学深度学习》d2l-zh仓库中的情感分析章节为核心完整演示一条可运行的实战链路使用在大规模语料库上预训练的 GloVe 词向量表示每个词元将其送入**多层双向长短期记忆网络BiLSTM**得到文本序列的整体表示再经全连接层映射为情感类别输出。读完本文你将掌握如何构建BiRNN模型、如何加载并冻结预训练词向量、如何训练与评估模型以及如何用训练好的模型对新句子进行情感预测。为什么情感分析要用预训练词向量与词相似度、词类比任务类似情感分析同样可以应用预训练词向量。由于本节使用的 IMDb 评论数据集规模并不大直接从头训练词嵌入容易过拟合而使用在大规模语料库上预训练的文本表示可以显著降低模型的过拟合风险。预训练词向量已经在大规模文本上捕捉到了词语的语义与句法信息相当于为模型提供了“先验知识”。具体而言本节的方案是用预训练的GloVe 模型为每个词元生成向量表示将这些词元表示送入多层双向循环神经网络得到整条文本序列的表示将文本序列表示转换为情感分析输出积极 / 消极。这里选择的实验数据来自 IMDb 电影评论数据集Maas et al., 2011。对于相同的下游任务后续章节还会给出不同的架构选择例如基于 CNN 的情感分析。环境准备与数据加载首先导入 d2l 工具包与深度学习框架。仓库在d2l/目录下提供了mxnet.py、torch.py、paddle.py、tensorflow.py四个后端的统一封装下面的代码以 PyTorch 后端为例MXNet 与 Paddle 的写法见仓库对应文档from d2l import torch as d2l import torch from torch import nn batch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)d2l.load_data_imdb封装了整个数据流水线实现见 d2l/torch.py自动下载并解压aclImdb数据集调用read_imdb读取训练集与测试集其中积极评论标签为 1、消极评论标签为 0见 d2l/torch.py用tokenize(..., tokenword)对评论做词级切分基于训练集构建词表vocab词频低于 5 的词元会被过滤min_freq5通过truncate_pad将每条评论统一截断或填充到num_steps500个词元不足部分用pad填充打包成批量大小为batch_size的train_iter/test_iter数据迭代器。使用循环神经网络表示单个文本在文本分类任务如情感分析中核心挑战是可变长度的文本序列需要被转换为固定长度的类别。解决办法是用循环神经网络把整条序列编码成一个定长的文本表示向量。BiRNN 模型结构下面的BiRNN类由三个部分组成模块属性作用嵌入层self.embedding为文本序列中每个词元查表获得其预训练词向量表示编码器self.encoder双向 LSTM对整个序列进行编码解码器self.decoder全连接层将文本表示映射为 2 个输出“积极”“消极”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) # 将bidirectional设置为True以获取双向循环神经网络 self.encoder nn.LSTM(embed_size, num_hiddens, num_layersnum_layers, bidirectionalTrue) self.decoder nn.Linear(4 * num_hiddens, 2) def forward(self, inputs): # inputs的形状是批量大小时间步数 # 因为长短期记忆网络要求其输入的第一个维度是时间维 # 所以在获得词元表示之前输入会被转置。 # 输出形状为时间步数批量大小词向量维度 embeddings self.embedding(inputs.T) self.encoder.flatten_parameters() # 返回上一个隐藏层在不同时间步的隐状态 # outputs的形状是时间步数批量大小2*隐藏单元数 outputs, _ self.encoder(embeddings) # 连结初始和最终时间步的隐状态作为全连接层的输入 # 其形状为批量大小4*隐藏单元数 encoding torch.cat((outputs[0], outputs[-1]), dim1) outs self.decoder(encoding) return outs前向传播过程中张量形状的变化是理解本模型的关键输入inputs形状为(批量大小, 时间步数)即每行是一条评论的词元索引序列转置嵌入由于 LSTM 要求输入的第一维是时间维先把输入转置为(时间步数, 批量大小)再经嵌入层得到形状为(时间步数, 批量大小, 词向量维度)的embeddings双向编码双向 LSTM 在每一时间步同时从左到右和从右到左地扫描序列因此输出最后一维是2 * num_hiddens形状为(时间步数, 批量大小, 2 * 隐藏单元数)首尾连结取双向 LSTM 在初始时间步和最终时间步的最后一层隐状态沿特征维连结得到(批量大小, 4 * 隐藏单元数)的文本序列表示正向起始隐状态 正向末尾隐状态 反向起始隐状态 反向末尾隐状态类别输出全连接层将文本表示映射为 2 个输出对应“积极”和“消极”。构造网络并初始化构造一个具有两个隐藏层的双向循环神经网络MXNet 后端使用rnn.LSTM(num_hiddens, num_layersnum_layers, bidirectionalTrue, input_sizeembed_size)并配合init.Xavier()初始化可对照 d2l/mxnet.py 相关实现embed_size, num_hiddens, num_layers 100, 100, 2 devices d2l.try_all_gpus() net BiRNN(len(vocab), embed_size, num_hiddens, num_layers) def init_weights(m): if type(m) nn.Linear: nn.init.xavier_uniform_(m.weight) if type(m) nn.LSTM: for param in m._flat_weights_names: if weight in param: nn.init.xavier_uniform_(m._parameters[param]) net.apply(init_weights);这里用 Xavier 均匀初始化对全连接层和 LSTM 的权重进行初始化。注意embed_size词向量维度与后续加载的 GloVe 向量维度必须一致。加载预训练的词向量为了让模型利用大规模语料库的先验知识接下来加载预训练的100 维 GloVe 嵌入维度需与embed_size保持一致glove_embedding d2l.TokenEmbedding(glove.6b.100d)TokenEmbedding是 d2l 工具包提供的 GloVe / fastText 嵌入加载器实现见 d2l/torch.py。其工作方式为自动下载对应的预训练嵌入文件并解析vec.txt中的词元与向量将unk未知词元索引设为 0其向量为全零向量通过token_to_idx字典实现词元到索引的快速映射支持embedding[tokens]的切片式访问返回批量词元对应的向量矩阵。打印词表中所有词元向量的形状embeds glove_embedding[vocab.idx_to_token] embeds.shape该操作把词表中的每个词元在 GloVe 词表中查找对应的 100 维向量返回形状为(词表大小, 100)的矩阵词表中存在而 GloVe 中没有的词元会被映射到unk全零向量。将预训练向量注入模型并冻结我们使用这些预训练词向量来表示评论中的词元并且在训练期间不更新这些向量将其冻结以保留预训练知识、同时减少可训练参数量、缓解过拟合net.embedding.weight.data.copy_(embeds) net.embedding.weight.requires_grad False在 MXNet 后端中等价操作是net.embedding.weight.set_data(embeds)配合net.embedding.collect_params().setattr(grad_req, null)在 Paddle 后端中则是net.embedding.weight.set_value(embeds)配合stop_gradient的设置。训练和评估模型现在可以开始训练双向循环神经网络进行情感分析。训练超参数设定为学习率lr 0.01、迭代轮数num_epochs 5优化器使用 Adam损失函数使用交叉熵损失lr, num_epochs 0.01, 5 trainer torch.optim.Adam(net.parameters(), lrlr) loss nn.CrossEntropyLoss(reductionnone) d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)d2l.train_ch13是 d2l 提供的多 GPU 训练辅助函数实现见 d2l/torch.py其内部流程为将网络包装为nn.DataParallel并搬移到devices指定的设备上按轮次遍历训练数据累加损失与准确度输出训练过程动画每轮结束在测试集上调用evaluate_accuracy_gpu计算测试准确度打印最终损失、训练准确度、测试准确度以及吞吐量examples/sec。训练完成后定义predict_sentiment函数来使用训练好的模型预测文本序列的情感该函数同样被收录进 d2l 工具包见 d2l/torch.pydef predict_sentiment(net, vocab, sequence): 预测文本序列的情感 sequence torch.tensor(vocab[sequence.split()], deviced2l.try_gpu()) label torch.argmax(net(sequence.reshape(1, -1)), dim1) return positive if label 1 else negative其核心步骤为将句子按空白切分为词元并映射为索引张量reshape 成(1, -1)的批量形状送入网络取两个输出中分数较大者作为预测类别索引 1 对应积极、索引 0 对应消极。最后用训练好的模型对两个简单句子进行情感预测predict_sentiment(net, vocab, this movie is so great) # 期望输出: positive predict_sentiment(net, vocab, this movie is so bad) # 期望输出: negative小结预训练词向量可以表示文本序列中的各个词元GloVe 等在大规模语料库上预训练的向量为每个词元提供了语义丰富的表示缓解了小数据集上的过拟合问题。双向循环神经网络可以表示整条文本序列通过连结双向 LSTM 在初始和最终时间步的隐状态得到一个固定长度的文本表示再经全连接层即可将该表示转换为类别输出。结合预训练词向量、双向 LSTM 编码与全连接分类器即可搭建一个端到端可训练、可部署的情感分析模型整个流程在本仓库中均有完整的源码实现与可复现示例。练习与进阶调优增加迭代轮数将num_epochs调大观察训练与测试准确度的变化进一步调优学习率、隐藏单元数num_hiddens、层数num_layers等超参数探索更优配置。使用更大的预训练词向量尝试加载 300 维的 GloVe 嵌入glove.6b.300d并把embed_size同步改为 300比较分类精度的变化。更换分词器尝试用 spaCy 词元化替代默认分词以提升分类精度。安装方式为pip install spacy和python -m spacy download en然后在代码中执行import spacy、spacy_en spacy.load(en)并定义def tokenizer(text): return [tok.text for tok in spacy_en.tokenizer(text)]替换原来的tokenizer函数。注意 GloVe 与 spaCy 对短语词元的不同处理形式例如短语 “new york” 在 GloVe 词表中是 “new-york”而 spaCy 词元化后得到 “new york”这会导致词表匹配差异。除 PyTorch 实现外本仓库的chapter_natural-language-processing-applications/sentiment-analysis-rnn.md还提供了等价的 MXNetgluon与 Paddle 版本实现便于在不同深度学习框架下对照学习与迁移实践。赞分享人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载相关推荐动手学深度学习基于预训练 GloVe 与双向循环神经网络的情感分析实战动手学深度学习基于预训练 GloVe 与双向循环神经网络的情感分析实战 情感分析sentiment analysis研究人们在产品评论、博客评论等文本中人工智能深度学习机器学习教程《动手学深度学习》词向量实战基于预训练 GloVe 与 fastText 的词相似性与类比推理《动手学深度学习》词向量实战基于预训练 GloVe 与 fastText 的词相似性与类比推理 本篇实战指南以《动手学深度学习》d2l zh中词的相似性人工智能深度学习机器学习教程FLA 算子内核正确性测试与覆盖矩阵flash-linear-attention 的 fla/ops 验证指南FLA 算子内核正确性测试与覆盖矩阵flash linear attention 的 fla/ops 验证指南 本文基于 flash linear atten人工智能深度学习机器学习教程上一篇FRESCO与EBSynth的协同工作完整视频翻译流程详解下一篇如何快速上手Luminous5分钟实现优雅图片灯箱效果创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网