Winograd,GEMM算法综述(CNN中高效卷积实现)(上)
? ? ? ? ? ? ? ? ? ? ? ?高效卷積實現(xiàn)算法和應(yīng)用綜述(上)
在下一篇文章會介紹Winograd算法的應(yīng)用,在ICLR,CVPR,FPGA,FCCM等機器學(xué)習(xí)和FPGA領(lǐng)域的定會上的研究實現(xiàn)和新的突破。下一篇理論分析鏈接。https://blog.csdn.net/qq_32998593/article/details/86181663
摘要:
首先要說明的是,卷積是指ConvNet中默認(rèn)的卷積,而不是數(shù)學(xué)意義上的卷積。其實,ConvNet 中的卷積對于與數(shù)學(xué)中的 cross correlation。
計算卷積的方法有很多種,常見的有以下幾種方法:
滑窗:這種方法是最直觀最簡單的方法。 但是,該方法不容易實現(xiàn)大規(guī)模加速,因此,通常情況下不采用這種方法(但是也不是絕對不會用,在一些特定的條件下該方法反而是最高效的)。
im2col:目前幾乎所有的主流計算框架包括 Caffe, MXNet 等都實現(xiàn)了該方法. 該方法把整個卷積過程轉(zhuǎn)化成了GEMM過程,而GEMM在各種 BLAS 庫中都是被極致優(yōu)化的,一般來說,速度較快。
FFT:傅里葉變換和快速傅里葉變化是在經(jīng)典圖像處理里面經(jīng)常使用的計算方法,但是,在 ConvNet中通常不采用,主要是因為在 ConvNet 中的卷積模板通常都比較小,例如?3×3?等,這種情況下,FFT 的時間開銷反而更大,所以很少在CNN中利用FFT實現(xiàn)卷積。
Winograd: Winograd 是存在已久最近被重新發(fā)現(xiàn)的方法,在大部分場景中, Winograd方法都顯示和較大的優(yōu)勢,目前cudnn中計算卷積就使用了該方法。
高效卷積算法之一:
1. BLAS簡介
BLAS(Basic Linear Algebra Subprograms)是一組線性代數(shù)計算中通用的基本運算操作函數(shù)集合[1] 。BLAS庫中函數(shù)根據(jù)運算對象的不同,BLAS庫中函數(shù)根據(jù)運算對象的不同,分為3個level。
Level 1 函數(shù)處理單一向量的線性運算以及兩個向量的二元運算。Level 1 函數(shù)最初出現(xiàn)在1979年公布的BLAS庫中。
Level 2 函數(shù)處理 矩陣與向量的運算,同時也包含線性方程求解計算。 Level 2 函數(shù)公布于1988年。
Level 3 函數(shù)包含矩陣與矩陣運算。Level 3 函數(shù)發(fā)表于1990年。
PGEMM是Level 3中的庫,其中函數(shù)的語法和描述為:
- Description: matrix matrix multiply
- Syntax: PGEMM( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
- P: S(single float), D(double float), C(complex), Z(complex*16)
詳情可以去BLAS的官方文檔查詢這個卷積實現(xiàn)算法。
向量和矩陣運算是數(shù)值計算的基礎(chǔ),BLAS庫通常是一個軟件計算效率的決定性因素。除了BLAS參考庫以外,還有多種衍生版本和優(yōu)化版本。這些BLAS庫實現(xiàn)中,有些僅實現(xiàn)了其它編程語言的BLAS庫接口,有些是基于BLAS參考庫的Fortran語言代碼翻譯成其它編程語言,有些是通過二進(jìn)制文件代碼轉(zhuǎn)化方法將BLAS參考庫轉(zhuǎn)換成其它變成語言代碼,有些是在BLAS參考庫的基礎(chǔ)上,針對不同硬件(如CPU,GPU)架構(gòu)特點做進(jìn)一步優(yōu)化。
幾個比較著名的基于BLAS庫開發(fā)的高級庫包括:
Intel? Math Kernel Library
Intel? Math Kernel Library (Intel? MKL) accelerates math processing and neural network routines that increase application performance and reduce development time. Intel MKL includes highly vectorized and threaded Linear Algebra, Fast Fourier Transforms (FFT), Neural Network, Vector Math and Statistics functions. The easiest way to take advantage of all of that processing power is to use a carefully optimized math library. Even the best compiler can’t compete with the level of performance possible from a hand-optimized library. If your application already relies on the BLAS or LAPACK functionality, simply re-link with Intel MKL to get better performance on Intel and compatible architectures.
cuBLAS
The NVIDIA CUDA Basic Linear Algebra Subroutines (cuBLAS) library is a GPU-accelerated version of the complete standard BLAS library that delivers 6x to 17x faster performance than the latest MKL BLAS.
clBLAS
This repository houses the code for the OpenCL? BLAS portion of clMath. The complete set of BLAS level 1, 2 & 3 routines is implemented.
2. GEMM分析
GEMM在深度學(xué)習(xí)中是十分重要的,全連接層以及卷積層基本上都是通過GEMM來實現(xiàn)的,而網(wǎng)絡(luò)中大約90%的運算都是在這兩層中。而一個良好的GEMM的實現(xiàn)可以充分利用系統(tǒng)的多級存儲結(jié)構(gòu)和程序執(zhí)行的局部性來充分加速運算。
Matrix-Matrix multiplication中,BLAS的兩個矩陣相乘的標(biāo)準(zhǔn)接口是:
dgemm( transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc)
這個接口的主要功能為計算:
而transa和transb可以分別指定矩陣A和矩陣B是否進(jìn)行轉(zhuǎn)置;A的計算維度為m×k,矩陣B的計算維度為k×n,矩陣C的計算維度為m×n;ldX表示矩陣X的行數(shù)(這個的參數(shù),可能有的同學(xué)會說,不是跟m或者n或者k一樣嗎?其實不然,這個參數(shù)的功能是讓這個接口能夠使得A本身比計算維度大,只使用子矩陣來進(jìn)行計算,m≤lda)。接下來開始對這個接口進(jìn)行優(yōu)化。
GEMM算法基礎(chǔ):
則根據(jù)矩陣相乘的定義,可得C=AB+C的計算公式為:
從而可將其實現(xiàn)為:
for i=0:m-1for j=0:n-1for p=0:k-1C(i,j):=A(i,p)*B(p,j)+C(i,j)endforendfor
endfor
?可以看出,根據(jù)定義實現(xiàn)的算法計算復(fù)雜度為O(mnk),也就是O(n^3)。
常規(guī)的卷積操作為:
3維卷積運算執(zhí)行完畢,得一個2維的平面:
將卷積操作的3維立體變?yōu)槎S矩陣乘法,可以調(diào)用BLAS中的GEMM庫,按 [kernel_height, kernel_width, kernel_depth] ? 將輸入分成 3 維的 patch,并將其展成一維向量:
此時的卷積操作就可轉(zhuǎn)化為矩陣乘法:
由于內(nèi)存中二維數(shù)組是以行優(yōu)先進(jìn)行存儲的,因此B[k][j]存在嚴(yán)重的cache命中率問題,解決這個問題的方法是也將B進(jìn)行一次沿對角線進(jìn)行翻轉(zhuǎn),使得最里面的計算變成row直接取出來。
從下圖可以看出,一個CNN模型運算過程中,基本上的時間都來消耗在CONV操作上。(圖像來自于賈揚清畢業(yè)論文,論文地址)
高效卷積算法之二:
Winograd算法簡介
這個算法用更多的加法來代替乘法,在FPGA上,由于乘法的計算消耗更多的資源和時鐘,往往是很慢的。一般的乘法需要借助FPGA中的DSP來計算,DSP的大小有18 bits X 25 bits的乘法,如果兩個浮點數(shù)較大,則需要更多的乘法。采用Winograd卷積算法,借助LUT來計算乘法,會節(jié)省FPGA的資源,加快速度。
因此,我們可以在filter 維度較小情況下應(yīng)用winograd 做卷積。
以下是一些實際運算中,采用該方法的性能對比結(jié)果:
從上面的對比可以看出,利用Winograd算法進(jìn)行卷積,比NVIDIA的深度學(xué)習(xí)庫cuDNN中的卷積計算快很多。其中cuDNN的卷積是GEMM算法實現(xiàn)。batch_size越大,加速效果越明顯,因為越大的batch_size,計算的負(fù)載并不是線性的增加,開辟的內(nèi)存地址和GPU的顯存被充分計算應(yīng)用,增加的一部分空間,平均到一個樣本數(shù)上,計算時間更短,速度更明顯。這個理論在Google的一篇論文上也具體介紹了batch_size的影響。(圖片來自于Intel官方提供的對比,對比圖像地址?)
反過來看精度,Winograd算法的實現(xiàn)和直接卷積(原始的卷積實現(xiàn))的效果差不多4X4,2X2的Winograd卷積核效果都不怎么掉。說明Winograd算法是一種高效的卷積算法。有值得發(fā)掘的價值。
在下一篇文章會介紹Winograd算法的應(yīng)用,在ICLR,CVPR,FPGA,FCCM等機器學(xué)習(xí)和FPGA領(lǐng)域的定會上的研究實現(xiàn)和新的突破。請點擊下一篇綜述。https://blog.csdn.net/qq_32998593/article/details/86181663
?
總結(jié)
以上是生活随笔為你收集整理的Winograd,GEMM算法综述(CNN中高效卷积实现)(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 钻石烟多少钱一包啊?
- 下一篇: Winograd,GEMM算法综述(CN