摘要
这个是最近比较火的Hinton关于对之前深度神经网络的质疑性论文, 大家都知道Hinton在深度学习领域的地位,那么他为什么对dnn提出质疑,甚至于最近他的演讲论文的title 是 “What is wrong with convolutional neural nets?”。我们来看下具体是什么情况。
定义
capsule: 神经网络的一个层分成多个组,每个组包含多个神经元,他的输出是一个激活向量
激活向量:它是一个向量,它的长度(2范数)用来表示实体存在的概率,方向来表示实体的参数
激活capsule: 上一层的每个capsule通过转换矩阵来得到一个“预测向量”,预测这个capsule和下一层的capsule连接的概率,只有上一层多个capsule的预测是一致的时候,这个这个下层的capsule变为激活状态。
质疑点
论文还没有开始,我先列下Hinton对dnn的质疑点:
- dnn能发挥的能力取决于我们对不同layer的结合,我们通常用的是全连接的方式来连接不同的layer。但是这种方式除了在计算的时候带来性能消耗外,还带来其他的负面影响。我们认为 l层是 眼睛和嘴的单元,l+1 层是脸的单元,这样的连接是有意义的。但是我们把 眼,轮子,手 连接到 脸,其实是无意义的,还加入了干扰信息。所以他们要寻找一种比纯粹全连接更加有意义的连接方式,而且这种方式更容易也更快优化。
- dnn是用bp的形式优化的,但是相反大脑神经元的连接原理是遵从Hebbian 原则:共同激发的神经元连接在一起,Capsules 也是模仿这个假设,低级的capsule更加倾向于将自己的输出传输给某种高级的capsules,这种高级的capsules的激活的向量和低级capsule的数据的点积值比较高。
- 标准的dnn 比如:AlexNet,ResNet,层级之间的下采样pooling连接,采用的 max操作,考虑的2x2这样的邻近像素中最大的值,这里的pooling层没有要学习的参数。一种更好的想法是让他们在更大的区域去学习怎么pool,另外一种更优的方式是一种动态的模式:对于每个可能的父capsule,它自身通过对output和一个权重矩阵进行计算得到一个“预测向量”,有了这个预测向量,这个capsule就知道和那些父capsule进行层级连接了。这个机制称为 routing-by-agreement
CapsNet 机制
CapsNet故名思意它是capsules组成的网络,一般:
第一层是正常的卷积层,卷积层之后生成一个基础的capusle层,然后开始多层的capsules组成的layers。
capsule是一组unit的组合,capsule分别接受上一层每一个capsule的输入,然后经过内部迭代计算,得出一个向量。
我们希望输向量的长度用来代表这个capsule在这个层级能代表这个entity的概率(直观的解释是,假如这个capsule所在的层是预测层,那么每个capsule代表一个类别,最长输出的那个capsule的那个类别概率最大),我们用一个非线性的挤压函数,将短的向量的长度(向量长度)接近0,将长的向量长度变的接近为1
这里保证长度代表概率的机制为,非线形函数:
vj=||sj||21+||sj||2sj||sj||
输入是 sj , 输出是 vj
代码为:
# squash function
ded squash(capsules):
vec_squared_norm = tf.reduce_sum(tf.square(capsules), -2, keep_dims=True)
scalar_factor = vec_squared_norm / (1 + vec_squared_norm) / tf.sqrt(vec_squared_norm + epsilon)
vec_squashed = scalar_factor * capsules # element-wise
详细示例及代码:
我们以手写笔识别的CNN网络为例:

首先:输入图片
Conv1:
经过一个卷积层,卷积层的filter 为:9 x 9, stride=1, 输出的通道数是256
conv1 = tf.layers.conv2d(input, 256, 9, strides=(1, 1), padding='VALID')
# output_nul=256
# kernel_size=9
# conv1 shape = [batch_size, 20, 20, 256]
PrimaryCaps:
也是一个卷积层,filter 为: 9 x 9,strip=2,输出是 32 * 8, 其中32为通道数量,8为每个capsule的神经单元数, 然后经过一个squash 函数:
# output 32 * 8
# shape [batch_size, 6, 6, 32 * 8]
capsules = tf.layers.conv2d(conv1, 32 * 8, 9, strides =(2,2), padding='VALID', activation=tf.nn.relu)
# 8 units per capsule, 1152 capsules
# shape [batch_size, 1152, 8, 1]
capsules = tf.reshape(capsules, (batch_size, -1, 8, 1))
u_i = squash(capsules)
DigitCaps:
capsule 输入输出的计算, 这是算法和机制的重点:
我们先直接贴出capsule输出迭代的算法,然后我们一步步分析:

这个示例我们只是演示了一层capsules,如果多层只要将这个过程重复即可:
我们假设上一层的capsules的输出是 ui∈(u1,u2,...,um)
下面我们开始这个针对下一层capsule j路由的迭代:
ui
在经过一个针对j的独立线性变换后,得到一个i 对j的预测向量,
它的长度表示i是不是目标的概率。
û j|i=Wijui
这里的
Wij
不是共享的向量,假设上一层有i个capsule,
下一层有j个capsule,那么连层连接的W的个数就有i * j个。
代码:
W = tf.get_variable('Weight', shape=(1152, 10, 8, 16), dtype=tf.float32
u_hat_ji = tf.matmul(W, u_i, transpose_a=True)
其中 1152为上一层的输出capsule i的个数,10位下一层capsules j的数量,所以该层连接的W数量是1152 * 10 个。
上面我们计算的是单个capsule i对 j的预测,我们下面需要的上一层的每一个capsule的预测进行综合。
首先我们介绍
bij
:
它是一个参数,代表capsule i 和下一层 capusle j是否建立连接,可以初始化为0向量,求出它我们就有了路由信息,知道该和哪个capsule进行连接了。
# capsule num i=1152
# capsule num j=10
b_IJ = tf.constant(np.zeros([batch_size, 1152, 10, 1, 1], dtype=np.float32))
下面就开始算法的迭代了
Loop Start
- 对于上一层的一个i而言,我们计算i 到下一层各个capule的概率,也就是和它们每一个连接的可能性:
cij=exp(bij)∑kexp(bik)
c_IJ = tf.nn.softmax(b_IJ, dim=2)
- 对于下一层的一个j而言,我们得到i对j的输出预言:
sj=∑icijû j|i
s_J = tf.multiply(c_IJ, u_hat)
s_J = tf.reduce_sum(s_J, axis=1, keep_dims=True)
- 综合所有上一层capsules的预言,预言一致性选择:
vj=||sj||21+||sj||2sj||sj||
- 对输出进行squash处理
v_J = squash(s_J)
- 更新变量
aij=vj.û j|i
bij=bij+aij
u_produce_v = tf.matmul(u_hat, v_J, transpose_a=True)
b_IJ += u_produce_v
Loop End
预测
vj
的长度可以用来预测case j是目标的概率,
所以下一步先计算j维度的长度,然后利用softmax计算概率
代码:
self.v_length = tf.sqrt(
tf.reduce_sum(
tf.square(v_j),
axis=2, keep_dims=True) + epsilon)
self.softmax_v = tf.nn.softmax(self.v_length, dim=1)
Margin loss
我们按手写数字的case为例:
我们最终的目的是预测数字的分类,比如:0-9,最后一层的capsules, 假如数字是5,那么第5个capsule的示例向量应该很长,我们给个综合的Margin loss:
Lc=Tcmax(0,m+−||vc||)2+λ(1−Tc)max(0,||vc||−m−)2
这里如果capsule命中label,
Tc
=1,否则为0
m+=0.9
,
m−=0.1
, 建议的
λ=0.5
所有的loss 是这些最后一层的capsule的loss总和。
综述
下面对比下capsule机制和传统的神经单元的对比:

其他
Reconstruction as a regularization method
参考
论文:https://arxiv.org/pdf/1710.09829v1.pdf
代码:https://github.com/naturomics/CapsNet-Tensorflow
其他:https://medium.com/mlreview/deep-neural-network-capsules-137be2877d44
关注公众号: