圖像卷積及其計算(特征圖尺寸、參數量、計算量)
卷積前后特征圖尺寸的計算
定義參數如下:
- 輸入特征圖尺寸: W×WW×WW×W
- 卷積核尺寸: F×FF×FF×F
- 步長: SSS
- 填充的像素數:PPP
則有輸出特征圖尺寸為 N×NN×NN×N:
N=(W?F+2P)/S+1N = (W ? F + 2P )/S+1 N=(W?F+2P)/S+1
參數量的計算
卷積層的參數量
卷積的參數量即卷積核的參數量,設我們有如下參數:
- 卷積核尺寸:KKK
- 前一層的通道數:CinC_{in}Cin?
- 當前層的卷積核個數:CoutC_{out}Cout?
單個卷積核的參數量:
Paramskernel=Cin×K2Params_{kernel}=C_{in}\times K^2 Paramskernel?=Cin?×K2
有 CoutC_{out}Cout? 個卷積核,故:
Paramsconv=K2×Cin×CoutParams_{conv} = K^2\times C_{in}\times C_{out} Paramsconv?=K2×Cin?×Cout?
全連接層的參數量
上面已經說過卷積層的參數量計算方法了,那如何計算全連接層的參數量?其實和卷積層參數量的計算方法是一樣的。我們在進行全連接層的計算之前需要將最后一層卷積得到的特征圖展開為一維的向量,即 Din=H×W×CD_{in}=H\times W\times CDin?=H×W×C ,其中 H,W,CH,\ W,\ CH,?W,?C 是最后一層卷積輸出特征圖的高寬和通道數,DinD_{in }Din? 即為本全連接層的輸入特征維度,又設 DoutD_{out}Dout? 為輸出特征維度,則有:
ParamsFC=Din×DoutParams_{FC}=D_{in}\times D_{out} ParamsFC?=Din?×Dout?
可以理解為是一個卷積層,我們就是用4096個 7×7×5127\times 7\times 5127×7×512 的卷積核去做卷積。
驗證
我們用VGG16, PyTorch來驗證我們的公式是否正確。
VGG16的第一個卷積層輸入為原圖像 224×224×3224\times 224\times 3224×224×3,卷積核個數為 646464,尺寸為3,則根據公式,我們有VGG16第一個卷積層的參數量:
Paramsconv=K2×Cin×Cout=32×3×64=1728Params_{conv} = K^2\times C_{in}\times C_{out}= 3^2\times 3\times 64=1728 Paramsconv?=K2×Cin?×Cout?=32×3×64=1728
VGG16第一個全連接層的輸入維度數為最后一張特征圖的尺寸拉直:Din=7×7×512D_{in}=7\times 7\times 512Din?=7×7×512,輸出維度數為4046,則:
ParamsFC=Din×Dout=4096×4096=102760448Params_{FC}=D_{in}\times D_{out}=4096\times 4096=102760448 ParamsFC?=Din?×Dout?=4096×4096=102760448
手動計算好之后我們用PyTorch來打印輸出以下看一下:
import torch
from torchvision.models import resnet50, vgg16
import numpy as npmodel = vgg16()
for name, parameters in model.named_parameters():print(name, ':', np.prod(parameters.size()))
輸出:
features.0.weight : 1728
features.0.bias : 64
...
classifier.0.weight : 102760448
classifier.0.bias : 4096
計算正確。
卷積的計算量
參考:FLOPs、FLOPS、Params的含義及PyTorch中的計算方法
MAC
MAC:Multiply Accumulate,乘加運算。乘積累加運算(英語:Multiply Accumulate, MAC)是在數字信號處理器或一些微處理器中的特殊運算。實現此運算操作的硬件電路單元,被稱為“乘數累加器”。這種運算的操作,是將乘法的乘積結果和累加器的值相加,再存入累加器:
a←a+b×ca\leftarrow a+b\times c a←a+b×c
使用MAC可以將原本需要的兩個指令操作減少到一個指令操作,從而提高運算效率。
計算量FLOPs的計算
以下不考慮激活函數的計算量。
卷積層
(2×Ci×K2?1)×H×W×C0(2\times C_i\times K^2-1)\times H\times W\times C_0(2×Ci?×K2?1)×H×W×C0?
CiC_iCi?=輸入通道數, KKK=卷積核尺寸,H,WH,WH,W=輸出特征圖空間尺寸,CoC_oCo?=輸出通道數。
一個MAC算兩個個浮點運算,所以在最前面×2\times 2×2。不考慮bias時有?1-1?1,有bias時沒有?1-1?1。由于考慮的一般是模型推理時的計算量,所以上述公式是針對一個輸入樣本的情況,即batch size=1。
理解上面這個公式分兩步,括號內是第一步,計算出輸出特征圖的一個pixel的計算量,然后再乘以 H×W×CoH\times W\times C_oH×W×Co? 拓展到整個輸出特征圖。
括號內的部分又可以分為兩步,(2?Ci?K2?1)=(Ci?K2)+(Ci?K2?1)(2\cdot C_i\cdot K^2-1)=(C_i\cdot K^2)+(C_i\cdot K^2-1)(2?Ci??K2?1)=(Ci??K2)+(Ci??K2?1)。第一項是乘法運算數,第二項是加法運算數,因為 nnn 個數相加,要加 n?1n-1n?1 次,所以不考慮bias,會有一個?1-1?1,如果考慮bias,剛好中和掉,括號內變為 2?Ci?K22\cdot C_i\cdot K^22?Ci??K2。
全連接層
全連接層: (2×I?1)×O(2\times I-1)\times O(2×I?1)×O
III=輸入層神經元個數 ,OOO=輸出層神經元個數。
還是因為一個MAC算兩個個浮點運算,所以在最前面×2\times 2×2。同樣不考慮bias時有?1-1?1,有bias時沒有?1-1?1。分析同理,括號內是一個輸出神經元的計算量,拓展到OOO了輸出神經元。
可以用 thop
庫來驗證。
Ref
https://zhuanlan.zhihu.com/p/91277743