作者:小占同学
学校:中国科学技术大学
方向:自然语言处理
本文是本人所写的NLP基础任务——文本分类的【深入TextCNN】系列文章之一。【深入TextCNN】系列文章是结合PyTorch对TextCNN从理论到实战的详细教程。
对深度学习、卷积神经网络和PyTorch有一定的基础
对卷积神经网络用于文本分类有一定实践经验的读者
在拥有上面基础的同时想进一步提高自己、增加对TextCNN的理解的读者
结合PyTorch函数对一、二和三维卷积过程的详细解释;
可能是全网最详细的解释TextCNN过程的文章;
本人才疏学浅,有不足之处请各位不吝赐教,共同探讨!本文会不定期更新,不断修正里面的疏漏内容,增加新理解和新体会。
在卷积神经网络中,卷积核尺度远小于输入的维度,这样每个输出神经元仅与前一层特定局部区域内的神经元存在连接权重(即产生交互),我们称这种特性为稀疏交互。
必须要注意的是,卷积神经网络使用的数据可以是一维、二维和三维的,对于这三种数据,每种都可以是单通道或者是多通道的(可以参见《深度学习》花书p219页表9.1)。下面我们介绍不同维数据的情况下通道数不同的卷积操作。
CLASS torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
m = nn.Conv1d(16, 33, 3, stride=2)
input = torch.randn(20, 16, 50)
output = m(input)
output.shape
#torch.Size([20, 33, 24])
1.若channel数等于1,filter个数等于1时。
首先给出公式,在一维卷积中,我们有公式:
上图中的输入的数据维度为1,长度为8,channel数为1,过滤器filter的维度、个数均为1,长度为5。公式(1)中, 和 分别为输入序列长度和输出序列长度,其它的均为卷积网络中的常见参数。假定这里的padding为0,dilation为1和stride为1,根据给定条件, 等于8,kernel_size等于5,那么就有一维卷积后输出序列 等于8−5+1=4。
2.若channel数不等于1,filter个数等于1时。
3.不管channel数是多少,若过滤器filter数量为n,那么输出数据的shape就变为4×n。原因就是卷积后,在channel方向会进行对应数值相加,而增加滤器不会进行这种操作。
4.dilation参数。空洞卷积。dilation参数的作用,它控制卷积核点之间的间距大小。如下图所示:
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
# With square kernels and equal stride
m = nn.Conv2d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
# non-square kernels and unequal stride and with padding and dilation
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
input = torch.randn(20, 16, 50, 100)
output = m(input)
print(output.shape)
#torch.Size([20, 33, 26, 100])
1.若channel数等于1,filter个数等于1时。
首先给出公式,在二维卷积中,我们有公式
2.若channel数不等于1,filter个数等于1时。
3.不管channel数是多少,若过滤器filter数量为n,那么输出数据的shape就变为10×10×n。
CLASS torch.nn.Conv3d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
在由多个输入平面组成的输入信号上应用3D卷积。
例子:
#With square kernels and equal stride
m = nn.Conv3d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv3d(16, 33, (3, 5, 2), stride=(2, 1, 1), padding=(4, 2, 0))
input = torch.randn(20, 16, 10, 50, 100)
output = m(input)
print(output.shape)
#torch.Size([20, 33, 8, 50, 99])
1.三维卷积主要思想和一维二维的相似,主要区别就是输入数据本身是几维的,那么就用几维卷积。对于三维卷积的输出深度 、高度 和宽度 的计算公式分别如下,具体参数不再详细介绍,都是按标准的方式来写的。
池化也叫做亚采样、下采样(downsampling)或子采样(subsampling),主要针对非重叠区域,包括均值池化(mean pooling)、最大池化(max pooling)。池化操作的本质是降采样。例如,我们可以利用最大池化将4×4的矩阵降采样为2×2的矩阵。
均值池化通过对邻域内特征数值求平均来实现,能够抑制由于邻域大小受限造成估计值方差增大的现象,特点是对背景的保留效果更好。均值池化是求窗口中元素的均值。
最大池化则通过取邻域内特征的最大值来实现,能够抑制网络参数误差造成估计均值偏移的现象,特点是更好地提取纹理信息。最大池化是求窗口中元素的最大值。
降维。这点很好理解,就是经过池化操作后,图像"变小"了。在图像处理中,把图像缩小就称为下采样或降采样,由此可窥见池化操作的降维性质。
不变性(invariance)。包括平移不变性(translation invariance),旋转不变性(rotation invariance),尺度不变性(scale invariance)。简单来说,池化操作能将卷积后得到的特征图中的特征进行统一化。另外,平移不变性,是指一个特征,无论出现在图片的哪一个位置,都会识别出来(也有人说平移不变性是权值共享带来的?)。
定长输出。比如我们的文本分类的例子中就是使用到了这个特性。无论经过卷积后得到的特征图有多大,使用池化操作后总能得到一个scalar,再将这些scalar拼接在一起,就能得到一个定长的向量。
CLASS torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
m = nn.MaxPool1d(3, stride=2)
input = torch.randn(20, 16, 50)
output = m(input)
output.shape
#torch.Size([20, 16, 24])
卷积神经网络的核心思想是捕捉局部特征,对于文本来说,局部特征就是由若干单词组成的滑动窗口,类似于N-gram。卷积神经网络的优势在于能够自动地对N-gram特征进行组合和筛选,获得不同抽象层次的语义信息。
每个词向量可以是预先在其他语料库中训练好的,也可以作为未知的参数由网络训练得到。这两种方法各有优势,预先训练的词嵌入可以利用其他语料库得到更多的先验知识,而由当前网络训练的词向量能够更好地抓住与当前任务相关联的特征。因此,图中的输入层实际采用了双通道的形式,即有两个 的输入矩阵,其中一个用预训练好的词嵌入表达,并且在训练过程中不再发生变化;另外一个也由同样的方式初始化,但是会作为参数,随着网络的训练过程发生改变。
首先,我们要注意到卷积操作在计算机视觉(CV)和NLP中的不同之处。在CV中,卷积核往往都是正方形的,比如 的卷积核,然后卷积核在整张image上沿高和宽按步长移动进行卷积操作。与CV中不同的是,在NLP中输入层的"image"是一个由词向量拼成的词矩阵,且卷积核的宽和该词矩阵的宽相同,该宽度即为词向量大小,且卷积核只会在高度方向移动。因此,每次卷积核滑动过的位置都是完整的单词,不会将几个单词的一部分"vector"进行卷积,词矩阵的行表示离散的符号(也就是单词)[2],这就保证了word作为语言中最小粒度的合理性(当然,如果研究的粒度是character-level而不是word-level,需要另外的方式处理)。
然后,我们详述这个卷积、池化过程。由于卷积核和word embedding的宽度一致,一个卷积核对于一个sentence,卷积后得到的结果是一个vector,其shape=(sentence_len - filter_window_size + 1, 1),那么,在经过max-pooling操作后得到的就是一个Scalar。我们会使用多个filter_window_size(原因是,这样不同的kernel可以获取不同范围内词的关系,获得的是纵向的差异信息,即类似于n-gram,也就是在一个句子中不同范围的词出现会带来什么信息。比如可以使用3,4,5个词数分别作为卷积核的大小),每个filter_window_size又有num_filters个卷积核(原因是卷积神经网络学习的是卷积核中的参数,每个filter都有自己的关注点,这样多个卷积核就能学习到多个不同的信息。[2]中也提到使用多个相同size的filter是为了从同一个窗口学习相互之间互补的特征。比如可以设置size为3的filter有64个卷积核)。一个卷积核经过卷积操作只能得到一个scalar,将相同filter_window_size卷积出来的num_filter个scalar组合在一起,组成这个filter_window_size下的feature_vector。最后再将所有filter_window_size下的feature_vector也组合成一个single vector,作为最后一层softmax的输入。对这个过程若有不清楚的地方,可以对照着图2(该图来自论文[2])来看,图2非常完美地诠释了这个过程。
形式化的说明如下:在输入为 的矩阵上,使用一个kernel 与一个窗口(window) 进行卷积操作,产生一个特征 ,即: 其中 代表由输入矩阵的第 行到第 行所组成的一个大小为 的窗口,由 拼接而成。 表示窗口中的单词数, 为 维的权重矩阵(因此一个filter需要学习的参数个数是 个), 为偏置参数, 为非线性函数。 和 进行点积运算(dot product,逐元素相乘得到的结果再求和)。过滤器应用到一个句子上,从上往下一次移动一步( ),如在 上经卷积操作得到 ,在 上经卷积操作得到 ...,然后将它们拼接起来得到的 就是我们的feature map。每一次卷积操作相当于一次特征向量的提取,通过定义不同的窗口,就可以提取出不同的特征向量,构成卷积层的输出。
最后是池化层。如图中所示的网络采用了1-Max池化,即为从每个滑动窗口产生的特征向量中筛选出一个最大的特征,然后将这些特征拼接起来构成向量表示。也可以选用K-Max池化(选出每个特征向量中最大的K个特征),或者平均池化(将特征向量中的每一维取平均)等,达到的效果都是将不同长度的句子通过池化得到一个定长的向量表示。
首先,我们默认的TextCNN模型超参数一般都是这种配置。如下表:
输入词向量表征:词向量表征的选取(如选word2vec还是GloVe)
卷积核大小:一个合理的值范围在1~10。若语料中的句子较长,可以考虑使用更大的卷积核。另外,可以在寻找到了最佳的单个filter的大小后,尝试在该filter的尺寸值附近寻找其他合适值来进行组合。实践证明这样的组合效果往往比单个最佳filter表现更出色
feature map特征图个数:主要考虑的是当增加特征图个数时,训练时间也会加长,因此需要权衡好。当特征图数量增加到将性能降低时,可以加强正则化效果,如将dropout率提高过0.5
激活函数:ReLU和tanh是最佳候选者
池化策略:1-max pooling表现最佳
正则化项(dropout/L2):相对于其他超参数来说,影响较小点
本文主要讲清楚了一维、二维和三维卷积,和文本分类中卷积操作的具体过程。不同维的卷积使用是根据卷积输入的数据来定,另外,当数据有多个channel时,也要进行相应处理。在文本分类中,主要是要注意一下和CV场景中不同的情况,卷积核不是一个正方形,是一个宽和word embedding相同、长表示n-gram的窗口。一个卷积层会使用多个不同大小的卷积核,往往是(3, 4, 5)这种类型。每一种大小的卷积核也会使用很多个。
[1] Convolutional Neural Networks for Sentence Classification
https://arxiv.org/abs/1408.5882
[2] A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification
https://arxiv.org/abs/1510.03820
卷积神经网络
http://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/5_CNN.html
花书《深度学习》
http://www.deeplearningbook.org/
卷积神经网络(CNN)之一维卷积、二维卷积、三维卷积详解
https://www.cnblogs.com/szxspark/p/8445406.html
官方文档——nn.Conv1d | 官方文档——nn.Conv2d | 官方文档——nn.Conv3d
官方文档——nn.MaxPool1d | 官方文档——nn.MaxPool3d | 官方文档——nn.MaxPool1d
推荐阅读
抛开模型,探究文本自动摘要的本质——ACL2019 论文佳作研读系列
基于RASA的task-orient对话系统解析(二)——对话管理核心模块
基于RASA的task-orient对话系统解析(三)——基于rasa的会议室预定对话系统实例
关于AINLP
AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP君微信(id:AINLP2),备注工作/研究方向+加群目的。