从winograd原理到实现及汇编优化

一、预备知识

1.1 卷积操作

卷积的基本操作就是这样的:这仅是单通道的计算,多通道类似。

基本卷机操作

1.2 img2col

思路:

  • 首先,为啥要有这玩意?
  • 其次,这玩意是怎么做的?
  • 最后,这玩意有啥优缺点?边界在哪?

1.2.1 为什么要造出img2col来? 或者说造这玩意的目的是啥?

这个概念是在卷积的实现很粗糙的背景下提出来的,不信你看这个链接,里面是关于caffe框架的作者对他们卷积实现的吐槽,说当时是在很短的时间内要做出这个框架,所以就以一个学生水平的代码来实现的,他的原始实现方式如下:

Loosely speaking, assume that we have a W*H image with depth D at each input location. For each location, we get a K*K patch, which could be considered as a K*K*D vector, and apply M filters to it. In pseudocode, this is (ignoring boundary conditions):

for w in 1..W
  for h in 1..H
    for x in 1..K
      for y in 1..K
        for m in 1..M
          for d in 1..D
            output(w, h, m) += input(w+x, h+y, d) * filter(m, x, y, d)
          end
        end
      end
    end
  end
end

哈哈哈哈哈哈。。。。

等等。。。作者当时是博士第三年,还上了Berkeley's CS267 (parallel computers)课程,并在课程设计中针对两层做过了最优设计的男人~我哪来的自信哈哈哈?!


咳咳。。。

好,我们现在严肃回来!

你现在问我为什么么要造img2col这玩意出来?我只能告诉你:

这当然是为了优化卷积运算咯!

1.2.2 img2col的实现原理是啥?

你看我们原来的图像是这样的:

按照二维存储的话,假如我们是3X3的卷积核同时图像比较大的时候(内存地址的stride > cache line size),那么我们的小cache哟,那可是受不了的!

什么?你问为什么cache受不了?

嗯。。。。简单来说就是不满足cache空间局部性原理,更细致的原因可以去找一个cpu的新片手册,读一下cache那章,在cache line那个地方就有讲。

于是很自然的,我们想可不可以直接把这些跨度很大的内存单元提前放到一个连续的内存单元里来,这样子的话我们的cache hit rate会大大提高。

于是img2col就是干这个活的。

这里得说明一下: col并不一定是表示列哟,不同平台下实现方式不一样的额,如matlab是按列来的,但是caffe却是按照行来存的,其目的都是一样的,都是为了加速内存访问

这里懒得画了,借用图片一下(图片来源自这):

你看,每一步的卷积都提前给转换好,放到连续的内存中来。

点评:你看吧,瞎子都看出来了,有大量的冗余内存单元被放进来了,这就是典型的空间换时间的例子。

再捋一下:
你看下图示一张图,在卷积前先给加一层padding,然后开始卷积;

正常情况下左上角的绿色框就是要被卷积的,但是由于cache特性不好,所以我们给转一下,把这这三组(每组3个内存)不连续内存转成右图绿色框中那种形式,成为一列,这样在内存中就有办法搞成连续的内存地址了。

好了,目标定好了,那么我们怎么设计转换算法?

其实我也不会设计,就是看caffe的源码实现是按行来的,如图中的红色蓝色框所示,以这种间隔的方式按行存储原始数据,最终得到的就是每个卷积区域都转换成一列了,也就是线性的了

1.2.3 img2col的优缺点

  • 优点
    cache性能好很多了哟~

  • 缺点
    很明显啊,内存占用大大增加了啊,上图中原始图大小是7x7,转换后为9x9,也就是说内存占用多了65%啊!

这部分最后加上作者在Berkeley演讲时的ppt作为小结:


下面表示整个输入的feature map的卷积区域给连续展开了,转换成一个(HxW)x(CxKxK)的矩阵;
这里需要理解的是KxK:

  • 我们之前是CxHxW视角,也就是先看一整个面HxW,然后再看深度C,也就是 C个HxW平面。
  • 后面是以HxW面中的一小块区域(KxK)为坐标,然后加上深度信息,这样才构成一个基本的步进单元。解读为 HxW个CxKxK立方体

最后一页没画,但是基本上就是Filter Matrix乘以Feature Matrix的转置,得到输出矩阵Cout x (H x W),就可以解释为输出的三维Blob(Cout x H x W)。

第一部分附录:

图片来源:https://blog.csdn.net/lanchunhui/article/details/74838635

全连接
卷积
三维卷积输出的是二维feature map
按 [kernel_height, kernel_width, kernel_depth] ⇒ 将输入分成 3 维的 patch,并将其展成一维向量
此时的卷积操作就可转化为矩阵乘法

二、winograd原理

2.1 先·宏观来看

Strassen算法仅仅比通用矩阵相乘算法好一点,因为通用矩阵相乘算法时间复杂度是:

而Strassen算法复杂度只是:

但随着n的变大,比如当n >> 100时,Strassen算法是比通用矩阵相乘算法变得更有效率。

根据wikipedia上的介绍,后来Coppersmith–Winograd 算法把 N* N大小的矩阵乘法的时间复杂度降低到了:

而2010年,Andrew Stothers再度把复杂度降低到了:

一年后的2011年,Virginia Williams把复杂度最终定格为:

三、winograd实现

在ncnn的convolution_3x3.h文件中conv3x3s1_winograd64_neon4(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel_tm, const Mat& _bias) 实现了winograd算法。

步骤如下:

  • 首先把输出通道按照6x6的大小做补齐,使得整体的大小为6x6的整数倍,填充后的输出再加一层padding。

  • 第二步就是处理底层feature map层了。
    //把底层复制成扩展后的输出层+边的大小,空出来的地方填充V值。
    copy_make_border(bottom_blob, bottom_blob_bordered, 0, h - bottom_blob.h, 0, w - bottom_blob.w, 0, 0.f);

  • 第二步就是处理底层feature map层了。

    • 首先把输出做tile操作,也就是把每个6x6扩大到8x8,此时得到w_tm = outw / 6 * 8、h_tm = outh / 6 * 8

四、winograd汇编性能优化

待续。。。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容