zoukankan      html  css  js  c++  java
  • 一文深入理解Capsule胶囊网络

    0 - 背景

      Geoffrey Hinton是深度学习的开创者之一,反向传播等神经网络经典算法发明人,他在去年年底和他的团队发表了两篇论文,介绍了一种全新的神经网络,这种网络基于一种称为胶囊(capsule)的结构,并且还发表了用来训练胶囊网络的囊间动态路由算法。

    1 - 研究问题

      传统CNN存在着缺陷(下面会详细说明),如何解决CNN的不足,Hinton提出了一种对于图像处理更加有效的网络——胶囊网络,其综合了CNN的优点的同时,考虑了CNN缺失的相对位置、角度等其他信息,从而使得识别效果有所提升。

    2 - 研究动机

    2.1 - CNN的缺陷

      CNN着力于检测图像像素中的重要特征。考虑简单的人脸检测任务,一张脸是由代表脸型的椭圆、两只眼睛、一个鼻子和一个嘴巴组成。而基于CNN的原理,只要存在这些对象就有一个很强的刺激,因此这些对象空间关系反而没有那么重要。

      如下图,右图不是人脸但都具备了人脸需要的对象,所以CNN有很大可能通过具有的对象激活了是人脸的判断,从而使得结果判断出错。

        img

      重新审视CNN的工作方式,高层特征是低层特征组合的加权和,前一层的激活与下一层神经元的权重相乘并且相加,接着通过非线性激活函数进行激活。在此设置中,组成更高级别特征的简单特征之间没有姿势(平移和旋转)关系。 CNN解决此问题的方法是使用最大池化或连续卷积层,以减少流经网络的数据的空间大小,从而增加高层神经元的“感受野”,从而使它们能够检测出输入图像的较大区域中的高阶特征。最大池化是使卷积网络工作异常出色的关键,在许多领域都可以实现惊人的性能。但是,不要被它的性能所迷惑:尽管CNN的性能比之前的任何模型都要好,但是最大池化却在丢失有价值的信息。Hinton本人说,“The pooling operation used in convolutional neural networks is a big mistake and the fact that it works so well is a disaster.”

    关键问题

    Internal data representation of a convolutional neural network does not take into account important spatial hierarchies between simple and complex objects.

    2.2 - 思想来源

      计算机图形学是基于几何数据内部的层次结构表示来构造可视图像,其结构考虑到了对象的相对位置。内部表示形式以几何对象和矩阵的阵列形式存储在计算机的内存中,这些矩阵表示这些对象的相对位置和方向。然后,专用软件将这种表示形式转换为屏幕上的图像。这称为渲染。

    ​ Hinton受此启发,认为大脑所做的和渲染正好相反,称为逆图形,从眼睛接受的视觉信息中,大脑解析出其所在世界的层次结构表示,并尝试匹配学习到的模式和存储在大脑中的关系,从而有了辨识,注意到,大脑中的物体表示并不依赖视角

      因此,现在要考虑的是如何在神经网络中建模这些分层关系。在计算机图形学中,三维图形中的三维对象之间的关系可以用姿态(pose)表示,位姿的本质是平移和旋转。Hinton提出,保留对象部件之间的分层位姿关系对于正确分类和辨识对象来说很重要。胶囊网络结合了对象之间的相对关系,在数值上表示为4维位姿矩阵。当模型有了位姿信息之后,可以很容易地理解它看到的是以前看到的东西而只是改变了视角而已。如下图,人眼可以很容易分辨出是自由女神像,只是角度的不同,但CNN却很难做到,而把位姿信息集合进去的胶囊网络,也可以判别出是自由女神像的不同角度。

    img

    2.3 - 优点

    • 由于胶囊网络集合了位姿信息,因此其可以通过一小部分数据即学习出很好的表示效果,所以这一点也是相对于CNN的一大提升。举个例子,为了识别手写体数字,人脑需要几十个最多几百个例子,但是CNN却需要几万规模的数据集才能训练出好结果,这显然还是太暴力了!
    • 更加贴近人脑的思维方式,更好地建模神经网络中内部知识表示的分层关系,胶囊背后的直觉非常简单优雅。

    2.4 - 缺点

    3 - 研究内容

    3.1 - 胶囊是什么

      摘抄Hinton等人的《Transforming Auto-encoders》关于胶囊概念理解如下。

    人工神经网络不应当追求“神经元”活动中的视角不变性(使用单一的标量输出来总结一个局部池中的重复特征检测器的活动),而应当使用局部的“胶囊”,这些胶囊对其输入执行一些相当复杂的内部计算,然后将这些计算的结果封装成一个包含信息丰富的输出的小向量。每个胶囊学习辨识一个有限的观察条件和变形范围内隐式定义的视觉实体,并输出实体在有限范围内存在的概率及一组“实例参数”,实例参数可能包括相对这个视觉实体的隐式定义的典型版本的精确的位姿、照明条件和变形信息。当胶囊工作正常时,视觉实体存在的概率具有局部不变性——当实体在胶囊覆盖的有限范围内的外观流形上移动时,概率不会改变。实例参数却是“等变的”——随着观察条件的变化,实体在外观流形上移动时,实例参数也会相应地变化,因为实例参数表示实体在外观流形上的内在坐标。
    

      简单来说,可以理解成:

    • 人造神经元输出单个标量。卷积网络运用了卷积核从而使得将同个卷积核对于二维矩阵的各个区域计算出来的结果堆叠在一起形成了卷积层的输出。
    • 通过最大池化方法来实现视角不变性,因为最大池持续搜寻二维矩阵的区域,选取区域中最大的数字,所以满足了我们想要的活动不变性(即我们略微调整输入,输出仍然一样),换句话说,在输入图像上我们稍微变换一下我们想要检测的对象,模型仍然能够检测到对象
    • 池化层损失了有价值的信息,同时也没有考虑到编码特征间的相对空间关系,因此我们应该使用胶囊,所有胶囊检测中的特征的状态的重要信息,都将以向量形式被胶囊封装(神经元是标量)

      胶囊和人工神经元对比如下:

         img

    img

    2

    3.2 - 囊间动态路由算法

      低层胶囊需要决定如何将其输出向量发送给高层胶囊。低层胶囊改变标量权重,输出向量乘以该权重后,发送给高层胶囊,作为高层胶囊的输入。关于权重,需要知道有:

    • 权重均为非负标量
    • 对每个低层胶囊而言,所有权重总和等于1
    • 对每个低层胶囊而言,权重的数量等于高层胶囊的数量
    • 这些权重由迭代动态路由算法确定

      低层胶囊将其输出发送给对此表示“同意”的高层胶囊,算法伪码如下:

    img

      权重更新可以用如下图来直观理解。

      其中两个高层胶囊的输出用紫色向量表示,橙色向量表示接受自某个低层胶囊的输入,其他黑色向量表示接受其他低层胶囊的输入。左边的紫色输出和橙色输入指向相反的方向,所以它们并不相似,这意味着它们点积是负数,更新路由系数的时候将会减少。右边的紫色输出和橙色输入指向相同方向,它们是相似的,因此更新参数的时候路由系数会增加。在所有高层胶囊及其所有输入上重复应用该过程,得到一个路由参数集合,达到来自低层胶囊的输出和高层胶囊输出的最佳匹配。

             img

      采用多少次路由迭代?论文在MNIST和CIFAR数据集上检测了一定范围内的数值,得到以下结论:

    • 更多的迭代往往会导致过拟合
    • 实践中建议使用3次迭代

    4 - 整体框架

      CapsNet由两部分组成:编码器和解码器。前3层是编码器,后3层是解码器:

    • 第一层:卷积层
    • 第二层:PrimaryCaps(主胶囊)层
    • 第三层:DigitCaps(数字胶囊)层
    • 第四层:第一个全连接层
    • 第五层:第二个全连接层
    • 第六层:第三个全连接层

    4.1 - 编码器

      img

      编码器接受一张28×2828×28的MNIST数字图像作为输入,将它编码为实例参数构成的16维向量。

    4.1.1 - 卷积层
    • 输入:28 x 28 x1
    • 输出:20 × 20 × 256
    • 卷积核:256个步长为1的9 × 9的核
    • 激活函数:ReLU
    • 参数数量:(9 x 9 + 1) x 256 = 20992
    4.1.2 - PrimaryCaps层(32个胶囊)
    • 输入:20 × 20 × 256
    • 输出:6 × 6 × 8 × 32
    • 卷积核:8个步长为2的9×9×256的核/胶囊
    • 参数数量:(9 x 9 x 256 + 1) x 8 x 32 = 5308672
    • 具体:该层有32个主胶囊,通过256个9 x 9的kernel(每8个的结果汇成一个capsule),stride为2,得到PrimaryCaps维度为6 x 6 x 8 x 32(6 x 6是卷积结果,8是capsule的维度,32是channel数).所以这里 (u_{i}, i in[1,32 imes 6 imes 6], v_{j}, j in[1,10] )
    4.1.3 - DigitCaps层(10个胶囊)
    • 输入:6 × 6 × 8 × 32
    • 输出:16 × 10 每一行就是 (v_{j}),共10个数字胶囊,相当于每个 (v_{j})都是由8块胶囊层,每层32个6 x 6维的胶囊通过dynamic routing求和搞出来的。
    • 参数数量:1152 x 8 x 16 + 1152 + 1152 = 1497600
    • 细节:可以将其视为6x6x32 个8维向量,总共是1152个输入向量。根据胶囊的内部工作原理,这些输入向量中的每个向量都有其自己的8x16权重矩阵,该矩阵将8维输入空间映射到16维胶囊输出空间。因此,每个胶囊有1152个矩阵,以及动态路由中使用的1152 c系数和1152 b系数。
    4.1.4 - 损失函数

    img

    4.2 - 解码器

    img

      decoder是为了reconstruction loss,只考虑最后的activity vector(所属的那一类),mask掉其他,并将其通过3层全连接网络重构出原始图像,并将其和原始图像对比算出一个loss,将这个作为一个regularization的方法加在总的损失上。它接受正确的DigitCap的输出作为输入,重建一张28×28像素的图像,损失函数为重建图像和输入图像之间的欧式距离。解码器强制胶囊学习对重建原始图像有用的特征,重建图像越接近输入图像越好,下面展示重建图像的例子。

    img

    4.2.1 - 第一个全连接层
    • 输入:16×10
    • 输出:512
    • 参数数量:(16 x 10 + 1) x 512 = 82432
    4.2.2 - 第二个全连接层
    • 输入:512
    • 输出:1024
    • 参数数量:(512 + 1) x 1024 = 525312
    4.2.3 - 第三个全连接层
    • 输入:1024
    • 输出:784 (用来返回 28 x 28反编码的图片)
    • 参数数量:(1024 + 1) x 784 = 803600

    参考

    https://pechyonkin.me/capsules-1/

  • 相关阅读:
    JUC 1
    给定一个随机数生成器randm(),获得randn()
    堆与优先队列
    集合与映射
    二分搜索树
    链表
    栈与队列
    PostgreSQL ALTER TABLE 命令
    postgresql修改自增序列
    SQL 删除重复行,只保留一条记录
  • 原文地址:https://www.cnblogs.com/icodeworld/p/14072618.html
Copyright © 2011-2022 走看看