capsule的一些复现实验
传统卷积神经网络的人脸识别方式已经相当成熟,性能不断提升,各方面的优化空间也慢慢变小,探究新的模型方法,主要解决当前经典模型参数量,计算量大的问题,探索在人脸识别上的有无其他“捷径”可走。
针对《Dynamic Routing Between Capsules》(NIPS 2017)做文章的复现操作,针对文章中网络模型只能适用于小规模输入(28*28)做出改进 ,将其中的全连接的动态路由方式改为卷积方式中的动态路由方式。在MNIST和YaleFace上训练模型,看最终准确率大小。
对于Capsule网路中提出的动态路由,capsule向量作为基本神经网络单元,全连接代替卷积几个新方法尝试做ablation实验,看其各部分内容能给网络参数减少带来的增益有多少。以及在低分辨率的图片中实现有最后层capsule向量向原来图片的重构网络,这样可以在最后层的capsule空间中分析各个capsule在描述图片内容方面承担什么不同的表达任务,譬如字体倾斜,笔画粗细等。
-
实验内容
-
实验方案
-
理解并复现Capsule网络
-
-
作者思想主要有以下几个motivation:
1.当前的梯度反传方式与人类的认知学习过程相违背。作为神经网络提出伊始的仿生目标,人脑神经细胞的突触敏感度的改变方式没有被探究清楚,但是不会是梯度反传这种计算大,计算要求精度高的方式。因此作者希望通过提出的动态路由方式来模拟人脑细胞连接变化。
2.一个单独的标量不足以完整的描述一个实体。对于一个数字或者人脸,即便是对于其中某个部分,譬如鼻子,也需要各个不同的指标去衡量其不同特征,因此作者使用一个向量来作为神经网络的基本构成单元。
图1:capsule网络结构图
图1为capsule网络的一个结构图,其实对于前两层的操作都是普通的卷积操作,卷积核为9*9,比较大,后面会在试验中尝试较小卷积核带来的影响,而且因为capsule网络采取了改变全连接权值来产生激活函数的方式,导致网络中没有pooling层,如果单纯使用3*3卷积的方式来处理图像的话网络会比较深,仅仅处理28*28大小的图像就需要10层以上的神经网络,这会与capsule网络所标榜的减少参数量,降低网络层数的特点相违背。
从第二层开始,256层的channel中的每个“像素”被理解为32个长度为8的capsule,也就是说,在capsule的角度上理解的话,channel降低为32,在我的代码实现中的capsule_layer中的inputs_size和outputs_size所代表都是capsule维度,在乘以capsule_size后,才是真正的featuremap的厚度。之后论文中的处理可以考虑为以capsule为基本单位的全连接操作,capsule_size为8的情况下,每个W矩阵中的元素W(i,j)都是一个转换矩阵,大小为capsule_size*capsule_size,目的是将一个capsule映射成输出capsule。
在前一层所有的capsule对后一层的贡献中,文章并不采用标量运算中的简单求和。其中的原因可以理解为各个神经网络都要有一种措施来引入非线性操作,这样才能拓展网络的表达空间。
上述公式中的迭代路由大概可以理解为前层所有capsule对后层capsule按照均匀的权值来做出贡献,即求平均。得到了一个后层的capsule,因为前层capsule本身长短不一,其长度代表了该capsule代表的实体出现的概率大小,而且分布杂乱,我们拿得到的capsule来逐一地与前层的capsule做乘法,可以得到其余弦距离作为每个前层capsule对该后层capsule的贡献大小评分,按照此评分,我们更新各个capsule的权值(之前均匀权值,各个都相同),会使得各权值发生变化,按照新的权值去求后层capsule会得到新的值,按照此值可以去求新的余弦距离,得到新的权值,以此迭代。
我们可以看到上述过程的一个基本的想法是强者越强的思路。
对于后面提到的重构网络,实现方式比较简单粗暴,直接使用三层的全连接网络来重构图像,使用原图来作为label去训练权值。
-
改写capsule网络到卷积方式
将全连接的网路改写成卷积方式涉及到对基本卷积方式的改写,我们在pytorch中,将卷积操作提到最外层操作。设置capsule_size个普通卷积层,其深度和input_channel一样大小,仍然可以将channel维度上每capsule_size个weight作为一个w(i,j)的一列,用来和一个输入capsule对应相乘,而不同不同的capsule_size的相同位置的weight作为一个w(i,j)的另外一列,这样将所有capsule_size个卷积层结果相加即得到最终所求的结果。将capsule改成卷积方式后,就可以设置不同步长来处理高清图像了。
capsule_layer代码实现如下:
但是这样子在没有pooling或者设置stride大于1的情况下仍然参数量巨大,因为pooling和stride大于1的设置对网络的缩减是成倍缩小的,虽然这可能违背capsule作者Hinton的模型设计初衷,但是本文还是尝试实现,探究其效果如何。
-
实验结果以及分析
根据网络原文,构建了两个capsule网络,一个是capsule_original,构建方式完全和论文中的一样采用两层普通卷积,两层capsule全连接动态路由。这种网络由于使用全连接的方式,导致输入图片变大时参数量会指数增长,所以才yaleface数据集中,统一resize成28*28大小的,在人眼的观察下,图片已经相当模糊了。
图2:yaleface resize(28*28)效果
YaleFace为小数据集其中仅有166张图像,分类目标为15个人。在如此模糊的情况下,capsule_original的识别正确率仅为50%左右.但是在MNIST上,训练集规模较YaleFace大得多,capsule_original达到60000,可能还有数字图像相对变化单一的因素,capsule_original的准确率很高,达到99.38%的准确率。
而另一个capsule网络采用卷积方式连接,称为capsule_conv,我们采用了卷积的方式连接两层capsule,以此来解决全连接的capsule_original不能处理高清样本的问题。但是不能采用relu激活函数来产生非线性,因为relu激活函数在不同channel会激活不同位置的神经元,导致原本不是相同capsule中的变量组成到一个‘杂交’的新capsule,这样子就违背了capsule作为一个操作最小单元的初衷。这样子的话,参数缩减工作只能由设置capsule卷积的stride来完成,在输入为243*320的情况下,通过stride=2来不断减小featuremap规模,让模型不至于out of memory,在这个条件的实验中capsule_conv在YaleFace上准确率84%,而且从trainset的loss下降到0.001以下来看,模型已经有过拟合的趋势。
有一个注意的地方是,人脸识别任务和MNIST的learning_rate设置大小很不一样,可能和数据预处理相关,在learning_rate设置过大的情况下,模型基本上识别错误率不变。
我们对于上述两个capsule模型设置了一组对比实验,是参数规模完全相同的普通卷积网络,stride设置也相同,在训练速度上,普通卷积网络快很多,但是在最终结果上,模型收敛后,只达到了65%的识别准确率,在这个角度上,capsule结构还是优于普通cnn的。
另有文章《Capsule Network Performance on Complex Data》对capsule在cifar10上的表现做了评估,识别准确率只有64%远低于96.53%的最好效果。
图3:在MNIST和CIFAR10上的重构效果
从图3中的重构网络效果比较,我们可以发现,MNIST由于其样本分布空间相对小,重构任务可以很简单的恢复原图,但是cifar10这种的复杂数据集图像就比较难做到。
-
结论
-
从上面几个对比实验,可以发现,相同的参数量的条件下,capsule网络训练时间变长,当然有一部分原因是没有对其中的操作做优化导致的效率问题,但是capsule网络比相同规模的cnn识别准确率和泛化能力都更强一些。
-
而对于文章中提出的重构问题,仅适用于MNIST这种简单数据图像,对于复杂图像的重构效果很差。但是可能引用FCN中的反卷积操作会使重构效果提升很多。capsule网络目前是一个新网络模型的探索阶段,现在来看,并没有产生在识别准确率等方面的令人惊喜的结果。