卷积优化方法之Winograd

在卷积神经网络当中, 卷积运算是尤其是计算敏感的, 尤其是在端上设备中, 对于性能的要求更为苛刻。对于卷积优化的方法也有很多种,本文便针对近年来最常见的优化方法Winograd做一个简单总结。

相关资料

winograd算法最早是1980年由Terry Winograd提出的,当时并没有引起太大的轰动。在CVPR'16会议上,Lavin等人[1]提出了利用winogrd加速卷积运算,于是winograd加速卷积优化在算法圈里火了一把。网上较多的实现版本为andravin实现的py版本[2]。目前cudnn中计算卷积就使用了该方法。

[1] "Fast Algorithms for Convolutional Neural Networks" Lavin and Gray, CVPR 2016.
[2] https://github.com/andravin/wincnn

算法

在winograd算法下,对于一维卷积,当输出为m,卷积核长为r,要对应的乘法数量:
\[ u(F(m,r)) = m+r+1 \]
将一维卷积扩展到二维,如果输出维度为mxn,卷积核维度为rxs,则对应的乘法数量:
\[u(F(m * n,r * s)) = u(F(m,r)) * u(F(n,s)) = (m+r-1) * (n+s-1) \]

对一个矩阵大小为4 * 4的输入,卷积核大小为3 * 3,对应的输出为2 * 2,正常计算的情况下,滑动窗口或者im2col的计算方法的乘法次数为2*2*3*3 = 36次,而当使用winograd时,对应的乘法次数为$ u(F(2*2,3*3)) = (2+3-1) * (2+3-1)=16 $,乘法次数明显减少。

假设对应的一维输入为[d0,d1,d2,d3],对应的卷积为[g0,g1,g2],对应的输出为[m0,m1,m2],那么:
\[ F(2,3) = \begin{bmatrix}d0 & d1 & d2\\\\d1 & d2 &d3\end{bmatrix} \begin{bmatrix}g0\\\\g1\\\\g3\end{bmatrix} = \begin{bmatrix}m1+m2+m3\\\\m2-m3-m4\end{bmatrix}\]

其中:
\[ m1 = (d0-d1)g0 \]
\[m2 = 0.5(d1+d2)(g0+g1+g2)\]
\[m3 = 0.5(d2-d1)(g0-g1+g2)\]
\[m4 = (d1-d3)g2\]

这种计算方式需要2+3-1=4次乘法,4次加法。写成矩阵乘法的形式即为:
\[ Y = A^T \left[\left[Gg\right] \odot \left[B^Td\right]\right] \]

其中$ \odot $表示 element-wise multiplication. 对于F(2,3),以上矩阵分别为:

\[ B^{T}=\begin{bmatrix} 1 &0&-1 &0 \\ 0&1 &1 &0 \\ 0&-1 &1 &0 \\ 0& 1& 0& -1 \end{bmatrix} \]

\[ G=\begin{bmatrix} 1 & 0 & 0\\ 0.5& 0.5 &0.5 \\ 0.5& -0.5 &0.5 \\ 0& 0 &1 \end{bmatrix} \]

\[ A^{T}=\begin{bmatrix} 1 & 1 & 1 & 0\\ 0 & 1& -1 & -1 \end{bmatrix} \]

\[ g=\begin{bmatrix} g_{0} &g_{1} &g_{2} \end{bmatrix}^{T} \]

\[ d=\begin{bmatrix} d_{0} &d_{1} &d_{2}&d_{3} \end{bmatrix}^{T} \]

扩展为二维的形式即为:

\[ Y = A^T \left[\left[GgG^T\right] \odot \left[B^TdB\right]\right]A \]

注意

  1. 以上描述的 Winograd 算法只展示了在二维的图像 (更确切的说是 tile) 上的过程, 具体在 ConvNet 的多个 channel 的情况, 直接逐个 channel 按照上述方法计算完然后相加即可;
  2. 按照 1. 的思路, 在计算多个 channel 的时候, 仍然有可减少计算次数的地方.
  3. 按照 2. 的思路, Winograd 在目前使用越来越多的 depthwise conv 中其优势不明显了.
  4. 在 tile 较大的时候, Winograd 方法不适用, 因为, 在做 inverse transform 的时候的计算开销抵消了 Winograd 带来的计算节省.
    Winograd 会产生误差

[winograd]winograd算法在卷积中的应用的更多相关文章

  1. 任意半径局部直方图类算法在PC中快速实现的框架。

    在图像处理中,局部算法一般来说,在很大程度上会获得比全局算法更为好的效果,因为他考虑到了图像领域像素的信息,而很多局部算法可以借助于直方图获得加速.同时,一些常规的算法,比如中值滤波.最大值滤波.最小 ...

  2. 06 - 从Algorithm 算法派生类中删除ExecuteInformation() 和ExecuteData() VTK 6.0 迁移

    在先前的vtk中,如vtkPointSetAlgorithm 等算法派生类中定义了虚方法:ExecuteInformation() 和 ExecuteData().这些方法的定义是为了平稳的从VTK4 ...

  3. 1145: 零起点学算法52——数组中删数II

    1145: 零起点学算法52--数组中删数II Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 293 ...

  4. KMP算法 --- 在文本中寻找目标字符串

    KMP算法 --- 在文本中寻找目标字符串 很多时候,为了在大文本中寻找到自己需要的内容,往往需要搜索关键字.这其中就牵涉到字符串匹配的算法,通过接受文本和关键词参数来返回关键词在文本出现的位置.一般 ...

  5. 剑指Offer——算法复杂度中的O(logN)底数是多少

    剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...

  6. AES加解密算法在Android中的应用及Android4.2以上版本调用问题

     from://http://blog.csdn.net/xinzheng_wang/article/details/9159969 AES加解密算法在Android中的应用及Android4.2以上 ...

  7. tarjan算法-解决有向图中求强连通分量的利器

    小引 看到这个名词-tarjan,大家首先想到的肯定是又是一个以外国人名字命名的算法.说实话真的是很佩服那些算法大牛们,佩服得简直是五体投地啊.今天就遇到一道与求解有向图中强连通分量的问题,我的思路就 ...

  8. 利用“海底捞算法”在MongoDB中优雅地存储一棵树

    目前常见的树形结构数据库存储方案有以下四种,但是在处理无限深度.海量数据的树结构时,都存在一些问题: 1)Adjacency List(邻接表):每个节点仅记录父节点主键.优点是简单,缺点是访问子树需 ...

  9. 图像处理之优化---任意半径局部直方图类算法在PC中快速实现的框架

    在图像处理中,局部算法一般来说,在很大程度上会获得比全局算法更为好的效果,因为他考虑到了图像领域像素的信息,而很多局部算法可以借助于直方图获得加速.同时,一些常规的算法,比如中值滤波.最大值滤波.最小 ...

随机推荐

  1. [HNOI2010]城市建设

    [HNOI2010]城市建设 玄学cdq O(nlog^2n)的动态最小生成树 其实就是按照时间cdq分治+剪枝(剪掉一定出现和不可能出现的边) 处理[l,r]之间的修改以及修改之后的询问,不能确定是 ...

  2. dgraph实现基本操作

    dgraph实现基本操作 简单介绍 dgraph 是一个分布式图数据库 mutate 为一个突变, 一般认为添加数据或者是删除数据为一个突变 query 为一个查询 golang实现dgraph的基本 ...

  3. 一、TensorFlow的简介和安装和一些基本概念

    1.Tensorflow的简介 就是一个科学计算的库,用于数据流图(张量流,可以理解成一个N维得数组). Tensorflow支持CPU和GPU,内部实现了对于各种目标函数求导的方式. 2.Tenso ...

  4. crm 一级菜单排序,二级菜单选中并且展开,非菜单权限的归属,权限粒度控制到按钮级别

    排序 /rbac/templatetags/rbac.py from django import template from django.conf import settings import re ...

  5. sass补充(2019-3-9)

    @each 输出 格式: @each $var in value,value1,value2{ } eg: @each $var1 in 100px,200px,300px{ .box{ width: ...

  6. pthread mutex 进程间互斥锁实例

    共享标志 定义 名称 描述 0 PTHREAD_PROCESS_PRIVATE 进程内互斥锁 仅可当前进程内共享 1 PTHREAD_PROCESS_SHARED 进程间互斥锁 多个进程间共享 第一个 ...

  7. 一秒钟带你走进P图世界-----(python)PIL库的使用

    python-----PIL库的使用 一.什么是PIL库 1.PIL(Python Image Library)库是python语言的第三方库,具有强大的图像处理能力,不仅包含了丰富的像素.色彩操作功 ...

  8. tensorflow 莫烦教程

    1,感谢莫烦 2,第一个实例:用tf拟合线性函数 import tensorflow as tf import numpy as np # create data x_data = np.random ...

  9. LeetCode第二十三题-合并n个有序链表

    Merge k Sorted Lists 问题简介:合并k个已排序的链表并将其作为一个排序链表返回. 举例: 输入: [ 1->4->5, 1->3->4, 2->6 ] ...

  10. 预攻击 局域网 Windows 查看其它在线设备

    环境:win10 首先我发现,一个常用的命令用不了,如图: net view 按理来说,按Enter键之后显示应该出局域网内所有正在运行的电脑:(截图来自百度) 那么我试一下另外一个办法: 首先ipc ...