学界 | 在有池化层、1步幅的CNN上减少冗余计算,一种广泛适用的架构转换方法

选自arXiv

机器之心编译

参与:刘天赐、刘晓坤

CNN 的近邻图像块计算中一般都存在冗余问题,当存在池化层或步幅为 1 时,减少冗余的方法将变得更加复杂。本文中,来自德国 AI 研究中心等机构的研究者提出了一种在有池化层和步幅为 1 时也能有效减少冗余的方法。他们的方法普遍性很强,可应用于几乎全部现有的 CNN 架构上,来实现快速的特征提取。

虽然绝大多数的 CNN 都直接运行在整张图像上,但还有很多重要任务需要使用基于图像块(patch based)的 CNN 来处理:在一个邻近、重叠的图像块上多次运行同一个 CNN。这类问题大多可以归为基于 CNN 的特征提取的范畴 [8, 10],其中包括如摄影机校准、图像块匹配 [2]、光流估计 [1, 5],以及立体匹配 [13]。另一方面,也有一些重要的基于图像块的应用场景,如滑动窗口的物体识别与检测 [7],通常并不会被归为特征提取任务。

所有基于图像块的任务,在近邻的 CNN 计算之间都存在大量冗余,如图 1 所示。如果没有池化层(pooling layer)或步幅等于 1(striding layer),则可以通过在整张图像上运行某个通过有限图像块训练的 CNN 来避免这些计算冗余。但如果存在池化层,情况就会变得很复杂。目前,人们的做法一般是:彻底避免池化层或步幅为 1 [13]、直接使用冗余计算 [5] 或设计出一个也能得到更稀疏结果的方法 [6, 7]。研究者意识到,仅有他们之前的研究 [1] 来尝试避免这一冗余,但也没有详细介绍用于避免冗余的方法。

图 1:左:一个简单的 1 维 CNN。右:如果将此 CNN 运行在图像的每个像素位上,来为每个像素位创造特征,许多中间层结果会在网络之间实现共享。节点上的数字为该节点被共享的次数。红色连接展示了红色节点是如何共享的。步长为 2 的池化减半了输出分辨率。因此,我们需要两个池化层:一个原始的(蓝色)和一个平移了一个像素的(绿色),来避免输出分辨率被减半。

在本文中,研究者展示了一个优美的、可推广的避免冗余计算的方法,存在池化层或步幅为 1 时本方法依然有效。此方法只需要在原始 CNN 层的基础上添加实现转置和重塑(reshape)运算的神经层。这两种运算基本在所有的机器学习框架中都适用。另外,此方法几乎可以在目前所有的 CNN 架构中使用。

论文结构如下:第 2 部分展示相关研究;第 3 部分展示本文的方法;第 4 部分展示该方法的一个基准测试。最后在附录部分,为深度学习框架 Torch 的示例源代码,使本研究的贡献更加清楚易懂。

方法

本文中我们希望将一个 CNN CP(利用图像块 P T 训练得到)迅速高效的运行于输入图像 I 的所有图像块 P(x, y) 上。输出向量 O(x, y) = CP(P(x, y)) 为一个 k 通道向量,属于 (I_h,I_w, k) 维的输出矩阵 O,其中 O 包含了 CP 在所有图像块 P(x, y) 上运行的结果。

图 2:通过本文的方法,从网络 CP 中生成网络 CI。CI 结果和在图像 I 的每个图像块上独立运行 CP 得到的结果相同。但 CI 运行速度更快,因为其避免了重叠图像块上的冗余计算。

图 3 展示了池化的主要问题:不同的图像块 P(x, y) :即使它们本身是直接相邻的,如 P(x, y) 和 P(x+1, y),也需要不同的池化,因此无法共享池化输出。

图 3:图像不同位置的图像块 P(红线表示)。第一个图像块 P(x, y) 需要的图像块 2x2 池化(蓝色)和第二个图像块 P(x + 1, y) 所需的(绿色)不同。但图像块 P(x + 2, y) 则可以再使用第一个池化(蓝色)。P(x, y) 和 P(x + 2, y) 的重叠部分结果相同,因此可以共享(黄色部分)。蓝色图像块和绿色图像块之间无法共享池化。

图 4 展示了 2×2 池化的展开。当存在多个池化层是,直接展开相当复杂。这也许是之前研究避免池化层的一个原因。

图 4:左:来自 2×2 多池化(Multi-pooling)得到的 2×2 = 4 输出图。右:输出 O 的最终展开。

如图 5 所示,需要将将内部的 x 和 y 维传递给右边,并将外部维度传递给左边。

图 5:问题 (x2, x1 +1) = (x2, x1) + 2 和 (x2, x1) = (x2, x1) + 1:内部维度 x1 的步长更大。可以通过转置(交换)两个维度来修复此问题。然后,记忆(memory)的重新解释(重塑)可以将其降低为一个 x 维度。

实验

表 1:CP 和 CI 的速度基准测试。后者的速度明显更快,在更大图像上尤为如此。研究者提供了基准测试的源代码作为补充材料,以满足复现性要求。对于 CP 而言记忆并不是一个大问题(见正文)。

论文:Fast Dense Feature Extraction with CNNs that have Pooling or Striding Layers

论文地址:https://arxiv.org/pdf/1805.03096.pdf

近年,许多研究表明,基于卷积神经网络提取的特征比工程化特征表现更好。但目前还缺少在完整图像上高效提取局部特征的研究。本文展示了一种当存在池化层和步幅为 1 时,对完整图像计算基于图像块的局部特征解释器的高效算法。这是一种通用方法,可以应用于几乎所有的现有神经网络架构。这包含了所有的用于局部特征提取的神经网络,如摄影机校准、图像块匹配、光流估计,以及立体匹配。另外,此方法也可以应用于其他基于图像块的方法,如滑动窗口的物体检测与识别。我们将一个基于 CNN 的特征提取方法运用于整张图像,并给出使用/未使用我们的加速方法下的速度基准测试,以及对应的(Torch)示例代码:这表明任意 CNN 架构都可以轻松地用我们的方法转换。

原文发布于微信公众号 - 机器之心(almosthuman2014)

原文发表时间:2018-05-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端之路

LinkedList源码解读

List中除了ArrayList我们最常用的就是LinkedList了。 LInkedList与ArrayList的最大区别在于元素的插入效率和随机访问效率 ...

19710
来自专栏赵俊的Java专栏

从源码上分析 ArrayList

1181
来自专栏alexqdjay

HashMap 多线程下死循环分析及JDK8修复

1K4
来自专栏MelonTeam专栏

ArrayList源码完全分析

导语: 这里分析的ArrayList是使用的JDK1.8里面的类,AndroidSDK里面的ArrayList基本和这个一样。 分析的方式是逐个API进行解析 ...

4519
来自专栏xingoo, 一个梦想做发明家的程序员

Spark踩坑——java.lang.AbstractMethodError

百度了一下说是版本不一致导致的。于是重新检查各个jar包,发现spark-sql-kafka的版本是2.2,而spark的版本是2.3,修改spark-sql-...

1200
来自专栏拭心的安卓进阶之路

Java 集合深入理解(6):AbstractList

今天心情比天蓝,来学学 AbstractList 吧! ? 什么是 AbstractList ? AbstractList 继承自 AbstractCollec...

19210
来自专栏计算机视觉与深度学习基础

Leetcode 114 Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place. For example, Given...

1958
来自专栏开发与安全

算法:AOV网(Activity on Vextex Network)与拓扑排序

在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称之为AOV网(Activity on Vextex ...

2537
来自专栏拭心的安卓进阶之路

Java 集合深入理解(12):古老的 Vector

今天刮台风,躲屋里看看 Vector ! 都说 Vector 是线程安全的 ArrayList,今天来根据源码看看是不是这么相...

2447
来自专栏desperate633

LeetCode Invert Binary Tree题目分析

Invert a binary tree. 4 / \ 2 7 / \ / \1 3 6 9 to4 / \ 7 2 / \ / \9 6 3 1 Tri...

861

扫码关注云+社区