本文为 AI 研习社编译的技术博客,原标题 History of Convolutional Blocks in simple Code,作者为 Paul-Louis Pröve。 翻译 | 孟凡 校对 | Lamaric 审核 | Lamaric
我会努力定期去阅读机器学习和人工智能相关的论文。这也是能够持续跟进最新进展的唯一途径。作为一名计算机科学家,我经常在翻阅科学描述文本或者公式的数学符号时碰壁。我发现在普通代码中理解它要容易的多。因此在本文中,我想引导你通过 Keras 实现精选的最新架构的重要卷积块。
当你在 GitHub 上查阅受欢迎的架构实现的时候,你一定会惊讶于他们怎么会包含这么多代码。这是一个很好的包含足够数量的注释并且使用额外参数来增强模型的实践,但是与此同时这会分散架构本质的注意力。为了更加简化和缩短代码,我将使用一些别名函数:
我发现当删除模版代码时更具有可读性。当然,这只有在您理解我的首字母缩写后才有效,让我们开始吧!
瓶颈块
卷积层的参数数量取决于卷积核大小、输入滤波器和输出滤波器的的数量。你的网络越宽,3x3 卷积就会付出更大的代价。
瓶颈块背后的思想是通过一个确定的比率 r 采用代价小的 1x1 卷积来减少通道数,以便随后的 3x3 卷积具有更少的参数。最后,我们在再使用一个 1x1 的卷积拓宽网络。
Inception 模块
Inception 模块引入了并行使用不同操作并且合并结果的思想。因此网络可以学习不同类型的滤波器。
这里我们使用卷积核大小为 1、3 和 5 的卷积层和 MaxPooling 层进行合并。这段代码展示了inception模块的原始实现。实际的实现是将它与上述瓶颈的思想结合起来,这使得它稍微复杂了一些。
Residual 块
ResNet 是一个被来自微软的研究者推出的架构,它允许神经网络拥有他们希望得到的层数,同时仍能够提高模型的准确度。到现在你或许已经习惯它了了,但是在ResNet 之前情况并非如此。
这个想法是将初始的激活添加到卷积块的输出。因此网络可以通过学习过程决定用于输出的新卷积的数量。做的注意的是Inception模块串联输出,而Residual模块是求和。
ResNeXt 块
基于它的名字你就能够猜到ResNeXt与ResNet的密切联系。作者将基数一词云如到另一个维度,比如宽度(通道数)和深度(层数)。
基数(cardinality)是指出现在模块中的平行路径数。这听起来像inception块并行发生的四个操作。然而,并非并行使用不同类型的操作,基数为4时是简单的使用相同操作四次。
如果它们做的是同样的事情为什么还要把他们并列?好问题。这个概念也被称作分组卷积而且可以追溯到原始的AlexNet论文。虽然,当时它主要被用做分解训练过程到多个GPU,而ResNeXt则用他们来增加参数的利用效率。
这个想法是将所有的输入通道分成几个组。卷积只会在它们专属的通道组中进行而不会影响到所有通道组。发型每个组将会学到不同类型的特征,同时提高了权重的效率。
想象一个瓶颈块,首先使用一个为4的压缩率将256个输入通道减少到64个,然后将它们恢复到256个通道作为输出。如果我们想引入基数32和压缩率2,我们将使用32个平行的1x1的卷积层,其每个的输出通道为4(256/(32*2))个。之后我们使用32个拥有4个输出通道的3x3的卷积层,紧接着是32个1x1层,每个层有256个输出通道。最后一步包含将32个平行路径相加,使得在加上初始输入作为一个残差连接之前为我们提供单个输出。
左侧:ResNet块 右侧:参数复杂度大致相同的ResNeXt块
这里有很多东西需要消化。利用上图可以直观了解其如何起作用的,也可以直接复制这些代码,以便自己用Keras构建一个小型网络。我的复杂描述可以用这9行简单的代码总结出来,难道不是很棒吗?
顺便提一下,如果基数与通道的数量相同我们会得到一个称为深度可分离卷积的东西。自从引入了Xception架构以来,得到了广泛的使用。
Dense 块
一个dense块是一个residual块的极端版本,其中每个卷积层都会这个块中之前所有卷积层的输出。首先,我们将输入激活到列表中,之后我们进入一个循环,循环遍历块的深度。以便后续的迭代的到越来越多的输入特征映射。这个方案会持续进行直到达到所需要的深度为止。
虽然的到一个能够像DenseNet一样的出色的架构需要花费数月的研究,但实际的构建模块就是这么简单,令人着迷。
Squeeze-and-Excitation 块
SENet在短时间内是ImageNet的很杰出的架构。它建立在ResNext之上,而且专注于对网络逐个通道的信息进行建模。在常规的卷积层中每个通道对于点积运算中的加法操作有着相同的权重。
Squeeze- and-Excitation块
SENet引入了一个非常简单的模块,它能够加入任何已经存在的架构。它创造了一个小的神经网络,能够根据输入学习每个滤波器的权重。你可以看到它本身并不是卷积块,但是因为它能够添加到任何卷积块中而且能够提高性能,所以我想要将它添加到混合架构中。
每个通道被压缩成一个单值并馈入两层神经网络。根据分布的通道,这个网络会基于重要性加权这些通道,最后这些权重会与卷积激活相乘。
SENet引入了一个很小的计算开销,但是却可能改进任何卷机模型。在我看来,这个块并没有得到应有的重视。
NASNet 标准单元
这就是事情开始变得棘手的地方。我们正在离开人们的空间,提出简单而有效的设计决策并且进去一个设计神经网络架构的算法世界。NASNet在设计方面令人难以置信,但是他的实际架构却相对复杂。我们知道,在他ImageNet的表现是相当的好。
通过手工,作者定义了不同类型的卷积和池化层的搜索空间,每个层都有不同的可能性设置。他还定义了这些层如何平行排列,排列顺序以及怎样加或者串联这些层。一定这样定义,他们就建立了一个基于递归神经网络的强化学习(RL)算法,如果特定的方案设计在CIFAR-10数据集上表现的良好,那么就会得到奖励。
由此产生的架构不仅再在CIFAR-10上表现良好,它也在ImageNet得到了杰出的结果。NASNet由标准单元和还原单元组成,它们彼此重复。
这是你如何在Keras中使用标准单元的代码。除了层的组合和设置非常好用之外没有什么新的东西。
倒置残差块
到现在为止你已经听说了瓶颈块和可分离卷积。让我们把它们放在一起。如果你运行过一些测试你或许会注意到可分离卷积已经减少路参数数量,压缩它们可能会损害性能,而不是增加性能。
作者们提出了一个和瓶颈残差块恰恰相反的想法。他们通过一个代价小的 1x1 卷积增加通道的数目,因为后续的可分离卷积层已经大量的减少了参数的数目。它将在把通道加到初始激活之前降低通道数。
这个难题的最后一部分是可分离卷积层后面没有激活函数。相反,它直接添加到输入层中。这个块在放入架构时非常有效。
AmoebaNet 标准单元
AmoebaNet的标准单元
利用AmoebaNet,我们可以在 ImageNet 上获得很棒的结果,或许在图像识别领域也是如此。就像 NASNet,它是使用与以前一样的搜索空间算法设计的。唯一的不同是他们没有采用强化学习算法而是采用了通常被称为进化的遗传算法。但是,详细了解其如何工作的超出了本文的范围。故事的结局是通过进化,作者能够找到一个相对于NASNet有更少的计算成本的更好的解决方案。这是第一个能够在ImageNet上Top-5准确率达到 97.89% 的单一架构。
查看代码可知,这个块不会添加你没看到过的任何新的东西,你为什么不去基于这个图片尝试实现用这个新的标准单元去看看你是否能够跟进呢?
结论
我希望这篇文章能让你对这些重要的卷积块有深刻的理解,并且知道,实现它们可能比你想象的要容易。 要更详细地了解这些架构,请查看各自架构对应的论文。你会注意到,一旦你掌握了论文的核心理念,就会更容易理解其余部分。还请注意,实际的实现通常会将批标准化添加到混合层中,并且在应用激活函数的位置方面会有所不同。 请在评论中针对本问题尽情发言。
注:我正在考虑用简单的代码创建一个包含所有这些块和体系结构的存储库。 这会对你们当中有些人会有所帮助吗?
原文链接:
https://towardsdatascience.com/history-of-convolutional-blocks-in-simple-code-96a7ddceac0c