如何同时满足减少可学习参数的数量以及维持computation/memory access比值?你需要Shift操作。本文将详细介绍shift操作的具体方法、如何剪掉冗余的Shift操作、3种用于深度神经网络加速的Shift操作、如何利用bit-wise的Shift操作避免乘法运算以及如何将Shift的思想应用到加法网络中。 >> 年度盘点:极市计算机视觉资源汇总,顶会论文、技术视频、数据集等(限时开放下载)
在之前的文章中,我们详细介绍了模型压缩中的Slimming操作 以及高效模型设计的自动机器学习流水线 ,本文将非常全面的介绍模型压缩的另一种操作:Shift。
目录
详细讲解3种用于深度神经网络加速的Shift操作。
再进一步的bit-wise的Shift操作, 走向无乘法的神经网络
讲解如何利用bit-wise的Shift操作避免乘法运算。
"移位"Shift操作与加法网络结合,打造适用于边缘设备的ShiftAddNet
1 我们为什么需要Shift操作?
端侧设备 (手机,各种可穿戴设备,自动驾驶,智能机器人等)的功率较低,内存受限。而且,内存之间的通信和计算量也对CNN的功耗有很大的影响。除此之外,如果设备需要和云通信的话(模型更新等),模型的大小也会极大地影响成本。所以,对于端侧设备和物联网设备的推理过程(Inference)来讲,模型的优化,尺寸的缩减,速度的提升和功耗的节约是研究的重点。CNN主要依赖卷积 (Spatial Convolution) 来聚合图像中的空间信息。在神经网络中,卷积核是卷积操作最核心的部分,它也叫滤波器,接收这一层的输入Input,计算出这一层的输出Output。卷积网络计算密集,且模型变大的原因是卷积核引入了高强度的计算量,且使模型参数量急剧上升。在这样的背景下,研究者们设法减少卷积核的大小,进而减少模型的计算量和参数量。其中比较著名的是Depthwise Seperable Convolution ,即深度可分离卷积 。如下图所示,图中对比了深度可分离卷积和常规卷积操作的不同:
假设输入张量 ,其中 代表特征的height和width, 代表特征的channel数。 假设卷积核 ,其中 代表卷积核的kernel size, 分别代表输入特征和输出特征的channel数。 假设输出张量 ,其中 代表特征的height和width(这里假设输入输出的大小一致), 代表特征的channel数。
所以,常规卷积的computation/memory access :
这里需要着重强调的是computation/memory access ,这个值反映了模型计算量与内存大小的比值,比值越大,代表我们把更多的资源倾向于计算,而不是内存访问上;比值越小,则代表我们把更多的资源倾向于内存的访问 (memory access),而这个过程相比计算要耗费更多的能量和更多的时间,使模型延迟 (Latency)上升严重。 这个缺点意味着I/O密集型设备 (I/O-bound device) 将无法实现最大的计算效率。
注: 关于I/O密集型设备 (I/O-bound device)和 计算密集型设备 (CPU-bound device):意思是计算机在处理某个任务的时候,主要时间花在什么地方,就是被什么所“束缚”。比如主要时间消耗在CPU计算上,也就是说处理该任务大部分时间都在等待CPU的计算而不是等待读写(硬盘/内存)数据,那么就是CPU-bound,称之为CPU密集型。反过来如果主要时间消耗在等待读写数据而CPU利用率很低,那么该任务就是I/O-bound,I/O密集型。CPU bound的程序一般而言CPU占用率相当高。这可能是因为任务本身不太需要访问I/O设备,也可能是因为程序是多线程实现因此屏蔽掉了等待I/O的时间。
I/O bound 指的是系统的CPU效能相对硬盘/内存的效能要好很多,此时,系统运作,大部分的状况是 CPU 在等 I/O (硬盘/内存) 的读/写,此时 CPU Loading 不高。
根据以上的注释,我们希望computation/memory access这个值尽量大 ,以更有效率地利用我们的硬件资源。 式中, 代表Depthwise Convolution的卷积核。 式中, 代表Pointwise Convolution的卷积核。
Depthwise Convolution的计算量:
Depthwise Convolution卷积核的参数量:
所以,Depthwise Convolution的computation vs. memory access :
Depthwise Convolution的计算量/内存占用的比值 相比于常规卷积小很多,这意味着Depthwise Convolution将更多的时间花费在内存访问上,这比浮点运算慢好几个数量级 ,并且更消耗能量 。这个缺点意味着I/O密集型设备将无法实现最大的计算效率,使之不容易在硬件设备上实现。 问:为什么更轻量化的深度可分离卷积反而不利于实现最大的计算效率? 答: 因为其内部的Depthwise Convolution的computation/memory access这个比值太低了,换句话说,同样的参数,没有带来同比的计算量。
减少可学习参数 (learnable parameters)的数量。
维持computation/memory access这个比值不变小 。
Shift 操作因此诞生。它的最大特点是:requires zero FLOPs and zero parameters 。这个特点能够同时满足上面的2个要求。这样,Shift 操作维持了computation/memory access这个比值,从而能够很容易地在硬件设备上实现。同时,Shift 操作与其他的模型压缩方法是正交 (orthogonal) 的,即Shift操作可以与其他的压缩方法联合使用。
A和B是正交 (orthogonal)的意思是:使用A方法,不妨碍B方法的使用,换句话说,A和B可以同时使用。
2 如何进行Shift操作?
原文链接:CVPR2018: Shift: A Zero FLOP, Zero Parameter Alternative to Spatial Convolutions
Shift操作可以看做是Depthwise Convolution的一种特殊情况,表达式为: 式中,shift operation的卷积核 的定义为: 这里,你会发现Shift操作与Depthwise Convolution的不同之处在于Shift操作的卷积核的每一个channel中的卷积核 中的 个值,只有一个是1,其他都是0 。这里的 是个索引,告诉我们位于 处的这个值为1,其他 个值为0。 这一步做完以后,和Depthwise Convolution一样,我们在后面接上pointwise convolution来进一步融合channel之间的信息。下图1是Shift操作与常规卷积和深度可分离卷积的对比,图2是做完Shift操作以后,进一步在后面融合pointwise convolution。
图1:Shift操作与常规卷积和深度可分离卷积的对比
图2:Shift操作在空间上调整数据,1×1卷积在通道间混合信息。 我们发现,如下图3所示,shift卷积过程相当于将原输入的矩阵在某个方向进行平移,如图3所示。这也是为什么该操作称之为shift的原因。虽然简单的平移操作似乎没有提取到空间信息,但是考虑到我们之前说到的,通道域是空间域信息的层次化扩散 。因此通过设置不同方向的shift卷积核,可以将输入张量不同通道进行平移,随后配合1x1卷积实现跨通道的信息融合,即可实现空间域和通道域的信息提取。 图3:shift卷积相当于将原输入矩阵在某个方向进行平移 一个卷积核在每一个channel上面有 种可能的shift directions,再假设有 个channel,所以共有 种可能的shift选择 。显然,在这样的空间里暴力搜索出最适合的shift选择是不现实的。所以作者使用了近似的手段,即:把这 个channel分成 组,我们将每个组称之为平移组 (shift group)。那么每组的 个channel使用相同的shift选择,采用相同的平移方向。当然,有可能存在除不尽的情况,这个时候将会有一些通道不能被划分到任意一个组内,这些剩下的通道都称之为“居中”组对输入按通道数进行分组, 每一组通道只往一个方向平移。
举个例子哈,比如现在卷积核是 的,然后一共有64个channel,按照上面的做法我们把这些channel分成9组,每组7个channel,剩下的一个channel不做shift操作。
那么下面的问题是:如何把每个channel正确地划分到对应的组里面? 图4:如何把每个channel正确地划分到对应的组里面? 虽然通过这种手段大大缩小了搜索空间,但是仍然需要让模型学出如何将第个通道映射到第个平移组的最佳排列规则,这仍然是一个很大的搜索空间。为了解决这个问题,以下需要提出一种方法,其能够使得shift卷积层的输出和输入是关于通道排序无关的。 具体来讲,比如现在输入的通道如图4左侧图所示,相同颜色的通道应该归为一组 (此时是最优情况),但是现在我其实是事先告诉你哪些通道应该归为一组,即颜色应该相同。其实你事先是不知道的,即:我们不知道具体哪些通道的颜色是相同的,也就是说,我们不知道具体哪些通道应该归为一组。这时,为了解决这个问题,我们想先通过一个排序 (permutation),使得4个应该分到group 1的channel排到最上面,把4个应该分到group 2的channel排到5-8位置。这样,我们就可以直接把最上面的4个通道归为group 1,再下面的4个通道归为group 2,再下面的4个通道归为group 3,以此类推。shift进行完后,再通过一个排序恢复原来的channel的顺序。但是这样做排序 (permutation)是未知的,我们的目的就是关于通道排序无关的。 假设表示是在以为通道排序的shift卷积操作,则上式(2.1)可以表示为,如果我们在进行该卷积之前,先后进行两次通道排序,分别是和,那么我们有: 上式的意思是:输入特征 先经过一个排序 ,再经过Shift操作 ,再经过一个排序 。 那么,如上文所述,排序 都是未知的。怎么解决这个问题? 答:可以的。 只需要在头和尾加上 卷积即可。为什么?令和分别表示1x1卷积 操作,我们有式子(2.4): 这一点不难理解,即便对1x1卷积的输入进行通道排序重组,在学习过程中,通过算法去调整卷积的参数的顺序,就可以通过构造的方式,实现和之间的双射(bijective)。如式子(2.5)所示,就结论而言,不需要考虑通道的排序,比如只需要依次按着顺序赋值某个平移组,使得其不重复即可。通过用卷积“三明治”夹着shift卷积的操作,从理论上可以等价于其他任何形式的通道排序后的结果。 这样我们就有效地避开了排序 的求解。那么接下来,根据shift算子构建出来的卷积模块如下图所示: 图5:基于shift卷积算子构建的ResNet网络基本模块。 如上图5所示为一个基于Shift操作的模块,先忽略虚线部分,首先输入经过一个pointwise convolution,融合channel维度的信息。然后,是带有Shift操作的卷积核重新分配spatial维度的信息,最后再经过一个pointwise convolution,融合channel维度的信息。这样就形成了1x1 conv -> shift kernel -> 1x1 conv 的结构。所有的pointwise convolution前面都会加上BN和ReLU激活函数 。与此同时,为了形成残差结构,模块还添加了Identity块,如果输入输出的shape是一样的,就直接使用残差即可;如果输入输出的shape是不一样的,就结合downsampling。 蓝色虚线块的Shift块 是实验补充的一个设计,存在虚线部分的shift块的设计称之为结构,只存在实线部分的设计则称之为结构,它可以在下采样之前就结合spatial information。同时,也使用了expansion rate来控制中间层的channel数,因为 卷积计算密集,使得中间层的channel数不能过大。但是使用了Shift操作之后,因为卷积核得到了调整,就可以使中间层的channel数更大。 ShiftResNet的构建是通过把ResNet里面所有的basic module (2个3×3卷积) 替换为图5的 结构。下图6为若我们把ResNet56网络使用Shift操作,并通过调节expansion rate使参数量降低约3倍时的结果,我们发现模型的Accuracy基本没有变化。 下图7展示了3个模型 (ResNet20,ResNet56,ResNet110)的不同参数量 (expansion rate=1,3,6,9)时在2个数据集 (CIFAR-10,CIFAR-100)上的实验结果。Shift算子的确在计算量和参数量上有着比较大的优势。比如说当我们控制参数量或计算量下降8倍左右时,即每组的第一行,那么常规ResNet的性能会大幅地下降,而ShiftResNet的性能下降幅度较小。
图7:不同模型使用Shift操作,在不同参数量级上的结果 如下图8所示为ShiftNet-A的结构,因为参数量并不会随着Shift kernel size的增长而变大,所以在一开始的module里面使用了比较大的卷积5×5。通过调节expansion rate来改变每个CSC module的参数量。下图所示的结构为ShiftNet-A。若把每个CSC模块的channel数变为原来的0.5倍,即得到ShiftNet-B的结构。若在group 1,2,3,4中分别使用{1,4,4,3}个CSC module,channel数分别为{32,64,128,256},expansion rate,kernel size为3,则得到ShiftNet-C的结构。
下图9所示为ShiftNet的3种结构:ShiftNet-A,ShiftNet-B,ShiftNet-C与其他方法的对比,ShiftNet-A,ShiftNet-B,ShiftNet-C对比的对象为具有相似的精度 (Accuracy)的模型。结果发现,在精度相当的条件下,ShiftNet的参数量大幅减少。
下图10所示为不同的网络改造成ShiftNet之后的结果对比,结果表明,ShiftNet模型在精度和参数量/计算量之间提供了很好的trade-off。
图10:ShiftNet模型在精度和参数量/计算量之间提供了很好的trade-off
3 稀疏的Shift操作
原文链接:CVPR 2019: All you need is a few shifts: Designing efficient convolutional neural networks for image classification
我们把CPU称为compute-bound computation platforms,对于这类设备来说,算力是它们的瓶颈。而GPU称为memory-bound computation platforms,对于这类设备来说,内存数据的移动等是它们的瓶颈。然后分别测试以下Shift操作 和Depth-wise convolution 在这两类设备上的运行时间(Runtime)的占比:结果如下图11所示。 图(a)和(b)展示了在ShiftNet(上一小节讲的模型)中,Shift操作分别在在这两类设备上的运行时间(Runtime)的占比,我们发现,Shift操作在CPU上占3.6%的运行时间,但在GPU上占28.1%,这表明由于memory movement,Shift操作在memory-bound computation platforms上仍然占据相当大的运行时间。 图(c), (d)展示了在ShiftNet中,我们仅用深度可分卷积Depthwise separable convolution代替Shift操作来测试其推理时间,得到此时的Depthwise convolution 在GPU上的运行时间(Runtime)的占比。其中,图(c)为使用5×5卷积核的占比,Depthwise separable convolution占了运行时间的79.2%;图(d)为使用3×3卷积核的占比,Depthwise separable convolution占了运行时间的62.1%。 通过以上的对比即可体现出Shift操作 的优越性,即: 对于memory-bound的设备来说,某种操作占用越小份额的运行时间,代表memory movement所需要的时间越短,即这种操作更有利于在memory-bound的设备中实现。
图11:Shift操作和Depth-wise convolution在这两类设备上的运行时间(Runtime)的占比 尽管Shift操作在实际运行时间上优于Depthwise separable convolution,但它的实现仍然存在瓶颈,即上文所述memory movement。这里自然就来了一个问题: 如果消除无意义的Shift操作,那些memory movement可以减少。这也就是本文的motivation。 为了抑制冗余移位操作,作者在优化过程中增加了惩罚。结果发现,一定数目的 Shift操作实际上足以提供空间信息通信。作者将这种类型的移位层称为稀疏移位层(Sparse Shift Layer , SSR),如图11(e)所示,它可以显著减少Shift操作的占用时间。 具体是怎么做的呢?我们先统一下Shift操作的表达:
其中, 角标 表示 channel, 和 分别表示这个channel的横向和纵向的移位数。 和 的参数数量分别相当于输入特征图的通道数,与卷积层的参数相比几乎可以忽略不计。
上节提到的分组Shift操作可以表达为(图12(a)):
式中, 代表第 个channel, 代表分组数, 代表kernel size。
为了使得移位数 和 可学习 , 也有研究者将位移从整数放宽到实数值,并将移位操作放宽到双线性插值,以使其可微,前向传播 的表达式如下所示(图12(b)):即对于输出的每一个channel上的每个点 都会有一个neighbor set ,它包含的是 周围的4个点,之后利用这4个点的值做双线性插值。 但是,这种做法不能带来与Shift操作相同的inference speed的加速,因为插值仍然需要乘法,而标准的移位操作在推理过程中只需要存储器移动。 所以,本文方法是从减小Shift操作的数目开始, 冗余的Shift操作会带来冗余的memory movement,进一步影响神经网络的推理时间。从这一点出发,作者希望以更少的移位操作构建高效的网络。 为了避免无意义的记忆移动,我们在损失函数中加入位移惩罚来消除无用的Shift操作。具体是 使用 正则化, 以惩罚冗余的Shift操作,表达式如下: 但是,因为现在的 和 依然是实数值,所以现在依然需要解决主动Shift操作共性的问题,即利用这4个点的值做双线性插值,插值仍然需要乘法,而标准的移位操作在推理过程中只需要memory movement,所以插值会影响神经网络的推理时间。 所以,作者避开了双线性插值,而是直接把实数值的 和 作近似,如下式所示: 当前向传播使用Active Shift(式3.3)时,即移位数 和 是可学习的参数 时,损失对移位参数的偏导数为: 式中 和 是feature map的spatial size。损失对输入特征的偏导数为:
为了充分地利用每个特征,作者在每次只使用feature map的一个子集用于计算,其他的feature map直接传播到下一层,以确保信息流动,可以表示为下式: 式中, 和 分别代表输入和输出的特征, 表示channel的分离, 表示channel的concatenation。上式的意思是:先把这些输入的feature map的通道进行分离,再将一部分进行运算,另一部分直接传播;最后将得到的结果结合在一起。如下图13所示,以上操作叫做Fully-Exploited computational Block (FE-Block)。随着层数的增加,我们将更多的feature map混合到计算中。这样,每一个输入的特征最终都会被优化,得到多尺度的特征用于预测。
图13:Fully-Exploited computational Block (FE-Block) 其中,黑色的箭头代表基本的运算单元,如下图14所示,其中(a)和(b)分别为不带残差和带残差的运算单元,(c)为下采样的运算单元。expansion rate默认为6,即:1×1卷积先将channel数扩展为6倍。作者主要采用图14(b)作为基本计算单元。对于每个计算块(FE-Block) 的最后一个计算单元,我们使用图14(a)来改变下一个计算块的信道号,或者使用图14(c)来进行空间下采样。
模型:ResNet-20/56,ShiftResNet(GroupedShift)-20/56(上一小节的模型),ShiftResNet(SSL)-20/56。
图15:The analysis of SSL on CIFAR10 and CIFAR100
Grouped Shift vs. Sparse Shift:
通过Shift操作,网络可以根据不同的任务和不同的数据集自适应地调整移位操作的位移和方向。通过偏移惩罚,它可以消除大部分偏移操作,同时保持网络的精度与原始网络相当。即使偏移操作的稀疏度超过90%,该网络仍能保持相当好的性能,这表明只有少量的偏移操作在传递图像分类的空间信息方面起着至关重要的作用。当稀疏度达到100%时,即不再使用Shift操作而只有1×1 convolution时,性能会有明显下降,这也证明了Shift操作的重要性。
Deep Networks vs. Shallow Networks:
当网络由20层变为56层时,Shift操作的冗余度增加了,说明增加深度会给移位层带来更多冗余。
当 从0增大到5e-4时, 发现大部分Shift操作被逐步消除,而网络的精度略有下降。这里的( )实际上相当于量化感知的主动移位Active Shift。当我们显著地增加 ,使得稀疏度达到100%时,这意味着这些基本模块都由1×1 convolution组成,并且网络中只有3个pooling layer提供空间信息通信。在这种情况下,精度下降了很多,这从另一个方面反映了这样的几个偏移对空间信息交流真的很重要。 为了进一步分析部分Shift操作的冗余性,作者继续使用ShiftResNet-20在CIFAR-10/100上进行实验, ,结果如图16所示。作者详细展示了每一层的Shift操作的稀疏性。
图16:CIFAR10和CIFAR100上的ShiftResNet-20 (λ = 0.0005)中各层的shift稀疏度。 解释一下表格数据的含义:Unshifts/Channels(比如93/96)这个指标是指在某个block的某层中的96个channel里面,没有进行移位操作的channel占了93个,说明这93个channel是冗余的,并不重要,那么它的稀疏度就是93/96 = 96.9%。 我们也发现,确实在所有的层中都存在着大量的冗余Shift操作,可以直接剪掉。我们将block2_2进行可视化,结果如图17所示: 图17:在CIFAR100上从ShiftResNet-20的block2_2的偏移层中偏移值的可视化。 可以看到在所有的channel中不移位的channel是最多的,所以点也是最大的。但即使许多的channel选择不移位,剩下的移位的channel仍可以学习有意义的转换模式,并提供多个感受野。实际上,与pointwise convolution配合的移位层优于传统卷积层。 接下来作者直接粗暴地剪掉稀疏度大的layer,结果如下图18所示:
图18:在移除最不重要的偏移层后,ShiftNet-20在CIFAR10和CIFAR100上的性能。 图18为在移除最不重要的偏移层后,ShiftNet-20在CIFAR10和CIFAR100上的性能。可以看出,一共9个layer,我们一次砍掉4个,6个,甚至是只保留稀疏度最低的block 2_2,依然有89.4%/66.0%的精度。但是全部砍掉以后,精度就大幅下降。说明少量重要的Shift操作必须保留,大量冗余的Shift操作可以剪掉。 最后作者把SE 模块 (Squeeze-and-Excitation)操作融合进图14的FE-Block基本运算单元中,产生了2种新的FE-Block基本运算单元,如图19所示。
结果发现,将SE模块放置在 inverted bottleneck部分更为合理。表中的结果从经验上验证了这个想法。此外,我们注意到,在装备SE模块后,Shift操作的稀疏度增加了很多,这可以从另一个角度反映SE模块带来的 channel attention 的作用。
4 给深度神经网络加速的Shift操作
原文链接:WACV 2019:AddressNet: Shift-based Primitives for Efficient Convolutional Neural Networks
本文作者提出了3种基于Shift的操作:channel shift, address shift, shortcut shift来减少GPU上的推理时间,这些操作避免了内存复制(memory copy),所以很快。比如,channel shift的速度要比channel shuffle的速度快12.7倍,但能得到相同的精度。 一个神经网络,拥有较小的参数量 (params.)或计算量 (FLOPs)并不总是导致直接的神经网络推理时间 (inference time)的减少,因为这些最先进的紧凑架构 (compact architecture)引入的许多核心操作不能有效地在基于GPU的机器上实现。
我们举个例子,如下图20所示:
在MobileNet网络中,深度可分离卷积(depthwise separable convolutions)只占了总计算量的3%和总参数量的1%,但是占了总的推理时间的20%。
在ShuffleNet网络中,Channel shuffle 与 shortcut connections操作不占任何参数量和计算量,但是,推理时间却占了总的推理时间的30%。
在上文所讲到的ShiftNet网络中,特征图的 shift操作依旧是parameter-free 和 FLOP-free,但是,推理时间却占了总的推理时间的25%。
虽然MobileNet和ShuffleNet的FLOPs大致相同,但后者需要多两倍的推理时间。
图20:不同操作和模型中计算量、参数数量和推理时间的比较 所以根据上面的现象作者得到结论:无论是减少参数量或者是计算量都不能确保减少推理时间。 这也就是本文Motivation的来源,即:有哪些操作能够既减少参数和计算量,使模型达到压缩的效果,又减少推理时间,使模型达到加速的效果呢? 答:作者为GPU-based machine设计了3种Shift primitive的操作,如下图21所示:
图21:用于高效神经网络架构设计的三种高效Shift primitive (a)表示Channel Shift:用来替代Channel Shuffle的操作。
图22:具有2层卷积的Channel Shuffle和Channel Shift操作 Channel Shuffle非常耗时,因为它需要将特征映射移动到另一个存储空间。请注意,与浮点运算相比,移动数据在延迟和能耗方面要昂贵得多。相比之下,移动指针或加载数据的物理地址是free的。因此,作者提出Channel Shift Primitive来利用指针移位和最小化实际数据移动来减少时间和能量。Channel Shift 层,通道沿预定义的方向循环移位,该过程最多花费两个单位的时间来复制数据,因此memory movement比Channel Shuffle少8倍。 (b)表示Address Shift:有效收集空间信息而不消耗实际的推理时间。 Address Shift是把卷积核沿着4种不同的方向移位,以右移为例:黑色箭头指向feature map的初始地址,右移操作是指把这个地址移动一位,使它指向前面的A, 然后从地址开始在内存空间中连续取张量,相当于将整个张量右移一格。类似地,我们可以定义其他三种不同的移位操作(left,up和down)。
图23:实现4个方向的地址移位,其中A代表相邻要素图的值,黑色箭头表示指向feature map 的 pointer 式中, 是指根据指针 读取对应的地址位置的值, 代表移位的方向。具体而言, 。
图24:Depth-wise Convolution中的右移操作 Address Shift中的右移操作(图23)与上文讲到的Shift操作中的右移操作(图24)十分相似,区别是:Shift操作中的右移操作相当于是padding的值都取为0,而Address Shift中的右移操作的boundary值非0。但是作者通过实验发现, 这种细微差别对网络的准确性没有任何明显的影响。 可能的移位方向的数量相对于kernel size成二次增长(3×3 的kernel:9个可能的方向;5x5的kernel:25个可能的方向)。但是,左上移位 方向也可以分解为左移位+上移位 的形式。随着信道数量的增加,配备地址移位操作的CNNs可以融合来自各个方向的所有信息。因此,我们可以只使用四个基本的移动方向 来表示其他方向,以简化网络架构。 (c)表示Shortcut Shift:通过预先分配连续的存储空间来提供快速的channel concatenation以实现残差,但是不消耗推理时间。 作者通过预先分配一个固定大小的空间,将当前层的输出放在上一层的输出之后。换句话说,可以使两层的输出位于预先分配的连续存储空间中,这样就不会在channel concatenation上花费复制或计算时间。 这些操作只需要在内存空间中移动指针来实现, 以最小化实际内存移动(memory copy),完全避免浮点运算,从而能够实现推理加速。
图25:Address-based模块 and Address-enhanced模块 如图25(a)所示为Address-based模块,首先通过pointwise group convolution layer,然后通过Channel Shift层融合channel之间的信息。再然后是address shift层融合spatial information,并将channel分为3组,对每一组的数据使用4种基本移位操作里的一种。最后再通过pointwise group convolution layer来匹配channel数以及融合信息。如果特征的大小是不变的,就再使用 additive residual connection,否则就使用average pooling + concatenation。 如图25(b)所示为Address-enhanced模块,它进一步把Address Shift和Channel Shift融入第2个pointwise group convolution layer,并把channel分为4组,每一组分别使用一种方向的Address Shift操作,分别是Left,Up,Right,Down。
Channel shift vs. Channel shuffle:
以上二者都可以融合网络不同的通道之间的信息,二者的性能的对比如图26所示。 图26:Channel shift vs. Channel shuffle 上图为2者在相同的参数量(Params.)和计算量(FLOPs)下的性能对比,Total Time指的是模型的平均运行时间,Operation Time指的是这个操作的平均运行时间。两种模型达到了相同的精度,但是Channel shuffle在两个指标上的提速分别达到了1.4倍和12.7倍,显示出这种操作的优越性。
Address Shift vs. Feature map Shift:
基于上面的分析,4种基本的移位操作(Left,Up,Right,Down)可以替代原本的 个操作。所以,作者将第2节中的ShiftResNet中的feature map Shift操作替换为Address Shift操作,得到的网络结构称为AddressResNet,以及只使用4种基本的移位操作替代9个操作( ),比较的结果如下图27所示。
图27:Address Shift vs. Feature map Shift 第1个结果是:无论是使用4种基本的移位操作还是使用全部的9种操作,模型的性能相似。这表明基于四个基本方向的移动操作足以较好地融合空间上的信息。 第2个结果是:当将feature map Shift操作替换为Address Shift操作以后,模型实现了一定程度的加速。 下图28是AddressNet与ShiftResNet在参数量,计算量和推理时间这3个维度的对比。
图28:AddressNet与ShiftResNet在3个维度的对比 与ShiftResNet的最佳精度相比,AddressNet-44可以用少3倍的计算量和少6倍的参数量获得更好的性能。此外,图28(a)和图28(b)中的曲线表明,在不同的参数量和计算量下,AddressNet始终比移位寄存器网络获得更好的精度。在图28(c)中,AddressNet可以显著减少推理时间。
5 再进一步的"移位"Shift操作, 走向无乘法的神经网络
原文链接:Arxiv:Deepshift: Towards multiplication-less neural networks
在上面的工作里面我们是在二维空间上进行Shift的操作,目的是CNN卷积核减少参数量,进而减少整个网络的参数量和计算量。我们让卷积核的每个channel点乘一个one-hot矩阵(只有一个位置为1,其余位置为0),假设有M个channel,shift kernel的可能情况为 种,为了降低搜索空间,对M个channel分组,每个组内采用一个one-shot矩阵。相同的组使用相同的Shift操作,得到了满意的结果。 下面要讲的这篇工作将Shift操作拓展到了bit-wise,即按位进行 。简而言之就是:维持Shift操作的思想,只是把它按位进行。 这个工作的思想其实是来自数字电路中乘法器的实现原理:比如说有一个整数10,我们把它用8位二进制表示为:00001010。对它做乘法时,比如乘以4,其实可以不直接相乘,而是把它按位左移2位:即:00001010→00101000。这样一来,移位实现的乘除法比直接乘除的效率高很多。
用移位实现乘除法运算:
a=a×16;
b=b÷16;
可以改为:
a=a<<4;
b=b>>4;
说明:
除2 = 右移1位 乘2 = 左移1位
除4 = 右移2位 乘4 = 左移2位
除8 = 右移3位 乘8 = 左移3位通常如果需要乘以或除以2的n次方,都可以用移位的方法代替。大部分的C编译器,用移位的方法得到代码比调用乘除法子程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果,如:
答: 我们总结了这样一个结论,即:原数任意乘以一个数其实可以通过原数的移位操作和加法操作 来实现,而不需要直接相乘。且用移位的方法比调用乘除法子程序的计算量低很多。 上面这句话就是这个工作的核心思想,现在我们把它推广到神经网络里面,看看能为我们优化网络,减少运算带来哪些有益的启发。 我们定义一个移位矩阵Shift matrix ,代表每个元素的 值,为整数(integer)。式中 是整数(integer)或定点数(fixed-point)格式。
这里简单讲解下什么是定点数(fixed-point):
定点数(fixed-point number)就是小数点位置固定的数,也就是说,小数点后面的位数是固定的,比如要记录一笔账目,这些账目的数字都不会超过100,就可以使用2位小数位定点数来记录,比如99.99,2.30,75.28;如果要更精确,可以使用3位小数位的定点数来记录,比如7.668,38.235。 存储方式:
第1种方式是对每一个十进制数进行BCD编码 (BCD码(Binary-Coded Decimal),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码),然后加上一个额外的符号位,0表示正数,1表示负数。由于需要使用整数个字节数来存储定点数,所以依据不同情形,符号位可能使用4bit编码,也可能使用8bit编码。如果用4bit编码符号位,加上数值位的bit数刚好是整数字节,那么就用4bit编码编码符号位,否则就用8bit编码符号位。比如,对-9.99编码,由于使用BCD编码9.99需要1.5字节,那么使用4bit编码符号位刚好就可以凑成2字节,编码结果如下:0001 1001 1001 1001;如果对-99.99编码,由于使用BCD编码99.99刚好是2字节,那么对符号位就使用8bit编码,编码结果如下:0000 0001 1001 1001 1001 1001(蓝色部分表示符号位编码,红色部分表示数值位编码)。第2种方式是有一个定点小数的规范。 假设机器字长8 bits,我们规定从左至右,第一位为符号位,接着后5位表示定点小数的整数部分,后两位表示定点小数的小数部分。那么26.5的实际存储形式为01101010。这种情况是可以进行移位的操作的。注意对定点数的编码,不需要对小数点位置进行编码,因为小数点位置是固定的(对同一定点数表示方式来说)。 优缺点:
定点数的优点就是可以精确表示想要表示的数值,不会像浮点数一样计算机内部无法精确的表示一些数值,比如要表示[0,100)之间的任何两位小数,定点数都能精确表示;
定点数的缺点就是不适用于表示特别大或者特别小的数值,比如要表示[0.00000000026,490000000000)之间的任何11位小数,那么就需要使用的字节高达12个(算上符号位)。
在神经网络中,要成的权重也可能为负值,所以再定义取负操作 (sign flip): 我们定义一个符号矩阵Shift matrix ,代表每个元素的符号变化,即是否进行取负操作 。 这样,不论是神经网络的卷积层: 亦或是全连接层: ,我们都可以把乘法运算的过程 用下式来表示: 那么,我们通过上述简单的变换就把神经网络的乘法操作转换为了移位操作和加法操作。把训练神经网络的权重的问题转化为了训练移位矩阵Shift matrix和符号矩阵Shift matrix的问题。 如下图29所示:
图29:神经网络的乘法操作转换为了移位操作和加法操作 问:如何训练移位矩阵Shift matrix和符号矩阵Shift matrix呢? 答:DeepShift-Q 和DeepShift-PS方法。
假设现在有权重 ,我们先把它进行量化得到 ,具体的量化方法是:把它近似为离它最近的2的N次幂。
这样,我们再定义LinearShift operator :
式中, 为损失函数对输出的偏导数; 是损失函数对权重的偏导数。
这样,有了前向传播的方法(5.7-5.8)和反向传播的方法(5.9-5.12),我们就可以正常完成网络的训练过程,如下图30所示:
DeepShift-PS方法直接把移位矩阵Shift matrix 和符号矩阵Shift matrix 作为可训练的参数,按照上面的公式,前向传播的过程和权重的定义是相同的:
至此,有了前向传播的方法(5.13)和反向传播的方法(5.15,5.17),我们就可以正常完成网络的训练过程,如下图31所示: 图31:DeepShift-PS方法网络的训练过程
Train from Scratch:随机初始化权值,并把卷积和全连接的乘法变为移位相加,并使用Deepshift-Q or DeepShift-PS进行训练。
Train from Pre-trained Baseline:先使用32位的浮点数权重进行预训练,继承权重并把权值量化为最接近的2的次幂 (4.5式),再把卷积和全连接的乘法变为移位相加,并使用Deepshift-Q or DeepShift-PS进行训练。
图中的Simple FC: 一个简单的全连接模型,由3个线性层组成,特征输出大小分别为512、512和10。在层间插入了概率为0.2的Dropout层。所有中间层随后都有一个ReLU激活。
图中的Simple CNN: 由两个卷积层和两个线性层组成的模型。两个卷积层的输出通道大小分别为20和50,kernel size大小均为5×5,步长为1。在每个卷积层之后插入窗口大小为2x2的max-pool层,然后进行ReLU激活。线性层的输出特征尺寸分别为500和10。
图34:在ImageNet数据集的结果(只列举了部分)
6 "移位"Shift操作与加法网络结合,打造适用于边缘设备的ShiftAddNet
原文链接:NeurIPS 2020:ShiftAddNet: A Hardware-Inspired Deep Network
加法网络原文链接:CVPR 2020:AdderNet: Do We Really Need Multiplications in Deep Learning?
关于加法网络的详细介绍和原理推导,请参考这篇博客: 解读模型压缩1:轻量化模型设计新思路:加法神经网络的故事 https://zhuanlan.zhihu.com/p/262260391 加法网络的作者研究卷积神经网络中用加法代替乘法的可行性。一般的卷积计算的过程是: 假设我们的卷积核 ,其中 为卷积核的大小,和分别为输入和输出通道数,输入特征为 ,其中 和 为特征的长和宽,输出特征可以被计算为: 上述过程就是最普通的卷积层前向传播的过程,其中是预先定义好的距离度量函数(pre-defined similarity measure)。 CNN中的卷积运算是计算特征和卷积核之间的互相关性 。而这个互相关性 可以理解为一种距离的度量 。因此,卷积运算 也可以看成是距离度量 的一种方式。所以,在我们计算卷积的时候,可以理解为我们在度量特征 与卷积核 之间的距离。但是,距离度量的方式有很多种。 大部分的度量函数都包含乘法,因此带来了大量的计算代价。比如说:当使用互相关作为距离度量时,我们有,此时上面的公式就成为了卷积运算,当 时,公式可以被看做全连接层的计算。 所以,我们理所应当想到:有没有那么一种距离度量的方式,可以避开乘法运算? 谈到距离的度量,你一开始想到的应该是几个范数: -范数, -范数, -范数, -范数等等。而恰好 -范数(以向量的-范数为例): 不涉及乘法运算且也是一种距离度量函数,所以输出的特征可以被重新计算为: 只是把距离度量函数变为了不含乘法运算的 -范数。借助它,我们可以有效地计算卷积核 和特征 之间的相似性 。因此,我们可以只使用加法来提取神经网络中的特征,并构建加法神经网络。 但是传统的卷积神经网络的输出有正有负 ,可是按照上2式计算,输出全是负值 。怎么办? 借助batch normalization ,把输出归一化到一定的范围,并正常在后面使用激活函数。尽管batch normalization涉及乘法运算,但是乘法运算量相比于常规卷积微乎其微 。为什么微乎其微?这里作者给出了量化的对比 :
比如卷积核的尺寸是: ,输入特征为 ,输出特征为 。那么:
卷积层的计算复杂度是:
BN层的计算复杂度是:
假设 ,则二者计算复杂度差距4068倍,故BN层的乘法运算量微乎其微。
读到这里一个很自然的问题是:AdderNet如何进行参数的更新? 看上去相比于常规卷积操作只是改变了度量函数,那反向传播的方法能不能和常规卷积操作进行类比?
这一眼就能看出有问题,符号函数的输出结果只有 这三种情况,也就是说你的梯度也只可能算出来这三个值。这样的梯度更新方式没法在梯度下降的最陡方向更新,且当参数的维度很高时,效果会更差,非常不利于卷积核的优化。 因此,作者考虑使用以 -范数为距离度量的梯度计算公式: 这一步可行的原因是什么?我的个人观点是:改进后的梯度计算公式是以 -范数为距离度量的前向传播的配套的梯度计算方法,如果我们把前文所述的距离度量的方法 替换为-范数,那毫无疑问这种梯度更新方法是可行且收敛的。但现在距离度量的方法 为-范数,当 (收敛)时, ,也收敛。且 更能表达输入特征和滤波器之间的距离大小关系,也更加有利于梯度的优化。
同样的问题,符号函数的输出结果只有 这三种情况,仿照上面的做法,我们考虑使用以 -范数为距离度量的梯度计算公式: 但是,此时输出特征 对于输入特征 的偏导数 计算出的结果的量级可能大于1,当网络很深时,反向传播会导致梯度爆炸。 所以,在对输入特征X求偏导数时,我们对其进行截断: 其中 为 函数,即将输出截断到-1到+1。如果不对X进行截断,多层的反向传播会使得改进梯度的量级和真实梯度的量级有着很大的累计误差,导致梯度爆炸。
以上我们复习了加法网络的基本原理,上节我们介绍了DeepShift,它从硬件设计实践、计算机处理器、甚至数字信号处理中得出一个非常基本的概念:乘法可以通过加法和逻辑位移位来执行,其硬件实现非常简单且更快,而不会损害结果质量或精度。此外,在目前可用的处理器上,位移位指令比乘法指令更快,可用于乘法和除法的。 用一系列的移位和加法 (或减法)来实现常数的乘法 (或除法)。上述的“捷径”节省了算术运算,并且可以很容易地应用于加速任何涉及乘法(标量、矢量或矩阵)的机器学习算法的硬件实现。
仅仅使用Shift操作或者加法网络性能均不如原始的DNN,但将二者结合在一起可以提高网络的性能和表达能力,同时保持硬件效率的优势。
Shift操作属于粗粒度操作,而加法网络属于细粒度的操作,二者的结合甚至有可能产生新的模型,在任务精度方面与基于乘法的DNN相当,同时提供更高的硬件效率。
因此,以上也就是作者的Motivation,即把Shift操作 和加法网络 的思想相结合。 首先我们比较一下在ASIC和FPGA上面,不同的数据格式 (Format)的不同操作 (Operation):乘法,加法和Shift操作 的能耗 (pJ):
图35:在ASIC和FPGA上面:乘法,加法和Shift操作的能耗 (pJ) 我们发现,各种数据格式与它们相应的乘法相比,加法操作和Shift操作可以非常有效,大幅降低能耗。当分别在45nm CMOS和FPGA 中实现时,Shift操作 可以比它们的乘法电路节省高达196倍 和24倍 的能量成本 。此外,对于16 bit的设计,据估计乘法器的平均功率和电路面积 至少分别是Shift操作的9.7倍 和1.45倍 。 尽管Shift操作的硬件效率很高,但就表达效率(expressive efficiency) 而言,Shift操作构建的网络与基于乘法的网络相比是不利的。关于表达效率(expressive efficiency),作者是这样定义的:
从形式上来说,如果B实现的任何功能都可以被A复制,但是存在A实现的功能,除非B的规模显著变大,否则B无法实现。那么架构A的表达效率要高于架构B。
例如,人们普遍认为,与浅层网络(shallow network)相比,Deep network具有更高的表达效率,因为浅层网络必须指数增长才能逼近多项式大小的DNN所表示的函数。
为了便于讨论,作者定义表达能力(expressive capacity) 为:
表达能力是指在相同或相似的硬件成本下网络达到的精度,即如果网络A以相同或甚至更少的浮点运算(或能量成本)为代价达到更高的精度,则认为网络A比网络B具有更好的表达能力。
作者观察到Shift操作在表达能力上不如加法网络和乘法。 总之,Shift操作的特点是硬件效率高,表达能力弱。 加法可以对于 fixed-point 的数据可以比乘法节省高达196倍和31倍的能量成本,当分别在45nm CMOS和FPGA 中实现时,可以比浮点格式的数据节省47倍和4.1倍的能量成本。 目前并没有相关的工作研究加法网络的表达能力 或者表达效率 , 作者通过在各种setting下的实验表明,基于加法的网络通常比基于Shift操作的网络具有更好的表达能力。在ResNet18和ImageNet数据集上,在计算量相当甚至更少的情况下, Addernes的精度比DeepShift高1.37%。而且,在DNN中,学习到的特征细粒度的多样性是另一个对所达到的精度很重要的因素。从这个角度来讲,Shift操作属于粗粒度操作,而加法网络属于细粒度的操作。 以上我们在硬件层面和算法层面这2个方面对比了Shift操作和加法网络。下面是把二者结合起来: 为了更好地验证作者的上述假设(1),即,将两个weak players (Shift操作和加法网络) 集成为一个,与仅具有两个weak players 之一的网络相比,可以得到具有更高的任务准确性和硬件效率,我们采用基于SOTA的Shift操作和加法网络来实现 shift and add layers:
式中, 和 代表输入和输出, 和 是执行inner products(Shift操作)和 范数(加法网络)的核函数。 代表加法网络的权重, 代表Shift层的权重。 为符号位sign flip operators, 为移动的位数,即bit-wise shift。 本质是先进行Shift操作,得到的结果再通过加法网络,如上图所示。 在反向传播过程中,ShiftAddNet采用了SOTA的Shift操作和加法网络的反向传播设计。 简单来说,Shift操作的反向传播参考本文 (5.17) 式,加法网络部分的反向传播参考本文 (6.12) 式。为了查阅的方便,这里再叙述一遍:(6.1) 加法网络部分的前向传播 (依据(6.5)式): 式中, 和 是输入和输出的channel数, 和 是the size of the weight filters。 (6.2) 加法网络的反向传播为 (依据(6.12)式): 在反向传播时我们需要求输出对输入,输出对权值的偏导数,分别如下(6.16)和(6.17)式所示: 这里我们需要将梯度截断到-1到+1,如式(6.17)所示。如果不对X进行截断,多层的反向传播会使得改进梯度的量级和真实梯度的量级有着很大的累计误差,导致梯度爆炸。 ShiftAddNet的加法层的stride始终为1,Shift层的stride可以取与对应的原始卷积网络一致。 以上3式(6.15-6.17)为ShiftAddNet加法网络部分的更新方法,严格按照了 中的前向传播和反向传播方法。 (6.3) Shift部分的前向传播 (依据(5.7)式): (6.4) Shift部分的反向传播 (依据(5.17)式): 是激活函数输出, 为输入, 为权重。式中 的计算要依据(6.17)式。 在反向传播时依旧要求输出对输入,输出对权值的偏导数,只是此时加法网络的输入 是Shift操作的输出 ,即: 。所以输出对权值的偏导数如上(6.19)式所示;输出对输入的偏导数 ,如上(6.17)式所示。 模型和数据集: 作者分别在2种模型和6种数据集上进行了实验,数据集为:CIFAR-10/100,MHEALTH, FlatCam Face, USCHAD, Head-pose detection。模型为:ResNet-20和VGG-19 small。评价指标: 为了评估硬件效率,作者使用了为SOTA FPGA (ZYNQ-7 ZC706)来评估DNN的能量消耗。Baseline有3个: AdderNet[1],DeepShift[5],ConvNet(The lottery ticket hypothesis: Finding sparse, trainable neural networks论文所提出的网络)。ShiftAddNet的前向传播过程(weights and activations)使用FIX32(32位定点数)格式的数据,反向传播过程(error and gradient)使用FIX8(8位定点数)格式的数据。 以上实验的结果如下图37所示:ShiftAddNet无论是在能耗方面还是在精度方面都超过了单纯的Shift操作或者加法网络。全精度的ShiftAddNet甚至是超过了基于乘法的ConvNet。
我们可以发现量化为FP-8的ShiftAddNet的精度相比于FP-32的AdderNet的变化为-1.79%-0.18%,但是节约了65.1%-75.0%的能耗;量化为FP-8的ShiftAddNet的精度相比于DeepShift的变化为2.41%-16.1%,而且节约了34.1%-70.9%的能耗。作者同样对比了在相同的量化精度下(FIX32/16/8)ShiftAddNet的精度和能耗都优于DeepShift和AdderNet。 如下图38所示为ShiftAddNet与DeepShift和AdderNet的训练曲线,根据结果可以得出结论:ShiftAddNet以更少的时期和能量成本实现了相当或更高的精度,这表明它具有更好的泛化能力。
图38:ShiftAddNet与DeepShift和AdderNet的训练曲线 作者也尝试了把Shift layer的参数固定住,只去更新加法网络的参数,得到的结果如下图39所示:
图39:通过在CIFAR-10/100和两个IoT数据集上使用ResNet-20和VGG 19模型,在AdderNet(仅加法操作)、DeepShift(仅移位操作)和基于乘法的ConvNet上测试固定住Shift layer的参数的ShiftAddNet的准确性与能耗成本的关系。 总体而言,与AdderNet(具有浮点或定点精度)和DeepShift相比,ShiftAddNet可以实现高达90.0%和82.8%的节能,同时实现更高的精度(-3.74%-31.2%和3.5%-23.6%)。更有趣的是,把Shift权重固定的ShiftAddNet具有更少的能源消耗,同时对量化的更好的鲁棒性(FIX-8格式的数据取得了10.8%的精度提升)。 作者也对ShiftAddNet中的Shift层进行剪枝,对比不同的剪枝率下的ShiftAddNet的性能,如下图40所示。当剪枝率达到100%时,ShiftAddNet退化为AdderNet。我们可以发现,即使在Shift层被大幅删减的情况下,ShiftAddNet仍能保持其快速收敛的优势。
图40:ResNet-20 网络, CIFAR-10数据集,不同剪枝率下ShiftAddNet的收敛曲线。 最后一个对照试验作者对比了对加法网络层进行剪枝后的性能维持情况,如下图41右侧所示,使用ResNet-20作为主干。当加法网络层的剪枝率由30%→50%→70%→90%时,原AdderNet的性能出现大幅下降,即使稍微修剪AdderNet也会导致精度下降。 图41左侧为第11个add layer中的权重分布。为了更好地可视化,直方图中仅显示非零权重。
图41:左:在ResNet20主干,数据集CIFAR-10上训练的的第11个Adder Layer中的权重分布直方图。右:比较不同剪枝比例下的ShiftAddNet和AdderNet的精度。 我们可以看到,原始的加法网络,即AdderNet,在高剪枝率下不能为权重提供宽的动态范围(权重分布的范围变窄了,但是ShiftAddNet权重的分布范围还是依旧很宽),而ShiftAddNet可以保持一致的宽动态范围的权重。这解释了ShiftAddNet对稀疏化的鲁棒性的提高。图41(c)中的测试精度比较表明,当剪掉add layer层中50%的参数时,ShiftAddNet仍然可以达到80.42%的测试精度,而原始AdderNet的精度下降到51.47%。 [1] CVPR 2020:AdderNet: Do We Really Need Multiplications in Deep Learning? [2] CVPR 2018:Shift: A Zero FLOP, Zero Parameter Alternative to Spatial Convolutions [3] CVPR 2019:All you need is a few shifts: Designing efficient convolutional neural networks for image classification [4] WACV 2019:AddressNet: Shift-based Primitives for Efficient Convolutional Neural Networks [5] Arxiv:Deepshift: Towards multiplication-less neural networks [6] NeurIPS 2020:ShiftAddNet: A Hardware-Inspired Deep Network