本文已参与「新人创作礼」活动,一起开启掘金创作之路
Capsule network
《Dynamic Routing Between Capsules》
待解决
为什么要设计动态路由算法,动态路由算法的本质看起来也就是反向传播以更新前后层胶囊间的耦合系数。
总体介绍
Capsule network的灵感来自于人眼的视觉感官过程,人在观察图像的过程中并不是和卷积网络一样纵观全局从上至下层层堆叠递进,而是观察图中的关键点构建稀疏树来进行。这一过程就类似于图像渲染的逆过程,为了画一幅人像我们首先需要画出人的大体轮廓,而后在描绘出人体的重要部件如头、躯干、四肢,最后再再每个部件内部添加更为细节的零件如眼睛、嘴巴等等。文章想要构造的网络就是前述过程的逆序,首先判断出一堆局部零件是否存在,再判断这些局部零件可以组成的较大部件是否存在,最后给出由这些较大部件构成的整体是否存在。(在实际中,这并不是直接判断是否存在而是以概率给出)。每个部件实体都是稀疏树的一个节点,节点值即为该部件存在的概率。
模型介绍
如前所说,网络中的每个节点都指带着一个部件,文中将节点称之为胶囊,也就构成了胶囊网络。
squashing
每个胶囊的输入输出均为向量,向量的模值代表着部件存在的概率,向量的相位代表着部件的性质(即用来判断向量间的相似性、从属性)。为了实现这一目的,我们需要对胶囊的原始输出进行非线性压缩如下:
其中将向量缩放到了0~1范围之内,原输出向量的模值越大,整流后输出的模值越接近1,反之则越接近0。而则保留了原输出向量的相位,性质不变。
prediction vector
一个大部件由许多的小部件组合而成,但这些小部件在组合过程中需要发生一定的变换以符合部件融合时的要求,同时不同的小部件对于其从属的大部件的贡献程度不同,例如牙齿就是嘴部由较大贡献程度的部件。因此每个部件的输出应该由其子部件向量的加权变换得到:
其中为前层胶囊得输出向量,为前层某一胶囊i到该层某一胶囊j的变换矩阵,为前层某一胶囊i对该层某一胶囊j的预测向量prediction vector;为前层某一胶囊i对该层某一胶囊j的耦合稀疏coupling cofficients。
coupling cofficients
预测向量的计算涉及到了两个参数:变换矩阵和耦合系数,前者通过网络的反向传播即可得到,后者在本文中则是通过动态路由算法得到。首先假定耦合某个耦合系数是由一临时参数通过以下公式计算所得: 作者将临时参数记作某一胶囊i对该层某一胶囊j的对数先验概率,它在动态路由算法中经过多次循环迭代更新,动态路由算法流程图如下:
假定前层有个胶囊,每个胶囊的输出向量维度为,当前层有个胶囊,每个胶囊的输出向量维度为 则:
- 对前层每一个胶囊计算其对下一层每个胶囊的变换矩阵,构成一整体变换矩阵,矩阵相乘得到预测矩阵;
- 初始化对数先验概率矩阵;
- 对前层的每一个胶囊,计算它对当前层每个胶囊的耦合系数,构成一整体耦合矩阵,列方向上和为1保证前层某个胶囊对当前层的影响被当前层所有胶囊瓜分;
- 对当前层的每一个胶囊,计算其初始输出,构成整体原始输出;
- 对整体原始输出矩阵进行压缩得胶囊的输出;
- 对对数先验概率矩阵的值进行更新,,其内在含义为对当前层的每个胶囊都要计算和前层某个胶囊的预测向量间的点积来衡量二者间的相似性,即衡量在相位(性质)上的相似性,如果二者不相似则二者的点积为负,削弱了对于的重要性,反之则增强了重要性;
- 重复步骤3~6,直到循环终结;
- 输出当前循环轮次胶囊的输出矩阵;
值得注意的是,路由算法的目的应该是在于迭代已找到较好的耦合系数和变换矩阵,但二者均可以通过反向传播算法实现,虽然动态路由算法中存在显式的反向传播(的更新),但仍然受网络训练时的隐式反向传播更新影响。于是在代码实现过程中,有的方法将与动态路由算法解开(创建一副本参与计算),防止了的迭代过程对其产生反向传播影响,而仅在计算最后输出参与进来,而有的算法则未处理。透过这一差异,我们可以提出一个疑问:既然动态路由算法本质是在对进行显式的反向传播,而又是为服务的,为何不直接让或着通过网络的隐式反向传播更新?,可能是为了在不增加网络训练次数的同时增加反向传播的次数以让其更好的符合实际?
具体模型
作者使用的具体模型如下:
模型总共有三层,第一层就是简单的CNN,第二层是基础的Cap层,但对于第一层的输入并没有使用动态路由的方法优化,仍然是对输入采用CNN的模式处理,只不过使用了8个32通道的卷积层,将不同卷积层不同位置的输出拼接认为是经历了Cap的输出向量,获得了6*6*32个8维输出向量,第三层是高级的Cap层,对前层的Cap输入采用了动态路由处理,此层包含了10个Caps,最终输出了10个16维向量,对应于10个类别实体存在的“性质和概率”,取L2范数即可表示每个类别出现的概率,须注意的是由于并没有进行归一化,也就是可以进行识别出图片中多个类别。
训练措施
训练方面,作者使用了margin loss,对于每个类别得到的分类结果都计算出loss后取和作为最终的loss:
另外,作者认为检验网络特征提取能力的一个好方法是使用提取的特征进行重构,故在原始的Capsule net上附加了一个可训练的重构模块,将原Capsule net所有类别输出向量中模值最大的作为输入图片的解码结果,送入三层全连接层即可编码出复原图片,计算这这两张图片的squared error作为网络训练时的正则约束。
实验结果
文章主要在minist数据集上进行验证,给出的分类结果表明CapsuleNet在层数较浅的情况下得到了略逊色于ensembling SOTA模型,但优于单个模型的表现。同时结果表明增加了重构正则确实显著减少了判别错误率(甚至减少幅度大于CapsuleNet对于CNN的改进,怀疑如果在baseline基础上也引入重构正则会不会也有提升)。此外,为了证明模型重构能力不是因为decoder特征提取的好而是因为encoder训练的好(过拟合),作者对解码结果进行了有规律的扰动,发现重构结果也发生了有规律的变化,说明解码结果确实反映了原始图像的某方面的特征,且向量的不同位置于不同特征有关。
除了单个数字的重构,作者尝试了将两张图片进行重叠,编码时轮流将将两个概率最大类别的输出向量送入编码器编码,识别准确率在图片重叠范围更多的情况下与现有方法相当。这证明了CapsuleNet一个非常重要的性质,它确实是依照着部件的组合顺序将图片分配给最相近的类别,而不是简单的将图片和类别联系起来,而如果我们强行使用错误的向量进行重构,可以发现重构结果并不包含该数字,这一现象同样佐证了该性质。它并不是对所有的数字类别都给出了合理的特征提取结果,而是只给识别到的数字赋予可复原的特征向量。
总结
在参考了其他人对Hinton的研究路线梳理之后,大概明白了Capsule结构提出的目的。主要来说是Hinton觉得现有的CNN结构存在着较大的误区,体现在如下方面:
- BP算法过于简单粗暴,单纯的基于当前点的梯度来调整参数优化的方向一步步的逼近最优解,即使是对于鞍点、局部极值等问题的解决方法也只是在BP上添加了一些限制,没有做出实质性的改变,某种意义上而言是定性而非定量的算法。并且BP算法的好坏受最终设计的损失函数影响很大,但直觉上理解,无论是图像分类、语义分割、图像分割,它们的实质都应该归结到图像特征的提取,而不宜受最终目标影响过大;
- 从神经解剖学来看,哺乳动物的大脑皮层中存在着 Cortical minicolumn的柱状结构,而并没有包含大量的分层结构,也就是说从“模仿人脑”角度来看,现有CNN结构堆叠层数的措施是不对的,应该思考如何在单层之内实现复杂内部结构。
- 从认知科学的角度来看,人脑并不是一个完全精密的系统,而是依照着大量先验知识来做出下意识判决的,这就是为何存在着多种视错觉现象(样本过少,学习对实际生活无益)。一个比较显著的特质就是是视觉框架(coordinate frame),它表明人在观察物体时实际上受到坐标系的严重影响的。而CNN却并未体现出这以特点。
- 从不变性的角度来看,CNN架构中大量使用下采样操作(pooling、stride),其机理就是用响应强烈的局部代替整体,减小旋转、平移的影响,增加鲁棒性带来不变性(invariant)。但Hinton认为这种不变性只是对于目标的不变性,指分类结果不变,激活函数输出不变等等,而我们需要的则是更高级的知识等价,预处理时的augumentation同理。此外,CNN架构处理静态图像和视频流的方式有所区别,而大脑则使用同一套视觉系统。Hinton认为这依然与CNN缺乏视觉框架表征有关,
Hinton据此提出了Capsule来取代layer,Capsule使用一组组向量作为输入输出,每层结构更加的复杂,Capsule应该具有如下等价性:
- 位置编码(place-coded):视觉中的内容的位置发生了较大变化,则会由不同的 Capsule 表示其内容。
- 速率编码(rate-coded):视觉中的内容为位置发生了较小的变化,则会由相同的 Capsule 表示其内容,但是内容有所改变。
- 高层的 capsule 有更广的域 (domain),所以低层的 place-coded 信息到高层会变成 rate-coded 为了实现Cap第三点性质,cap的输出应当呈现出如下聚类特性: )
相邻的小内容实体(红点,如圆形、黑白、弧)构成一个更大范围的内容实体(眼睛)。
聚类方法用如下方式评估:
即得分越高,底层实体排布越紧密,对应混合高斯分布就越隶属于该高层部件,越趋向于均匀分布则越不可能形成高级部件。这就是初始提出的路由算法,routing by agreement。
对应于本文,Capsule使用向量输入输出:
底层到高层的部件寻路使用了dynamic routing算法,未使用聚类的概念,反而更加像是attenion机制,
对应不变性的解释:如果同样是在底层Cap发现了某个部件,位置变化过大时可能时会在高层分配给不同部件,通过耦合系数实现;变化不大时则耦合系数不咋变化,权重矩阵发生变化;而底层的大规模变化在高层则成了无伤大雅的小变化。
回到最开头的疑惑,使用routing算法的本质是为了形成底层对高层的选择性归属,具有一定的attention感觉,不直接使用全连接等等是为了减少对于BP的依赖,减少损失函数对训练的影响。
Capsule结构是一种非常有潜力的结构,它的引入也非常的符合直觉,但它的设计并没有让人觉得和初始目的有非常紧密的联系。向量对向量的输入输出对应Cortical minicolumn结构真的类似吗?坐标框架这一先验知识在CapsuleNet中好像也没有直观的体现。动态路由技术真的就很像是简单的内部自BP+attention,与减少BP影响的观念不是很符合。无论如何,这是另一场源自CV内部的革命,值得多加关注,相较于transfomer更加的符合直觉。
参考
浅析Hinton最近提出的Capsule计划 如何看待Hinton的论文《Dynamic Routing Between Capsules》? Capsule Network胶囊网络解读与pytorch代码实现