关键词:
本文展示的是使用 Pytorch 构建一个 TextCNN 来实现情感分析。本文的架构是第一章详细介绍 TextCNN(不带公式版),第二章是核心代码部分。
目录
1. TextCNN
相较于 LSTM 而言,我个人其实是没看过 CNN 的任何公式的,主要是我觉得也没必要,因为从使用的角度上讲,会用就行;从 CNN 的角度上讲,你只需要知道 CNN 提取的是一种聚合关系就行(与 GNN 不同的是,CNN 提取的是欧式数据的聚合关系,GNN 提取的是非欧数据的聚合关系)。
TextCNN [1] 的模型图如下图所示。其中一共包含了有 3 个模块:卷积层,最大池化层,和输出层。
在原论文中,作者采用了多个通道来提取不同词嵌入的特征,然而如果只有一种词嵌入输入的话,可以参考下面这篇论文[2]中的模型图:
我们现在就以上图作为例子,详细介绍下 TextCNN(仅有一种词嵌入输入时)的具体流程(放心,没有任何公式):
- 首先是输入,TextCNN 的输入是词嵌入,设序列长度为 s s s(在图中为 s = 7 s=7 s=7),设嵌入维度为 d d d(在图中 d = 5 d=5 d=5)。
- 接着 TextCNN 会经过一次二维卷积。首先是卷积核,从图中可以看到,一共有三个卷积核,大小分别为
(
4
×
5
)
(4\\times 5)
(4×5),
(
3
×
5
)
(3\\times 5)
(3×5),
(
2
×
5
)
(2\\times 5)
(2×5)。先从卷积核的第二维开始说,我们发现卷积核的第二维都是
5
,这个尺寸大小与嵌入维度 d d d 相同,就是说对于 TextCNN 而言,一次卷积要囊括所有词嵌入,这个也很好理解,因为只有 d d d 才能够代表整个词语。而对于第一维,分别为4
、3
、2
,这个就指的是,一次卷积考虑几个词语的依赖关系。假设卷积核大小为 ( 4 × 5 ) (4\\times5) (4×5),那么就说明该卷积核一次聚合4
个词语的依赖关系。(注
:图中从左到右第二个区域是卷积核,第三个区域才是卷积后的输出) - 然后从图上可以发现,该图中每个卷积核共有 2 个滤波器(
filter
),所以一共有2
个 ( 4 × 5 ) (4\\times5) (4×5) 的卷积核、2
个 ( 3 × 5 ) (3\\times5) (3×5) 的卷积核、2
个 ( 2 × 5 ) (2\\times5) (2×5) 的卷积核。这里就是说,我们用不同数量的滤波器来捕获这个区间内不同的特征,以 ( 4 × 5 ) (4\\times5) (4×5) 的卷积核举例,我们用滤波器 A 来捕获这4个词语之间的 A 特征,用滤波器 B 来捕获这4个词语之间的 B 特征。 - 卷积之后是一次一维最大池化操作。该过程提取卷积后的向量中的最大值,作为该滤波器的特征。
- 最后将所有滤波器通过最大池化后得到的特征拼接在一起,放到分类器中进行输出。
通过上述的解释,我们可以发现,TextCNN 是通过卷积核的尺寸,来控制模型捕获多少个词语之间的上下文关系。
2. TextCNN 实现情感分析
- 全部代码在 github 上,网址为:https://github.com/Balding-Lee/Pytorch4NLP
- 我采用的是 IMDb 数据集,由于数据集没有验证集,而且读取起来很麻烦,所以我将数据给读取出来,放到了一个文件中,并且将训练集中的10%划分为了验证集,数据集链接如下: https://pan.baidu.com/s/128EYenTiEirEn0StR9slqw,提取码:xtu3 。
- 采用的词嵌入是谷歌的词嵌入,词嵌入的链接如下:链接:https://pan.baidu.com/s/1SPf8hmJCHF-kdV6vWLEbrQ,提取码:r5vx
在本博客中仅介绍模型部分,详细代码见 github。
具体的模型代码如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Config:
def __init__(self):
# 训练配置
self.seed = 22
self.batch_size = 64
self.lr = 1e-3
self.weight_decay = 1e-4
self.num_epochs = 100
self.early_stop = 512
self.max_seq_length = 128
self.save_path = '../model_parameters/CNN_SA.bin'
# 模型配置
self.filter_sizes = (3, 4, 5)
self.num_filters = 100
self.dense_hidden_size = 128
self.dropout = 0.5
self.embed_size = 300
self.num_outputs = 2
class Model(nn.Module):
def __init__(self, embed, config):
super().__init__()
self.embedding = nn.Embedding.from_pretrained(embed, freeze=False)
self.convs = nn.ModuleList(
[nn.Conv2d(1, config.num_filters, (k, config.embed_size)) for k in config.filter_sizes])
self.dropout = nn.Dropout(config.dropout)
self.relu = nn.ReLU()
self.ffn = nn.Linear(config.num_filters * len(config.filter_sizes), config.dense_hidden_size)
self.classifier = nn.Linear(config.dense_hidden_size, config.num_outputs)
def max_pooling(self, x):
x = F.max_pool1d(x, x.size(2)).squeeze(2)
return x
def forward(self, inputs):
# shape: (batch_size, max_seq_length, embed_size)
embed = self.embedding(inputs)
# CNN 接受四维数据输入,
# 第一维: batch,
# 第二维: 通道数 (Channel), 在图像中指的是 RGB 这样的通道, 在自然语言里面指的是多少种词嵌入, 本项目中仅采用一种词嵌入, 所以就是 1 通道
# 第三维: 高度 (Height), 在图像中指的是图片的高, 在自然语言里面就是序列长度
# 第四维: 宽度 (Weight), 在图像中指的是图片的宽, 在自然语言里面就是嵌入维度
# shape: (batch_size, 1, max_seq_length, embed_size)
embed = embed.unsqueeze(1)
cnn_outputs = []
for conv in self.convs:
# shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1)
conv_output = conv(embed)
# shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1)
relu_output = self.relu(conv_output)
# shape: (batch_size, filter_size, max_seq_length - kernel_size + 1, 1)
relu_output = relu_output.squeeze(3)
# shape: (batch_size, filter_size)
pooling_output = self.max_pooling(relu_output)
cnn_outputs.append(pooling_output)
# shape: (batch, num_filters * len(num_filters))
cnn_outputs = torch.cat(cnn_outputs, 1)
cnn_outputs = self.dropout(cnn_outputs)
# shape: (batch, dense_hidden_size)
ffn_output = self.relu(self.ffn(cnn_outputs))
# shape: (batch, num_outputs)
logits = self.classifier(ffn_output)
return logits
在该代码中,我才用的卷积核尺寸是 ( 3 × e m b e d _ s i z e ) (3\\times \\rm embed\\_size) (3×embed_size)、 ( 4 × e m b e d _ s i z e ) (4\\times \\rm embed\\_size) (4×embed_size)、 ( 5 × e m b e d _ s i z e ) (5\\times \\rm embed\\_size) (5×embed_size),每个卷积核共有100个滤波器。同时,分类器一共有两层,一层的尺寸大小为 ( n u m _ f i l t e r s × l e n ( n u m _ f i l t e r s ) , d e n s e _ h i d d e n _ s i z e ) (\\rm num\\_filters \\times len(num\\_filters), \\rm dense\\_hidden\\_size) (num_filters×len(num_filters),dense_hidden_size),一层的尺寸大小为 ( d e n s e _ h i d d e n _ s i z e , n u m _ o u t p u t s ) (\\rm dense\\_hidden\\_size, \\rm num\\_outputs) (dense_hidden_size,num_outputs)。
实验结果如下:
test loss 0.367522 | test accuracy 0.833840 | test precision 0.822838 | test recall 0.850880 | test F1 0.836624
参考
[1] Yoon Kim. Convolutional Neural Networks for Sentence Classification [EB/OL]. https://arxiv.org/pdf/1408.5882.pdf, 2014.
[2] Ye Zhang, Byron C. Wallace. A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification [EB/OL]. https://arxiv.org/pdf/1510.03820.pdf, 2015.
keras深度学习实战——使用循环神经网络构建情感分析模型(代码片段)
Keras深度学习实战——使用循环神经网络构建情感分析模型0.前言1.使用循环神经网络构建情感分析模型1.1数据集分析1.2构建RNN模型进行情感分析相关链接0.前言在《循环神经详解与实现》一节中,我们已经了解循环神经网络(Recurr... 查看详情
keras深度学习实战——使用循环神经网络构建情感分析模型(代码片段)
Keras深度学习实战——使用循环神经网络构建情感分析模型0.前言1.使用循环神经网络构建情感分析模型1.1数据集分析1.2构建RNN模型进行情感分析相关链接0.前言在《循环神经详解与实现》一节中,我们已经了解循环神经网络(R... 查看详情
基于pytorch使用实现cnn如何使用pytorch构建cnn卷积神经网络(代码片段)
基于pytorch使用实现CNN如何使用pytorch构建CNN卷积神经网络本文是一个基于pytorch使用CNN在生物信息学上进行位点预测的例子基于pytorch实现CNN,基于CNN进行位点预测,将CNN代码进行封装,可以非常简单的使用代码,基... 查看详情
pt之transformer:基于pytorch框架利用transformer算法针对imdb数据集实现情感分类的应用案例代码解析(代码片段)
PT之Transformer:基于PyTorch框架利用Transformer算法针对IMDB数据集实现情感分类的应用案例代码解析目录基于PyTorch框架利用Transformer算法针对IMDB数据集实现情感分类的应用案例思路设计(1)、数据准备(2)、数据预处理(3)、模型构建(... 查看详情
项目1:pytorch实现文本情感分析详细教程-准确度高达82%-98%(代码片段)
文章目录比赛链接数据集介绍数据预处理加载Glove2Word2vec模型将单词转化为字典序号构建模型开始训练提交测试结果比赛链接数据集介绍数据集为英文文本数据,其中Label为其情感标签,正负类样本各有12500个。总计样本... 查看详情
pytorch笔记:torchsummary(代码片段)
作用:打印神经网络的结构以pytorch笔记:搭建简易CNN_UQI-LIUWJ的博客-CSDN博客 中搭建的CNN为例importtorchfromtorchsummaryimportsummaryclassCNN(nn.Module):def__init__(self):super(CNN,self).__init__()self.conv1=nn.Sequ 查看详情
nlp进阶,bert+bilstm情感分析实战(代码片段)
Bert+BiLSTM做情感分析情感分析情感分析一类的任务比如商品评价正负面分析,敏感内容分析,用户感兴趣内容分析、甚至安全领域的异常访问日志分析等等实际上都可以用文本分类的方式去做,情感分析的问题本质... 查看详情
keras深度学习实战(28)——利用单词向量构建情感分析模型(代码片段)
Keras深度学习实战(28)——利用单词向量构建情感分析模型0.前言1.模型与数据集分析1.1模型分析1.2数据集分析2.情感分析模型2.1使用CBOW模型获取单词向量2.2构建并训练情感分析模型小结系列链接0.前言在获取单词向量的相关博... 查看详情
学习打卡07可解释机器学习笔记之shape+lime代码实战(代码片段)
...记之Shape+Lime代码实战基于Shapley值的可解释性分析使用Pytorch对MNIST分类可解释性分析使用shap的DeepExplainer进行可视化使用Pytorch对预训练ImageNet图像分类可解释性分析指定单个预测类别指定多个预测类别前k个预测类别LIME代码实... 查看详情
学习打卡07可解释机器学习笔记之shape+lime代码实战(代码片段)
...记之Shape+Lime代码实战基于Shapley值的可解释性分析使用Pytorch对MNIST分类可解释性分析使用shap的DeepExplainer进行可视化使用Pytorch对预训练ImageNet图像分类可解释性分析指定单个预测类别指定多个预测类别前k个预测类别LIME代码实... 查看详情
基于pytorch使用实现cnn如何使用pytorch构建cnn卷积神经网络(代码片段)
基于pytorch使用实现CNN如何使用pytorch构建CNN卷积神经网络本文是一个基于pytorch使用CNN在生物信息学上进行位点预测的例子基于pytorch实现CNN,基于CNN进行位点预测,将CNN代码进行封装,可以非常简单的使用代码,基... 查看详情
keras深度学习实战——使用长短时记忆网络构建情感分析模型(代码片段)
Keras深度学习实战——使用长短时记忆网络构建情感分析模型0.前言1.构建LSTM模型进行情感分类1.1数据集分析1.2模型构建2.构建多层LSTM进行情感分类相关链接0.前言我们已经学习了如何使用循环神经网络(Recurrentneuralnetworks,RNN)构建... 查看详情
图像分类convit从入门到实战——使用convit实现植物幼苗的分类(pytorch)(代码片段)
摘要来自Facebook的研究者提出了一种名为ConViT的新计算机视觉模型,它结合了两种广泛使用的AI架构——卷积神经网络(CNN)和Transformer,该模型取长补短,克服了CNN和Transformer本身的一些局限性。同时,借助这两种架... 查看详情
pytorch实现文本情感分类流程(代码片段)
文章目录基本概念介绍文本情感分类准备数据集文本的序列化构建模型模型的训练与评估完整代码基本概念介绍tokenization:分词,每个词语就是一个token分词方法:转化为单个字(常见)切分词语N-gram:准... 查看详情
nlp进阶,bert+bilstm情感分析实战(代码片段)
Bert+BiLSTM做情感分析情感分析情感分析一类的任务比如商品评价正负面分析,敏感内容分析,用户感兴趣内容分析、甚至安全领域的异常访问日志分析等等实际上都可以用文本分类的方式去做,情感分析的问题本质... 查看详情
手撕cnn之alexnet(pytorch实战篇)
...#xff09;详细介绍了AlexNet的网络结构,今天我们将使用 PyTorch 来复现AlexNet网络,并用AlexNet模型来解决一个经典的Kaggle图像识别比赛问题。正文开始!1. 数据集制作在论文中AlexNe 查看详情
手撕cnn之alexnet(pytorch实战篇)
...#xff09;详细介绍了AlexNet的网络结构,今天我们将使用 PyTorch 来复现AlexNet网络,并用AlexNet模型来解决一个经典的Kaggle图像识别比赛问题。正文开始!1. 数据集制作在论文中AlexNe 查看详情
r语言︱情感分析—词典型代码实践(最基础)
R语言︱情感分析—基于监督算法R语言实现笔记。可以与博客 R语言︱词典型情感分析文本操作技巧汇总(打标签、词典与数据匹配等)对着看。 词典型情感分析大致有以下几个步骤:训练数据集、neg/pos情感词典、分词+... 查看详情