卷积之前对于矩阵进行转换_快速卷积Winograd

8044925ffea8dc2fb4000bcd3784d4c7.png

在CNN架构中,大部分时间都是由卷积层消耗的。我们将讨论Winograd算法,它可以将浮点乘法的数量减少2.25倍。请参阅http://arxiv.org/abs/1509.09308。

卷积是如何实现的呢?可能你最简单直观的想法是for循环,但这样的卷积太慢。为了有效利用CPU缓存和参考局部性。(局部参考性也称为局部性原理,是指处理器很有可能会在短时间内重复访问同一组存储器位置。),我们可以将卷积运算转换为矩阵乘法。

1. 更快的卷积算法im2col

我们将展示一种将卷积运算转换为矩阵乘法的方法。这有利于以更多内存使用为代价更快地计算。我们使用im2col操作将输入图像或批处理转换为矩阵,然后我们将此矩阵与reshape的内核相乘。然后在最后,我们使用col2im操作将该相乘后的结果矩阵reshape为图像。

卷积基本上是过滤器内核和移动窗口选择的局部区域(采样)之间的点积,采样的小块(patch)与内核大小是相同的。如果我们在内存上扩展所有可能的窗口并将点积作为矩阵乘法运行,会发生什么。那将可能导致200倍或更多的加速,以更多的内存消耗为代价。(使用BLAS库来执行矩阵乘法,例如CuBLAS(GPU)或Intel MKL(CPU),它们针对矩阵乘法进行了优化。)

effc03f2910fadf22d927c6b2a577fbc.png

例如,如果大小为[227x227x3]步幅4和填充0的输入与11x11x3滤波器进行卷积,那么我们将在输入中采样[11x11x3]像素块并将每个像素块拉伸为大小 11 * 11 * 3 = 363的列向量。

对于具有步幅4和填充0的大小为227的输入,沿宽度和高度会有((227-11)/ 4)+1 = 55个结果位置,得到尺寸为[363×3025]的输出矩阵X_col。这里的每列都是伸展的感受野,总共有55 * 55 = 3025个。

总结一下如何计算im2col输出大小:

[img_height, img_width, img_channels] = size(img);
newImgHeight = floor(((img_height + 2*P - ksize) / S)+1);
newImgWidth = floor(((img_width + 2*P - ksize) / S)+1);        
cols = single(zeros((img_channels*ksize*ksize),(newImgHeight * newImgWidth)));

CONV层的权重以类似的方式伸展成行。例如,如果有96个大小为[11x11x3]的过滤器,则会得到一个大小为[96 x 363]的矩阵W_row(11x11x3 = 363)。

6de65c279dc917aedb8db8b914fb00b6.png

在转换图像和内核之后,卷积可以实现为简单的矩阵乘法,在我们的例子中,W_col [96 x 363]乘以X_col [363 x 3025]得到的矩阵[96 x 3025],最后reshape为[55x55x96]。

ab58f1d50a78df8927681a3e05286e49.png

2. Winograd算法

假设我们有输入图像˚F大小为4和 过滤器大小为3

c0b23108edef1072462e1c3eed355180.png

然后,使用上面介绍的im2col函数将输入图像转换为

6fbbd821a3494428225896ac19dee58b.png

d168849254117cb92d817f431a8f2d96.png

那么,Winograd怎样才能进一步提高速度呢?它舍弃使用点积,而是使用下面的公式计算结果矩阵。

b738ce25c644841596095ac4846aa714.png

也就是,

5a15d22392de489c63d8cb9f48f8e125.png

其中,

5c3f30476cd4635995a42cd29f5243c2.png

这样我们就可以得到m1,m2,m3,m4的值。然后用它们来计算卷积而无需计算矩阵的点积。明显,经过这样的变换后,在每个卷积运算时不需要多次计算(g0 + g1 + g2)/ 2(g0-g1 + g2)/ 2的值,因为滤波器的值是一样的。我们可以在训练网络期间在卷积之前计算一次,并且可以在推理期间预先计算保存。

使用这个算法,我们需要 4次 ADD和4次 MUL操作计算m1,m2,m3,m4,然后基于计算好的m1,m2,m3,m4的值,使用4 个ADD操作得到结果。而在进行普通的点积时,我们将进行6次MUL操作而不是4次。明显Winograd可以将计算成本高昂的MUL操作减少1.5倍,这对速度的提高是非常重要的。

在上面的例子中,我使用了F(4,3),即f(4)g(3),它需要2次卷积。最小1D算法 F(m,r)与其自身嵌套以获得最小2D算法F(mxm,rxr)。如果我们尝试使用f(4,4)g(3,3),这需要4次卷积,Winograd算法使用4 * 4 = 16个MUL,对比普通的卷积使用2 * 2 * 9 = 36个MUL,这样可以将MUL减少2.25倍。

7a084160d96fc4f93a9c0281b21f8302.png

【参考文章】

  1. https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/making_faster.html?source=post_page---------------------------

2. https://medium.com/@dmangla3/understanding-winograd-fast-convolution-a75458744ff

f6350a8c6507d4172e6be05b60d84088.png
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值