Dynamic Routing Between Capsules学习资料总结

Dynamic Routing Between Capsules(NIPS2017)

摘要:Capsule 是一组神经元,其活动向量(activity vector)表示特定实体类型的实例化参数,如对象或对象部分。我们使用活动向量的长度表征实体存在的概率,向量方向表示实例化参数同一水平的活跃 capsule 通过变换矩阵对更高级别的 capsule 的实例化参数进行预测。当多个预测一致时,更高级别的 capsule 变得活跃。我们展示了判别式训练的多层 capsule 系统在 MNIST 数据集上达到了顶尖的性能,并且在识别高度重叠数字任务中比传统卷积网络的性能优越很多。为了达到这些结果,我们使用迭代的路由协议机制(routing-by-agreement mechanism):较低级别的 capsule 偏向于将输出发送至高级别的 capsule,有了来自低级别 capsule 的预测,高级别 capsule 的活动向量具备较大的标量积。

参考资料:

[1] Sabour S, Frosst N, Hinton G E. Dynamic Routing Between Capsules[J]. 2017.

[2] 知乎话题:https://www.zhihu.com/question/67287444/answer/254512736

[3] 机器之心:https://mp.weixin.qq.com/s/WspmbqlwdxKXH1cgbkuGwQ

[4] 代码实现:https://github.com/naturomics/CapsNet-Tensorflow

1、用一组 Capsules替代神经网络的一层

现在 layer 中的 neuron 太过简单,本身很难表征概念;而Capsule使用向量作为输入输出,而向量就可以作为良好的表征(比如word2vec中的向量就可以良好表征词汇),与一般的向量表征不同,Capsule 的输出向量表征了两个部分:其长度表征了某个实例(物体,视觉概念或者它们的一部分)出现的概率,其方向表征了物体的某些图形属性(位置,颜色,方向,形状等等)。下图(来源[4])展示了capsule与传统神经元之间的区别:

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

2、动态路由算法(Routing by agreement)

一组 Capsules层可以表示为(来源[3]):

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

    输入输出向量的长度表示了某个实体出现的概率,所以它的值必须在 0 到 1 之间。为了实现这种压缩,并完成 Capsule 层级的**功能,Hinton 等人使用了一个被称为squashing的非线性函数。该非线性函数将向量的长度缩放到在0和1之间,方向保持不变。以下是该非线性函数的表达式:

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

Capsule 处理输入分为两个阶段:仿射变换和routing。仿射变换一定程度上是借用神经网络中的线性组合的概念,不过这个仿射变换不是针对一个神经元(也就是只有一个matrix),而是针对capsules (多个matrices),亦即:(其中ui是下层的输入向量,由前层的标号为i的capsule产生,u^j|i是仿射变换后的结果,送给后层的标号为j的capsule)。

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

其中cij为耦合系数(coupling coefficients),该系数由迭代的动态路由选择过程确定。Capsule i的耦合系数和上面层级所有的 Capsule 耦合系数和为 1,并且由routingsoftmax决定,该 softmax 函数中的bij初始为 Capsule i 应该和 Capsule j 耦合的对数先验概率:

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

对数先验(log priors)可以同时和其它权重有区别地进行学习。它们依赖于两个 Capsule 的位置与类型,但不依赖于当前的输入图像。初始化耦合系数可以通过测量前面层级中每一个 Capsule j 的当前输入vj和 Capsule i 的预测间一致性(agreement),然后借助该测量的一致性迭代地精炼更新耦合系数。这个一致性(agreement)可以简单地设置为标量乘积

算法如下:

 Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

3、CapsNet架构

Dynamic Routing Between Capsules学习资料总结

Dynamic Routing Between Capsules学习资料总结

这是一个简单的用于手写体数字识别的 CapsNet 架构。该架构只有两个卷积层和一个全连接层。Conv1有256个9×9卷积核,步幅为1,带有ReLU**。该层将像素强度(pixel intensity)转换成局部特征检测器的活动,然后作为输入传送至主 capsule 中。

第一层的卷积层是最低级别的多维实体,从逆向图(inversegraphics)的角度来看,**该层对应的是逆转渲染过程(rendering process)。这和将多个实例化部分拼合起来组成一个整体有所不同。

第二个层(Primary Capsules)是一个卷积 capsule 层,具有 32 个通道的8D capsule(即每个卷积层包括 8 个卷积单元,每个卷积单元有一个9×9核,步幅为2)。每个主 capsule 输出接收到所有 256×8×1 Conv1 单元的输出,它们的感受野与 capsule 的中心位置重叠。PrimaryCapsules 一共有 [32, 6, 6] capsule 输出(每个输出都是一个 8D 向量),[6, 6] 网格中的每个 capsule 彼此共享权重。

最后的层(DigitCaps)的每个数字类别都有一个16D capsule,每个 capsule 接收来自上面一层所有capsule的输入。

路由选择算法只在两个连续的 capsule 层之间执行(如 PrimaryCapsules 和 DigitCaps)。Conv1 的输出是 1D 的,无法对其空间进行定位。因此 Conv1 和 PrimaryCapsules 之间无法进行路由选择。所有路由选择bij都要被初始化为0。因此最初 capsule 输出ui以同样的概率cij被发送至下一层capsules。

该架构另一种直观的表示方法:

Dynamic Routing Between Capsules学习资料总结 Dynamic Routing Between Capsules学习资料总结

4、损失函数

DigitCaps 层输出向量的长度即某个类别的概率,耦合系数cij是通过一致性 Routing 进行更新的,他并不需要根据损失函数更新,但整个网络其它的卷积参数和 Capsule 内的Wij都需要根据损失函数进行更新。一般我们就可以对损失函数直接使用标准的反向传播更新这些参数,而在原论文中,作者采用了 SVM 中常用的 Marginloss,该损失函数的表达式为:

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

其中 c 是分类类别,Tc为分类的指示函数(c存在为 1,c不存在为 0),m+为上边界,m-为下边界。此外,Vc的模即向量的 L2 距离。

因为实例化向量的长度来表示 Capsule 要表征的实体是否存在,所以当且仅当图片里出现属于类别 k 的手写数字时,希望类别 k 的最顶层 Capsule 的输出向量长度很大。为了允许一张图里有多个数字,对每一个表征数字c的 Capsule分别给出单独的Margin loss:Lc,总的Margin Loss为所有类别Lc求和。

此外,文章还使用额外的重构损失(reconstruction loss)来促进数字 capsule 对输入数字的实例化参数进行编码。

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

在训练期间,蒙住所有向量,除了正确的数字 capsule 的活动向量外,其他向量置为0。然后,使用该活动向量来重构数字,capsule的输出被馈送至包含 3个全连接层的解码器,按0.0005 的比例缩小重构损失,以使它不会主导训练过程中的边际损失。

 

5、实验解读

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

进行3次路由迭代的CapsNet在 MNIST 数据集上的测试重构样例。(l, p, r) 分别代表标签、预测和重构目标。最右两列是两个失败的重构样例,它展示了模型如何混淆该图像中的5和3。其他列来自正确的分类,展示了模型如何识别细节,同时使噪声变得平滑。


Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

CapsNet分类测试准确度与Routing算法以及重构误差之间的关系。其中 MNIST 均值和标准差都是根据三个试验计算而出。

 

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

维度扰动(dimension perturbation)。每一行展示当 DigitCaps 表征的 16 个维度之一在区间 [−0.25, 0.25] 中以0.05 的间隔(interval)进行变化并重构,,发现capsule 中的一个维度(所有 16 个维度中)几乎总是可以表征数字的宽度。而多个维度可以表征全局变化的组合,还有其它一些维度可以表征数字的局部变化。

 

Dynamic Routing Between Capsules学习资料总结Dynamic Routing Between Capsules学习资料总结

在MultiMNIST测试数据上使用了3个Routing迭代。两个重构数字以绿色和红色重叠位于图下方。图上方展示了输入图像。L:(l1,l2) 表示图中输入的两个数字的标签,R:(r1, r2) 表示重构的两个数字。最右两列展示了两个错误重构的例子,分别从标签和预测(以P标记)重构。在(2,8)的例子中,模型混淆了8和7,在(4,9)的例子中,模型混淆了 9 和 0。其它列都给出了正确的分类结果,表明模型能考虑所有的像素并决定每个像素如何分配给两个数字,即使是在相当困难的情景下(第1—4 列)。注意数据集生成的时候,像素的值都简化为 1。带*号的两列展示了既不是从标签也不是从预测重构的数字的结果。这些结果表明模型不止是为图像中的所有(包括未出现的)数字寻找最佳拟合。因此,在(5,0)的例子中,它无法重构出一个7,因为它知道5和0拟合得最好,并且模型已经考虑了所有的像素。同样,在(8,1)的例子中,数字8中的环并不会使模型指向0,因为它已经考虑了8。所以,如果其中一个没有任何其它的支持线索,模型不会将一个像素分配给两个数字。


目前被复现的代码版本:

-TensorFlow:
https://github.com/naturomics/CapsNet-Tensorflow.git 
https://github.com/InnerPeace-Wu/CapsNet-tensorflow 
https://github.com/chrislybaer/capsules-tensorflow

- PyTorch:
https://github.com/timomernick/pytorch-capsule
https://github.com/gram-ai/capsule-networks
https://github.com/nishnik/CapsNet-PyTorch.git
https://github.com/leftthomas/CapsNet

- MXNet
https://github.com/AaronLeong/CapsNet_Mxnet
  
- Chainer:
 https://github.com/soskek/dynamic_routing_between_capsules

- Matlab:
https://github.com/yechengxi/LightCapsNet