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。
假设输入feature的形状为[1, 1, 130, 40] [batch_size, channel, height, width]
batch size假设为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可视为乘算操作的次数。
输出张量上每一个数字都由kernel中每个数字和输入做一次乘法并加和得到,即,输出张量共有的32✖64✖4个数字,各需要4✖10次乘算才能得到。
FLOPs=32✖64✖4✖4✖10=312320
Parameter在这里即为这32个kernel中的每一个数字 + 每一个kernel一个 bias
因bias=false, 不用加1.
所以parameters = 32✖4✖10=1280
Batch norm 的 flops 和 parameters
上图右半边演示了BN的计算过程。
BN层输入和输出形状不变,有两个可学习的参数,伽马和贝塔 (具体请自行谷歌);
具体的标准化是一个channel一个channel进行的。
对每一个channel 形状为64 * 4的矩阵,进行norm需要求均值和方差,均值不需要乘法,而方差的具体计算需要做64 * 4次平方,即64 * 4次乘算;然后还需要把每一个数字乘以伽马来得最终的偏移值,即再做64 * 4次乘算;
因此每一个channel需要做64✖4✖2次乘算,
共有32个channel,所以FLOPs=32✖64✖4✖2=16384
BN的Parameter就是每一个channel的伽马和贝塔值
所以parameters = 32✖2=64
最后的Hardtanh方法没有可供学习的parameter也不做乘算,对FLOPs和parameters没有影响。
因此,此模型总共的FLOPs为344064,总parameters为1344