CapsuleNet在文本分类中的应用(一)

去年,由Hinton提出的胶囊网络和路由算法,意在解决CNN和反向传播的缺点,成为了网红结构。本文通过对CapsuleNet修改,尝试将其应用在文本分类上。本篇为第一部分,主要对CapsuleNet进行介绍,对CapsuleNet熟悉的同学可以直接点到第二篇。

1.CapsuleNet简介

首先我们先来看看CapsuleNet长什么样,下图图1和图2是论文中CapsuleNet的结构示意图。

图1 CapsuleNet结构图(1)

图2 CapsuleNet结构图(2)

乍一看这个结构看起来有点烦,不慌,我们一步步慢慢磨。首先是第一部分如下图图3所示。

图3 CapsuleNet分步解析第一部分

首先,第一部分是一个很普通的卷积层,如图3所示。网络的输入为[28, 28]大小的图片,单通道,即大小为[28, 28, 1]的图片;使用256个大小为[9, 9]的卷积核对输入的图片进行卷积操作,熟悉卷积的同学应该可以立马得出该卷积层的输出大小为[20, 20, 256],与普通的卷积层一样,这里的激活函数使用的是Relu函数。第二部分如图4所示。

图4 CapsuleNet分步解析第二部分

由上文可知第一层卷积层的输出为[20, 20, 256],接下来将这个输出输入到下一层名为Primary Capsule(这名字起得还可以)的网络层中。这层看上去很厉害,说白了其实就是作者的YY加上卷积组成的一层网络层。我们首先观察这一层的其中一个卷积层,卷积核的大小依旧为[9, 9],不同的是这里卷积的步长为2(即stride=2),共有8个卷积核,所以这层输出大小为[6, 6, 8]。接下来是关键,作者把32个上述这样的卷积层并列放置,构成Primary Capsule,所以不难得出Primary Capsule这层的总输出为[6, 6, 8, 32]。当然,同学们也可以认为这是一个大的卷积层,即卷积核大小为[9, 9],步长为2,共有256(32x8=256)个卷积核,输出为[6, 6, 256]。

但作者为什么要将原本一个好好的卷积层分开呢,这里就用一个例子阐释一下作者的想法。如下图图5我们要辨别一张图片里是否有一个人。

图5 这是一个普通的人

显然,我们可以简单的识别到图5里面有一个人,然后我们将其变换一下,如图6所示。

图6 这个不是人

在图6中,我们将鼻子,眼睛和嘴巴换了一下位置,得到了一个不是人的图片。接下来是重点,假若我们使用CNN去识别图5和图6是否是一个人,那么很遗憾的告诉你,CNN有很大的概率都会认为图5和图6里面画的东西都是一个人。这关乎了CNN的一个缺点,CNN在处理特征时只会关心该特征是否存在,而忽略了特征的位置,大小和方向等信息。回到图5和图6,显然在这两幅图中,均有眼睛,嘴巴和鼻子三个元素,但图6中这三个元素的位置不对。作者根据这个思路,认为在处理图像特征时,不仅仅要关注特征是否存在,还要关注特征的各种属性。其实这个思路与词向量的思路很像,以前我们使用空间向量模型(SVM),只使用0或1表示词语是否存在;而现在我们使用了词向量,能够更加丰富的表达词的语义信息。

理解了这个思路后,我们回到图4的输出结果为[6, 6, 8, 32],可以认为我们的图像中有32个特征,每个特征又有8个不同的属性,通过关注这些特征以及它们各自的属性,以此提升CNN的效果。一般来说,在卷积之后都会连接一个激活函数,因为我们这里输出的是向量(即[6, 6, 8],若普通CNN输出应为[6, 6, 1]),所以论文中使用了名为“squash”的非线性激活函数对输出进行激活,公式如下:

其中,s为卷积后的输出。在这里使用该函数的目的源于作者认为可以将卷积后输出向量的模长代表为特征出现的概率,而向量的方向则表示为该特征的一些属性。该函数的图像如下:

图7 squash函数图像

可以看到,该函数的值域为[0, 1],即模长越小概率越接近于0,模长越大概率越接近于1。接下来我们继续观察第三部分如图8所示。

图8 CapsuleNet分步解析第三部分

由上文可知,Primary Capsule层的输出为[6, 6, 8, 32],将其输入到下一层名为Digit Capsule的网络层中,在这里我们需要用到全连接和路由算法。论文中此处的全连接矩阵大小为[8, 16],因此我们可以把上一层的输出转置为[6, 6, 32, 8],于是可得输出大小为[6, 6, 32, 16]。接下来是重点,对于每一个特征(上文已经提到过了我们有32个特征,每个特征又有8个属性)都有10个[8, 16]的全连接矩阵,因此我们的最终输出为[6, 6, 32, 16, 10],需要注意的是这里暂时不使用偏置项

这里这么做的含义是:因为论文中使用的MNIST数据集,该数据集的分类类别为10,所以作者想表达的是用10个长度为16的向量表示每一个类别出现的可能性。接下来使用路由算法,路由算法如下图图9所示。

图9 路由算法

首先,先对进行置0,它的大小为[6, 6, 32, 10],然后进行迭代。

第一步为对中的j维进行softmax,即对[6, 6, 32, 10]中10这一维度进行softmax,得到。

第二步为将(将其变为[6, 6, 32, 1, 10])与上一层的输出[6, 6, 32, 16, 10]相乘并对i维进行求和,在这里(6x6x32=1152),将1的维度去除后,得到的结果大小为[16, 10]。还记得上文中我们没有用到偏置项吗,这里我们需要将结果加上偏置项[16, 10],得到。

第三步是使用squash函数对进行激活,得到,大小为[16, 10]。

第四步为对进行更新,将大小变为[1, 1, 1, 16, 10]并与上一层输出[6, 6, 32, 16, 10]相乘,与相加得到新的。

结束后返回作为输出,大小为[16, 10]。

论文中使用的迭代次数为3次,这个算法与其他算法一样也会有过拟合的问题,迭代次数过多会增加泛化误差。另外需要注意的是,路由算法中的参数不会受后向传播的影响,即后向传播的梯度并不会流入路由算法中,只会流入到前面的网络结构中,如Primary Capsule等。接下来我们看第四部分如下图图10所示。

图10 CapsuleNet分步解析第四部分

上文我们提过,作者对于用模长的大小作为表示概率,这里依旧同理,使用模长的大小代表每一个类别的概率,所以可以取其范数作为类别的概率。同时需要注意的是,各个类别的模长大小的和并不像softmax一样和为1,代表它具有识别多个类别的能力。

因为其允许多个类别的存在,所以这里的损失函数没有使用交叉熵损失函数,而是使用了margin loss(这是一种常用与SVM中的损失函数),公式如下。

其中,表示是否存在类别k,若存在则为1,否则为0。为上边界,值为0.9,负责惩罚假阴性(没有预测到存在类别的情况);为下边界,值为0.1,负责惩罚假阳性(预测到不存在的类别的情况)。为0.5,综合两者的情况构成损失函数。

终于,我们来到最后一部分即第五部分,如图11所示。

图10 CapsuleNet分步解析第五部分

这一部分被称为重构部分,即作者认为一个好的模型需要能够将提取出的特征恢复为原来的数据,这样能够保证提取出来的特征是有效特征,其实也可以理解为重构正则化。这里作者首先对Digit Capsule层后的结果进行Mask操作,然后连接了三个全连接层。

Mask操作是指对图像中没有出现的类别,则该类别的维度置为0。例如,输入的图像中包含了0和1两个类别,而没有2~9这八个类别,则在digit Capsule层所输出的结果[16, 10]中,在10这一维度上,第0维和第一维的结果不变,其他维度的值全部置为0。

在Mask操作之后,作者连接三个全连接层(大小和其激活函数如图10所示)对结果进行重构,使用平均平方误差(mse)计算重构后数据于原图之间的差异,该损失为乘上0.0005避免该损失在训练的时候占了大头,影响了margin loss。

至此,CapsuleNet已经完全介绍完毕,下面思考几个问题。

作者使用CapsuleNet的向量输出和路由算法代替传统CNN中的最大池化,好处是什么?

在传统CNN的最大池化中,只保留了最active的特征,当对图像这个特征进行旋转或位移后,对池化的结果并没有任何影响。从这个操作中我们可以感受到最大池化虽然能够保持每次都能检测出这个最active的特征,但如果该特征进行了位移旋转或其他操作,最大池化虽然能检测出来,但明显不能检测出这些位移旋转改变后所带来空间信息的改变。反观CapsuleNet和动态路由算法,虽然其本质上是一个加权求和,但它确确实实的考虑了整个空间中已经学习到的信息,可以说更加robust了。

关于动态路由算法的本质?

动态路由算法本质上就是一个attention,在知乎上看到一个这样的说法,“我认为这个routing确实有几分类似于attention的机制,但它跟attention的差别就是,routing是低层neural unit选择高层neural unit,而attention是高层的选择低层的。”我的理解是,一般来讲attention需要对输出乘上attention矩阵再进行softmax,这里可以理解为这是高层的neural unit;而反观dynamic routing,它通过对已有输出进行操作,避免引入新的变量(例如新的矩阵等,但事实上还是引入了新的变量),通过向量内积之间的大小迭代逐步决定最终softmax结果,这里的避免引入新的变量,只在原有输出上进行操作可看作低层neural unit。

对于抛弃后向传播算法的看法?

作者提出这篇论文的其中一个目的是对后向传播算法提出质疑,他认为后向传播算法现在正在制约深度学习的发展。其中一个观点是现在模型中的所有参数都由loss function通过BP决定,不太合理,一旦loss function设计的不好,整个模型表现就十分差。这点我个人是挺赞同,我们设计loss function时都是非常直接的与类别对比,这未免显得太“势力”,太“直接”了一点,直接对比虽然训练的速度很快,但有时候我们也需要考虑其他方面对模型参数的影响,可以理解为我们需要全局的知识帮助我们更新参数。我们的大脑内成千上万的神经元支持我们能够对事物有正确的认知,虽然计算机暂时还无法拥有这么大的算力,但个人认为需要考虑更多其他知识,比如模型内其他参数的变化也会影响整个模型的参数,即后向传播算法只是我们更新参数的其中一个重要部件,我们需要更多的装备来武装我们的模型。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180515G02B1V00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励