cnn0 = nn.Sequential()
cnn0.add_module("CNN-0", nn.Conv2d(1, 32, kernel_size=[4, 10], stride=[2,8], padding=[0, 0], bias=False))
cnn0.add_module("BN-0", nn.BatchNorm2d(32, eps=1e-04))
cnn0.add_module("ReLU4-0", nn.Hardtanh(min_val=0.0, max_val=4*127/128, inplace=True))
return cnn0
模型如上,一個Conv2d,一個 BatchNorm2d,一個Hardtanh。
假設(shè)輸入feature的形狀為[1, 1, 130, 40] [batch_size, channel, height, width]
batch size假設(shè)為1,即輸入只有一個樣本。

CNN 的 flops 和 parameters
上圖左半邊演示了Conv2d的計算過程。
輸入為130 * 4 形狀的矩陣,kernel (filter) 形狀為 4 * 10,
nn.Conv2d() output channel為32,即可視為,有32個kernel/做了32次卷積
而每一個kernel(filter) 輸出的形狀由圖中紅色方式計算,方法為 ((輸入邊長 - kernel邊長)/步長)+1 取整,沒有padding,為64 * 4。
因做了32次操作(32個channel),堆疊后得到最終的輸出形狀為 32 * 64 * 4
Flops可視為乘算操作的次數(shù)。
輸出張量上每一個數(shù)字都由kernel中每個數(shù)字和輸入做一次乘法并加和得到,即,輸出張量共有的32?64?4個數(shù)字,各需要4?10次乘算才能得到。
FLOPs=32?64?4?4?10=312320
Parameter在這里即為這32個kernel中的每一個數(shù)字 + 每一個kernel一個 bias
因bias=false, 不用加1.
所以parameters = 32?4?10=1280
Batch norm 的 flops 和 parameters
上圖右半邊演示了BN的計算過程。
BN層輸入和輸出形狀不變,有兩個可學(xué)習(xí)的參數(shù),伽馬和貝塔 (具體請自行谷歌);
具體的標(biāo)準(zhǔn)化是一個channel一個channel進行的。
對每一個channel 形狀為64 * 4的矩陣,進行norm需要求均值和方差,均值不需要乘法,而方差的具體計算需要做64 * 4次平方,即64 * 4次乘算;然后還需要把每一個數(shù)字乘以伽馬來得最終的偏移值,即再做64 * 4次乘算;
因此每一個channel需要做64?4?2次乘算,
共有32個channel,所以FLOPs=32?64?4?2=16384
BN的Parameter就是每一個channel的伽馬和貝塔值
所以parameters = 32?2=64
最后的Hardtanh方法沒有可供學(xué)習(xí)的parameter也不做乘算,對FLOPs和parameters沒有影響。
因此,此模型總共的FLOPs為344064,總parameters為1344