转载:【AI系统】Winograd 算法
在上一篇文章的介绍中,介绍了 Im2Col 技术,它通过将三维张量重新排列成矩阵形式,然后利用基于内存访问局部性的优化库如 GEMM(通用矩阵乘法库)加速计算。随后,还探讨了空间组合优化,这一种利用局部性原理来提升效率的技术。
在本文将重点介绍 Winograd 优化算法,它是矩阵乘优化方法中 Coppersmith–Winograd 算法的一种应用,按照 Winograd 算法的原理将卷积的运算进行转换,从而减少卷积运算中乘法的计算总量。其主要是通过将卷积中的乘法使用加法来替换,并把一部分替换出来的加法放到卷积权重的提前处理阶段中,从而实现卷积计算的加速。Winograd 算法的优化局限于一些特定的常用卷积参数,这限制了其在更广泛场景下的应用。尽管存在这些局限性,Winograd 算法仍然是深度学习领域中的重要优化手段之一,对于提高卷积神经网络运行效率具有显著作用。
Winograd 算法原理
Winograd 算法最早是 1980 年由 Shmuel Winograd 提出的《Arithmetic complexity of computations》,当时并没有引起太大的轰动。在 CVPR 2016 会议上,Lavin 等人在《Fast algorithms for convolutional neural networks》中提出了利用 Winograd 加速卷积运算,于是 Winograd 加速卷积在算法圈里火了起来,并从此 Winograd 算法在包括 Mindspore Lite,MMN 等推理引擎中被广泛应用。
那 Winograd 为什么能加速卷积运算呢?简单来说就是用更多的加法计算来减少乘法计算,从而降低计算量,接下来就进一步了解如何使用 Winograd 加速卷积运算。
加速一维卷积计算
以一维卷积
如果是使用一般的矩阵乘法进行计算,则如下式所示,会进行 6 次乘法操作与 4 次加法操作。
具体的过程可以由下图了解到,在卷积的计算过程中,由于在卷积层的设计中,往往卷积的步幅(Stride)的大小会小于卷积核的大小,所以最后转换的矩阵乘中往往有规律的分布着大量重复元素,比如这个一维卷积例子中矩阵乘输入矩阵第一行的
在 Winograd 算法中则是通过增加加法操作来减少乘法操作从而实现计算加速,具体操作如下式所示:
其中,
因为在推理阶段卷积核上的元素是固定的,所以上式
而 Winograd 加速卷积计算的具体推导过程如下,由上面的式子可以得知:
其中,因为
同理,也对
由最初的(5)(6)式与上式可以得知,如果同时在
同理,如果给
将上面的计算过程写成矩阵的形式如下:
其中,
表示 element-wise multiplication(Hadamard product),即对应位置相乘操作; 表示卷积核; 表示输入特征图(输入信号); 表示卷积核变换矩阵,尺寸为 ; 表示输入变换矩阵,尺寸为 ; 表示输出变换矩阵,尺寸为 ; 表示输出尺寸, 表示卷积核尺寸, 表示输入尺寸。
式子中各个矩阵具体的值如下:
加速二维卷积计算
将一维卷积
其中,
对于二维卷积,可以先将卷积过程使用 img2col 进行展开,将卷积核的元素拉成了一列,将输入信号每个滑动窗口中的元素拉成了一行,变成如下的矩阵乘的形式:
然后,将上述的矩阵乘的形式进行如下图的分块:
即可以表示成如下类似于前文中 Winograd 加速一维卷积计算形式:
当然,变成了这样的形式就可以使用前文的推导方法,推导到出式(8)中的 Winograd 加速二维卷积计算的矩阵形式。
Winograd 实现步骤
基于上文的介绍,Winograd 算法的实现可以细分为四个主要步骤:
- 对输入卷积核的变换:
,其中 表示为卷积核变换矩阵, 表示卷积核 - 对输入数据的变换:
,其中 表示为输入数据的变换矩阵, 表示输入的特征图 - 对中间矩阵 M 的计算:
- 卷积结果的计算:
,其中 表示输出变换矩阵
Winograd 算法的工作流程可以用以下图示来说明:
以上文中 Winograd 加速二维卷积
如下图所示,在输入卷积核的转换过程中,首先通过 Winograd 算法中的卷积核变换矩阵
如下图所示,在输入数据的转换过程中,首先将输入数据切分成
如下图所示,将上述转换得到的卷积核权重矩阵
随后,将相同位置的 16 个点重新排布成
算法约束与缺点
从上述方法的介绍中可以得知,Winograd 算法通过减少乘法操作的次数,有效降低了计算资源的消耗,从而提高了计算速度。尽管 Winograd 算法在加速卷积运算方面有明显优势,但同时也存在一些局限性和不足之处。
首先,当应用 Winograd 算法处理单个小局部的二维卷积时,该算法不能直接应用于这样的计算当中,因为产生的辅助矩阵规模过大,可能会对实际效果产生负面影响。另外,不同规模的卷积需要不同规模的辅助矩阵,实时计算出这些辅助矩阵不现实,如果都存储起来会导致规模膨胀。
Winograd 算法虽然通过减少乘法次数来提高计算速度,但加法运算的数量却相应增加,同时还需要额外的转换计算和存储转换矩阵。随着卷积核和分块尺寸的增大,加法运算、转换计算和存储的开销也随之增加。此外,分块尺寸越大,转换矩阵也越大,计算精度的损失也会进一步加剧。因此,Winograd 算法仅适用于较小的卷积核和分块尺寸。在实际工程应用中,Winograd 算法通常只用于处理一些特定的
在实际应用中,通常会将所有可以固定的数据在网络运行前预先确定。在算法程序的设计中,希望尽可能提前计算出可以固定的数据,因此会有一个预编译阶段或离线模块转换阶段,以便提前计算出一些可预知的结果。在推理引擎中,主要处理的是一些常见或通用的算法问题,以及一些通用的网络模型结构。对于一些特定的网络模型结构,如果
另一个想法是将 Winograd 算法与空间组织算法结合起来,充分利用局部性和算法分析的优化,将卷积计算通过空间组合优化算法中的拆分方法,将输入拆分成若干个小规模卷积。例如,可以拆分成每个小卷积输出
如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端