在图像识别领域,卷积神经网络是非常常见和有用的,我们试图将它应用到文本的情感分类上,如何处理呢?其实思路也是一样的,图片是二维的,文本是一维的,同样的,我们使用一维的卷积核去处理一维的文本(当作一维的图片)即可。这样也可以达到图片抽取特征类似的效果,也可以捕捉到临近词之间的关联。

下面是这节将需要导入的包跟模块

import d2lzh as d2l
from mxnet import gluon,init,nd
from mxnet.contrib import text
from mxnet.gluon import data as gdata,loss as gloss,nn

一维卷积层

一维卷积层的原理跟前面学到的二维卷积层是一样的,一维卷积层使用一维的互相关运算,在一维互相关运算中,卷积窗口从输入数组的最左边开始,按照从左往右的顺序,依次在输入数组上滑动,当卷积窗口滑动到某一个位置时,窗口中的输入子数组就跟核数组按元素相乘并求和。

我们来直观的看图就明白了,输入是宽为7的一维数组,核数组宽为2,输出的宽度:7-2+1=6,高亮颜色的地方按照元素相乘再相加:0x1+1x2=2,如下图:

以前的图很多都是通过CorelDraw来画图,现在使用小画桌来在线画图还是挺方便快捷的,推荐大家使用。

一维互相关运算函数如下:

def corr1d(X,K):w=K.shape[0]Y=nd.zeros((X.shape[0]-w+1))for i in range(Y.shape[0]):Y[i]=(X[i:i+w]*K).sum()return YX,K=nd.array([0,1,2,3,4,5,6]),nd.array([1,2])
print(corr1d(X,K))
'''
[ 2.  5.  8. 11. 14. 17.]
<NDArray 6 @cpu(0)>
'''

跟图片中的结果是一样的,接下来看下多通道的输入和多个卷积核是怎么计算的,先看图:

然后我们也使用一个函数来验证下多通道的结果:

def corr1d_multi_in(X,K):return nd.add_n(*[corr1d(x,k) for x,k in zip(X,K)])
X=nd.array([[0,1,2,3,4,5,6],[1,2,3,4,5,6,7],[2,3,4,5,6,7,8]])
K=nd.array([[1,2],[3,4],[-1,-3]])
print(corr1d_multi_in(X,K))
'''
[ 2.  8. 14. 20. 26. 32.]
<NDArray 6 @cpu(0)>
'''

没有问题,其中*星号是将结果列表变为add_n函数的位置参数,然后进行相加运算。上图的三通道输入的一维卷积运算,是可以看作单通道输入的二维卷积互相关运算。如下图:

时序最大池化层

前面的文章介绍的卷积运算有接池化层,这里同样的,也有一维的池化层。textCNN中使用的时序最大池化(max-over-time pooling)层实际上对应的是一维全局最大池化层:假设输入包含多个通道,各通道由不同时间步上的数值组成,各通道的输出即该通道所有时间步中最大的数值。因此,时序最大池化层的输入在各个通道上的时间步数可以不同。

在textCNN模型中是怎么使用卷积层与时序最大池化层的,我们先画个图来直观感受下:

图片比较直观感受到这个模型的流程,接下来我们设计这个模型,在此之前整理数据集,还是使用前面介绍的电影评论数据集来做情感分析

batch_size=64
d2l.download_imdb()
train_data,test_data=d2l.read_imdb('train'),d2l.read_imdb('test')
vocab=d2l.get_vocab_imdb(train_data)
train_iter=gdata.DataLoader(gdata.ArrayDataset(*d2l.preprocess_imdb(train_data,vocab)),batch_size,shuffle=True)
test_iter=gdata.DataLoader(gdata.ArrayDataset(*d2l.preprocess_imdb(test_data,vocab)),batch_size)

创建textCNN模型

textCNN模型主要步骤如下:

1、定义多个一维卷积,分别对这些输入做卷积计算,宽度不同的卷积核可能会捕捉到不同个数的相邻词的相关性,从图中我们也可以看到卷积核的一个宽度是2,另一个是4
2、对输出的所有通道分别做时序最大池化,再将这些通道的池化输出值连结为向量
3、通过全连接层将连接后的向量变换为有关各类别的输出,这里可以加一个Dropout丢弃层来应对过拟合

实现模型的代码,这里使用两个嵌入层,一个的权重固定,另一个的权重参与训练

class TextCNN(nn.Block):def __init__(self,vocab,embed_size,kernel_sizes,num_channels,**kwargs):super(TextCNN,self).__init__(**kwargs)self.embedding=nn.Embedding(len(vocab),embed_size)# 不参与训练的嵌入层self.constant_embedding=nn.Embedding(len(vocab),embed_size)self.dropout=nn.Dropout(0.5)self.decoder=nn.Dense(2)# 时序最大池化层没有权重,所以可以共用一个实例self.pool=nn.GlobalMaxPool1D()self.convs=nn.Sequential()# 添加多个一维的卷积层for c,k in zip(num_channels,kernel_sizes):# NCWself.convs.add(nn.Conv1D(c,k,activation='relu'))def forward(self,inputs):# NWC(批量大小,词数,词向量维度[通道])的两个嵌入层的输出按照词向量维度dim=2连结embeddings=nd.concat(self.embedding(inputs),self.constant_embedding(inputs),dim=2)# 一维卷积的输入格式是NCW,所以进行形状变换embeddings=embeddings.transpose((0,2,1))# 对于每个一维卷积层,在时序最大池化后会得到一个形状为(批量大小,通道大小,1)的NDArray# 使用flatten函数去掉最后一维,然后在通道维上连结encoding=nd.concat(*[nd.flatten(self.pool(conv(embeddings))) for conv in self.convs],dim=1)# 应用丢弃法后使用全连接层得到输出outputs=self.decoder(self.dropout(encoding))return outputs#创建textCNN实例,3个卷积层,其核宽分别是3,4,5,输出通道数均为100
embed_size,kernel_size,num_channels=100,[3,4,5],[100,100,100]
ctx=d2l.try_all_gpus()
net=TextCNN(vocab,embed_size,kernel_size,num_channels)
net.initialize(init.Xavier(),ctx=ctx)

训练模型

模型的创建,这里使用100维的GloVe词向量,对于GloVe的了解可以参阅:自然语言处理(NLP)之求近义词和类比词<MXNet中GloVe和FastText的模型使用>

glove_embedding=text.embedding.create('glove',pretrained_file_name='glove.6B.100d.txt',vocabulary=vocab)
# 这个嵌入层的权重参数训练
net.embedding.weight.set_data(glove_embedding.idx_to_vec)
# 固定权重
net.constant_embedding.weight.set_data(glove_embedding.idx_to_vec)
net.constant_embedding.collect_params().setattr('grad_req','null')

预训练词向量搞定之后就开始训练模型

lr,num_epochs=0.001,5
trainer=gluon.Trainer(net.collect_params(),'adam',{'learning_rate':lr})
loss=gloss.SoftmaxCrossEntropyLoss()
d2l.train(train_iter,test_iter,net,loss,trainer,ctx,num_epochs)
# 预测
print(d2l.predict_sentiment(net,vocab,['this','movie','is','very','nice']))
print(d2l.predict_sentiment(net,vocab,['this','movie','is','so','bad']))
print(d2l.predict_sentiment(net,vocab,['this','movie','is','not','bad']))
print(d2l.predict_sentiment(net,vocab,['this','movie','is','too','bad']))'''
epoch 1, loss 0.6138, train acc 0.714, test acc 0.832, time 44.2 sec
epoch 2, loss 0.3582, train acc 0.844, test acc 0.852, time 43.5 sec
epoch 3, loss 0.2646, train acc 0.892, test acc 0.864, time 43.5 sec
epoch 4, loss 0.1711, train acc 0.937, test acc 0.868, time 43.3 sec
epoch 5, loss 0.1081, train acc 0.962, test acc 0.858, time 43.4 sec
positive
negative
negative
negative
'''

可以看到训练的准确度还是很不错的,测试的准确度也可以,有待提高,第三条影评识别错误,其余都预测对了。

对于准确度的提高,有两个方向可以去做,还记得吗,就是 MXNet中使用双向循环神经网络BiRNN对文本进行情感分类<改进版>

这篇文章中的两种方法,使用SpaCy分词工具和扩大词向量的维度,有兴趣的伙伴们可以去试试。

MXNet中使用卷积神经网络textCNN对文本进行情感分类相关推荐

  1. MXNet中使用双向循环神经网络BiRNN对文本进行情感分类

    文本分类类似于图片分类,也是很常见的一种分类任务,将一段不定长的文本序列变换为文本的类别.这节主要就是关注文本的情感分析(sentiment analysis),对电影的评论进行一个正面情绪与负面情绪 ...

  2. MXNet中使用双向循环神经网络BiRNN对文本进行情感分类<改进版>

    在上一节的情感分类当中,有些评论是负面的,但预测的结果是正面的,比如,"this movie was shit"这部电影是狗屎,很明显就是对这部电影极不友好的评价,属于负类评价,给 ...

  3. 理解NLP中的卷积神经网络(CNN)

    此篇文章是Denny Britz关于CNN在NLP中应用的理解,他本人也曾在Google Brain项目中参与多项关于NLP的项目.  ·  翻译不周到的地方请大家见谅. 阅读完本文大概需要7分钟左右 ...

  4. 深度学习与自然语言处理教程(8) - NLP中的卷积神经网络(NLP通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://www.showmeai.tech/article-d ...

  5. 斯坦福NLP名课带学详解 | CS224n 第11讲 - NLP中的卷积神经网络(NLP通关指南·完结)

    作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://ww ...

  6. 论文解析:人脸检测中级联卷积神经网络的联合训练

    论文解析:人脸检测中级联卷积神经网络的联合训练 商汤科技解析CVPR2016论文:人脸检测中级联卷积神经网络的联合训练 width="250" height="250&q ...

  7. 【人工智能】图文详解深度学习中的卷积神经网络(CNN)

    [人工智能]图文详解深度学习中的卷积神经网络(CNN) 概念和原理 为什么要使用卷积神经网络? 卷积神经网络简介 卷积神经网络的数学公式 池化操作: 全连接层: 激活函数 卷积神经网络的 C++ 实现 ...

  8. PyTorch基础与简单应用:构建卷积神经网络实现MNIST手写数字分类

    文章目录 (一) 问题描述 (二) 设计简要描述 (三) 程序清单 (四) 结果分析 (五) 调试报告 (六) 实验小结 (七) 参考资料 (一) 问题描述 构建卷积神经网络实现MNIST手写数字分类 ...

  9. DL之AlexNet:利用卷积神经网络类AlexNet实现猫狗分类识别(图片数据增强→保存h5模型)

    DL之AlexNet:利用卷积神经网络类AlexNet实现猫狗分类识别(图片数据增强→保存h5模型) 目录 利用卷积神经网络类AlexNet实现猫狗分类识别(图片数据增强→保存h5模型) 设计思路 处 ...

最新文章

  1. websocket心跳链接代码_WebSocket原理与实践(五)--心跳及重连机制
  2. oracle 字符集 自造字,循序渐进Oracle:自定义字符集的使用、更改字符集的内部方式及字符集更改的案例...
  3. CenterNet-TensorRT 3D Detection
  4. 平滑重启_swoole服务平滑重启
  5. CNCF接纳Harbor为沙箱项目
  6. 未来智能实验室成立,建设世界第一个智能系统智商评测和趋势研究机构
  7. 八城联动丨神策 2020 数据驱动用户大会「深圳场」10 月 22 日不见不散!
  8. 前端学习(1798):前端调试之css伪元素练习
  9. require.js用法简介
  10. ORA-12541:TNS: 没有监听器.解决方法!
  11. HTML5 — 知识总结篇《VI》【路径的写法】
  12. 苹果手机回收价格怎么查询
  13. lzg_ad:下载资料必读
  14. Vo Mic|旧手机不要扔,一招秒变无线麦克风
  15. BZOJ 1135 [POI2009]Lyz 线段树
  16. Google TV 来了
  17. HBuilder开发旅游类APP(二) ----- mui结合H5+,快速实现首页、登录、注册等功能
  18. 【CSS】492- 无外链的CSS开发策略
  19. 微信小程序 自定义组件之 胶囊对齐 搜索FloatSearch
  20. 赛事简介 |香港科大-杰瑞集团 2022【人工智能】百万奖金国际创业大赛

热门文章

  1. RPT-4-D-2T高清录播一体机
  2. 23种设计模式-命令模式《三国大阅兵》
  3. 2021福建省安全员官方 单选题题库及答案
  4. 高标农田建设项目快速处理项目建设规模范围线
  5. Echarts legend属性使用
  6. 34.SAP中动态安全库存的计算
  7. 拼多多科学计算机,人类祖先直立行走的 拼多多怎么得100元时间又提前了数百万年...
  8. .Net中的frame框架
  9. [Win10应用开发] 使用 Windows 推送服务
  10. Q_UNUSED() 方法的使用