深度學習基礎--卷積--加速的卷積運算
加速的卷積運算
convolution在GPU上如何實現,文中介紹了三種方法
1)最直觀的方法是直接實現(即一般的卷積運算)
缺點:這種實現呢需要處理許多的corner case。
文中介紹cuda-convnet2是實現了該種方法,該種方法在不同取值的卷積引數空間效率不一,比如batch size > 128,效率很高,但是如果batch size < 64, 效率比較低。
2)採用快速傅立葉變換fft/fft convolution
優點:該種方法效率非常高
缺點:由於filter需要擴大到和input一樣大小,佔用了大量記憶體,特別是CNN的前幾層filter 大小遠小於input大小。而且,當striding 引數>1, fft效率也不高。
此時需要將卷積核擴大成和feature map一樣的長寬尺寸,這在二者相差較大的時候也是很浪費的。另外,當stride大於1時,資料比較稀疏,採用FFT效果也並不理想。
這是一種加速的2d卷積,matlab中有。 該種方法效率非常高,但是由於filter需要擴大到和input一樣大小,佔用了大量記憶體,特別是CNN的前幾層filter 大小遠小於input大小。第二,當striding 引數>1, fft效率也不高。
實際效果
對於大矩陣,filter2或conv2太慢了,而使用convfft有極大的提速(100 ^ 2和500^2的矩陣進行卷積時,加速為5-10倍。
Signal length 1 second, impulse length 1 second, fs=44100, vectors (one-dimension). conv 103.8 s filter 79.4 s fftfilt 0.38 s convfft 0.92 s Signal length 10 seconds, impulse length 1 second fftfilt 1.28 s convfft 14.61 s
3)cuDNN convolution
論文采用的是將卷積轉化為矩陣乘法的方法,利用NVIDIA的矩陣乘法的特點,做了一些改進。
具體來說就是,計算F(卷積核)對D(輸入的feature map)的卷積,並不是將D轉化後的二維矩陣直接存到視訊記憶體裡面,而是lazily materialing的方式。就是說,當需要用到這部分資料的時候,直接到D中索引對應的資料,並載入到視訊記憶體裡面進行計算,這樣就避免了佔用額外視訊記憶體這一弊端。
因此該方法還需要一個快速從D中索引資料的演算法。
對A x B = C, 分塊載入A和B從off-chip memory to on-chip caches, 同時計算C的一部分。這樣減少了資料傳輸帶來的延遲。對於擴大的input data,我們是在on-chip上轉換成擴大的input data,而不是在off-chip上轉換。
4)caffe中實現的方法(NVIDIA的矩陣乘法)
將卷積操作轉換為密集矩陣相乘。將input data組裝成大小為CRS x NPQ的矩陣,這使得記憶體相對原始input data的大小擴大了之多RS(即kernel_size的平方)倍。
這種方法使用擴大臨時記憶體方法換取密集矩陣計算的便利。
卷積核越大,stride越小,視訊記憶體耗費越高。
參考資料:http://blog.csdn.net/mounty_fsc/article/details/51290446
更詳細
下圖,更詳細地介紹NVIDIA的矩陣乘法。
最後,Filter Matrix乘以Feature Matrix的轉置,得到輸出矩陣Cout x (H x W),就可以解釋為輸出的三維Blob(Cout x H x W)。