胶囊网络入门一:胶囊网络背后的自觉

回顾:现今深度学习的主力:卷积神经网络
第一:胶囊网络不是空穴来风的新算法,而是基于CNN的缺陷和新需求的改进。
第二,胶囊网络比CNN(卷积神经网络)好在哪里??

CNN优点:
首先,CNN牛X之处在于用类似蛮力的海量数据方式,自动把重要的分类特征找到,所以,无论图像是不是完整,我们都有理由相信CNN能够识别图中有没有“米老鼠”这个对象。只要CNN看到有象征米老鼠的“耳朵”和“鼻子”, CNN就认定这张图中有“米老鼠”。(哪怕拼图还没完成)
CNN缺点:
1、它很难有效识别图中位置的关系,下面两张图对CNN来说是同一个人的脸(哪怕人脸鼻子和眼睛是错位的):即CNN蛮力的背后不能理解图片的语义(和位置关系)。
在这里插入图片描述
2、 CNN没有空间分层和空间推理的能力。而人类的视觉系统可以轻松对下面的图片举一反三:甚至在人脑中,只需要上图的1到2张图片,就可以推测出其他的图片都是“自由女神像”。而CNN需要各个方向的图片进行类似“蛮力”的训练,才能最后达到很好的准确率。
在这里插入图片描述

问题提出:事实上,CNN对于相对位置关系, 是有临时解决方案的:
Max pooling层,或者说pooling层
pooling池化层把邻近区域的特征像素连成一片,变成单个更高层的特征,这就导致了信息丢失(虽然这确实能训练出高层特征间的一些关系)。
解决方案:所以Hinton觉得是该把图像中元素位置关系小数据学习提上机器视觉日程了 (因为我们人类根本不用像CNN那样蛮力学习就能识别未知物体)。因此有了现在的胶囊网络。
论文中的CapsNet架构
论文中的CapsNet架构
结果:对CNN而言,这个任务非常难,因为它没有内建对三维空间的理解。而对于CapsNet而言,这个任务要容易得多,因为它显式地建模了这些关系。相比之前最先进的方法,使用CapsNet的论文能够将错误率降低45%(由约20%降低到约12%),这是一个巨大的提升。

胶囊网络的优势:
相比CNN需要的数据,它只需要学习一小部分数据,就能达到最先进的效果(Hinton在他关于CNN错误的著名演说中提到了这一点)。 从这个意义上说,胶囊理论实际上更接近人脑的行为。为了学会区分数字,人脑只需要几十个例子,最多几百个例子。而CNN则需要几万个例子才能取得很好的效果。这看起来像是在暴力破解,显然要比我们的大脑低级。

为何这么久:
这个想法非常简单,不可能没有人想到过!事实上,Hinton数十年来一直在思考这个想法。没有发表的原因很简单,以前技术上没有实现的方法。其中一个原因是,在大约2012年之前,基于GPU进行运算的时代之前,计算机还不够强大。另一个原因是,没有一种算法可以实现并成功学习胶囊网络。这和反向传播的历史有些相似,人工神经元的概念早在20世纪40年代就出现了,而直到20世纪80年代中期,随着反向传播算法的实现,我们才能成功地训练深度网络。(实际上,反向传播算法在20世纪60年代就提出了,但直到1982年才应用到神经网络上。)
同样,胶囊这个概念本身并不算新,Hinton之前也提到过它,但是直到现在才出现了一种能够实现它的算法。这个算法叫做“囊间动态路由”。它允许胶囊之间相互通信,并创建类似计算机图形中场景图的表示。

结论:
胶囊引入了一个用于深度学习的新构件,以更好地建模神经网络中内部知识表示的分层关系。胶囊背后的直觉非常简单优雅。
Hinton和他的团队提出了一种训练这种胶囊组成的网络的方法,并在一个简单的数据集上成功完成训练,达到了最先进的效果。这是非常鼓舞人心的。
无论如何,胶囊网络是一个非常有趣的模型,而且它现在就能工作。假以时日,它肯定会进一步发展,同时有助于深度学习应用领域的进一步扩展。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一维胶囊网络的Keras代码: ```python from keras import layers, models class CapsuleLayer(layers.Layer): def __init__(self, num_capsules, capsule_dim, num_routing=3, **kwargs): super(CapsuleLayer, self).__init__(**kwargs) self.num_capsules = num_capsules self.capsule_dim = capsule_dim self.num_routing = num_routing def build(self, input_shape): self.input_num_capsules = input_shape[1] self.input_capsule_dim = input_shape[2] self.W = self.add_weight(shape=[self.input_num_capsules, self.num_capsules, self.input_capsule_dim, self.capsule_dim], initializer='glorot_uniform', name='W') self.built = True def call(self, inputs, **kwargs): inputs_expand = tf.expand_dims(inputs, 2) inputs_tiled = tf.tile(inputs_expand, [1, 1, self.num_capsules, 1]) inputs_hat = tf.scan(lambda ac, x: tf.matmul(self.W, x), elems=inputs_tiled, initializer=tf.zeros([self.input_num_capsules, self.num_capsules, 1, self.capsule_dim])) b = tf.zeros([inputs.shape[0], self.input_num_capsules, self.num_capsules, 1, 1]) for i in range(self.num_routing): c = tf.nn.softmax(b, dim=2) s = tf.reduce_sum(tf.multiply(c, inputs_hat), axis=1, keepdims=True) v = self.squash(s) b += tf.reduce_sum(tf.multiply(v, inputs_hat), axis=-1, keepdims=True) return tf.squeeze(v, axis=1) def squash(self, x): norm = tf.reduce_sum(tf.square(x), axis=-1, keepdims=True) scale = norm / (1 + norm) / tf.sqrt(norm + 1e-8) return scale * x def build_capsule_network(input_shape, n_class, num_routing): x = layers.Input(shape=input_shape) conv1 = layers.Conv1D(filters=256, kernel_size=9, strides=1, padding='valid', activation='relu', name='conv1')(x) primary_caps = CapsuleLayer(num_capsules=8, capsule_dim=32, num_routing=num_routing, name='primary_caps')(conv1) digit_caps = CapsuleLayer(num_capsules=n_class, capsule_dim=16, num_routing=num_routing, name='digit_caps')(primary_caps) output = layers.Lambda(lambda x: tf.sqrt(tf.reduce_sum(tf.square(x), axis=-1)), name='output')(digit_caps) model = models.Model(inputs=x, outputs=output) return model ``` 这段代码定义了一个包含两个胶囊层的一维胶囊网络,其中第一个胶囊层包含8个胶囊,每个胶囊的维度为32,第二个胶囊层包含n_class个胶囊,每个胶囊的维度为16。num_routing参数指定了动态路由的迭代次数。输出层使用了Lambda层来计算胶囊输出的范数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值