CNN中FLOPs計算

轉載地址:https://blog.csdn.net/sinat_34460960/article/details/84779219

 

在這之前我們先看一下CNN的前向傳播計算公式,便於理解什麼是parameters和FLOPs,這裏參考Andrew老師課堂上的課件,如下:

前向傳播過程其實就是將輸入或上層輸出左乘以一個W,然後加上一個b,最後使用合適的\sigma函數進行激活的過程,結果便是下層的輸入或是最終的輸出,多層網絡就不斷重複這個過程。

如果要讓網絡自己學習到輸入數據中的良好特徵,一般而言就需要搭建較複雜的網絡,也就是包含更多的層,更大的層,更復雜的層等等。這基本是一個正相關的過程,即隱藏在數據中的特徵越高層,網絡就要越複雜,當然這個複雜是有一個合適的度的,不然就存在欠擬合和過擬合的問題了。

於是這就會產生一些實踐上的問題,一是這個複雜的網絡到底需要多少參數才能定義它?二是數據過一遍這麼複雜的網絡需要多大的計算量呢?這也分別就是我們今天要討論的兩個量:parameters和FLOPs。

在本文中,我們以下圖的AlexNet網絡模型來說明在CNN中二者的計算過程:

  • parameters

從Andrew的前向傳播PPT中,我們可以知道CNN中的parameters分爲兩種:W和b,注意這裏W是大寫,表示一個矩陣,也因此它相比b,既含有更多的信息,同時也是parameters的主要部分。

在AlexNet模型結構圖中,每個大長方體中的小長方體就是W,它是大小爲[K_h, K_w, C_{in}]的三維矩陣,其中K_h表示卷積核(filter或kernel)的高度,K_w表示卷積核的寬度,C_{in}表示輸入的通道數(Channels),一般情況下,K_h和K_w的大小是一樣的,且一般比較小,3、5、7之類。

同時由於CNN特點,我們知道,一個卷積核在輸入數據上從左往右、從上往下掃一遍,便會計算出很多個前向傳播的值,這些值就會按原來相對位置拼成一個feature map,當然一個卷積核提取的信息太過有限,於是我們需要N個不同的卷積核各掃數據,於是會產生N個feature map,這N個feature map在拼在一起就是這一層的輸出,也是一個三維矩陣,即大長方體。設每個卷積核掃一遍之後輸出的高度和寬度分別爲H, W(注意區分兩個W),同時N就是輸出的通道數,記作C_{out},則輸出矩陣大小爲[H, W, C_{out}}]。

例如在從AlexNet圖中左邊第一個大長方體(輸入圖片)到第二個大長方體(圖中是兩個並列小長方體,這是作者分佈式訓練的需要,這裏分析時可以將二者並起來看)這個過程,即是從[H, W, C_{in}] = [224, 224, 3]的矩陣,經過[K_h, K_w, C_{in}] = [11, 11, 3]的卷積核,變爲[H, W, C_{out}] = [55, 55, 48+48]的矩陣的過程。

注意到兩個特點,一是W是一個三維矩陣,通道數始終和輸入數據保持一致,所以實際是二維空間的掃描,二是W在掃描的過程中是不變的,即一個卷積核是掃一遍數據而不是某個點。於是對於AlexNet模型的第一層卷積,W的大小是[K_h, K_w, C_{in}] = [11, 11, 3],個數是N,也就是C_{out} = 96,於是這一個卷積層的parameters中權重的個數爲(K_h * K_w * C_{in}) * C_{out} = (11 * 11 * 3) * 96 = 34,848。

另外對於b,從前向傳播公式可以看出,和W是一一對應的,維度也和W是對應的,即[C_{out}, ],還是對於AlexNet的第一個卷積層,parameters中偏置的個數爲C_{out} = 96。

於是我們可以總結出規律:對於某一個卷積層,它的parameters個數爲:(K_h * K_w * C_{in}) * C_{out} + C_{out},參數定義同上文。

剛纔講的都是對於卷積層的,對於全連接層,比如AlexNet的後三層,其實要更簡單,因爲這實際是兩組一維數據之間(如果是卷積層過度到全連接層,如上圖第5層到第6層,會先將第5層三維數據flatten爲一維,注意元素總個數未變)的兩兩連接相乘,然後加上一個偏置即可。所以我們也可以總結出規律:對於某個全連接層,如果輸入的數據有N_{in}個節點,輸出的數據有N_{out}個節點,它的parameters個數爲:N_{in} * N_{out} + N_{out}。如果上層是卷積層,N_{in}就是上層的輸出三維矩陣元素個數,即三個維度相乘。

  • FLOPs

首先介紹一個很形似的概念——FLOPS:全稱是floating point operations per second,意指每秒浮點運算次數,即用來衡量硬件的計算性能,比如nvidia官網上列舉各個顯卡的算力(Compute Capability)用的就是這個指標,如下圖,不過圖中是TeraFLOPS,前綴Tera表示量級:MM,2^12之意。

這裏我們討論的FLOPs全稱是floating point operations,即表示浮點運算次數,小s後綴是複數的縮寫,可以看做FLOPS在時間上的積分,區別類似速度和時間。

同樣從Andrew的前向傳播PPT中,我們也可以看到,這裏的浮點運算主要就是W相關的乘法,以及b相關的加法,每一個W對應W中元素個數個乘法,每一個b對應一個加法,因此好像FLOPs個數和parameters是相同的。

但其實有一個地方我們忽略了,那就是每個feature map上每個點的權值是共享,這是CNN的一個重要特性,也可以說是優勢(因此才獲得特徵不變性,以及大幅減少參數數量),所以我們在計算FLOPs是隻需在parameters的基礎上再乘以feature map的大小即可,即對於某個卷積層,它的FLOPs數量爲:[(K_h * K_w * C_{in}) * C_{out} + C_{out}] * (H * W) = num\_params * (H * W),其中num\_params表示該層參數的數目。

還是裏AlexNet網絡第一卷積層爲例,它的FLOPs數目爲: [(11 * 11 * 3) * 96 + 96] * (55 * 55) = 105,705,600。

對於全連接層,由於不存在權值共享,它的FLOPs數目即是該層參數數目:N_{in} * N_{out} + N_{out}。
小結

運用上面的規律,我們便可以很輕鬆地計算出AlexNet網絡的parameters和FLOPs數目,如下圖(來自網絡,出處已不可考):

這裏不再重複舉例。但是其中就是有一個地方和我算的有出入:第四卷積層的FLOPs數目,我計算是:1.3M * 13 * 13 = 219.7M,圖中是112M。

 

最後還要說一點關於FLOPs的計算,在知乎上也有討論,另外Nvidia的Pavlo Molchanov等人的文章的APPENDIX中也有介紹,由於是否考慮biases,以及是否一個MAC算兩個operations等因素,最終的數字上也存在一些差異。但總的來說,計算FLOPs其實也是在對比之下才顯示出某種算法,或者說網絡的優勢,如果我們堅持一種計算標準下的對比,那麼就是可以參考的,有意義的計算結果。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章