在阅读论文时,我们会遇到参数量,FLOPS,Multi-add, CNN参数,CNN计算量等概念,通过阅读整理,这篇博客希望以最简洁的解释帮助大家理解这些基本概念。
首先,我们看一下卷积的计算方式:
卷积的计算方式:图片来自http://cs231n.github.io/convolutional-networks/
卷积的计算方式
上图描述了一个 553 的输入特征图边界采用1个0像素填充,利用 2 个 33 的卷积核,其步长为2进行计算的例子:最后的输出特征图是 33*2。
这个是怎么得到的呢,我先假定一些卷积相关的基本采参数:
输入特征图高:Hi,宽:wi
输入特征图的边界填充像素个数: p
卷积核尺寸(高x宽):Kh*Kw
卷积核滑动步长:s
输出特征图高:Ho,宽:Wo
则:Ho = [(Hi - Kh + 2p) / s] + 1 ,Wo = [(wi - Kw + 2p) / s] + 1
注:这里的 [x] 表示向下取整:e.g. [5 / 2] = 2
所以上图中:Ho = [5 - 3 + 21] / 2 + 1 = 3 ;Wo = [5 - 3 + 2p] / 2 + 1 = 3
由于采用了2个33的卷积核,所以输出两个特征图,其大小都为33
顺便提一句:如果我们采用的空洞卷积,则会有一个参数 d 表示膨胀率:(这里不具体解释空洞卷积的概念)
那么:Ho = [(Hi + 2p -d(Kh - 1) - 1) / s] + 1;Wo = [(Wi + 2p - d(Kw - 1) - 1) / s] + 1
当 d = 1时,表示的普通卷积,退化为前面的公式;所以大家可以直接记这个公式。
下面我们分析CNN的参数和CNN的计算量
对于一个 HiWiCi 的输入特征图经过KwKh的卷积操作并输出 HoWo*Co 的特征图有两种算数操作(即,Multi-Add)
1,乘法操作
对于Kh*Kw的卷积窗口,有 Kh*Kw*Ci 次乘法操作,因为卷积是在输入特征图上进行,而卷积是在 Ci 个通道上同时进行。
2,加法操作
对于 n 个元素求和,我们需要 n - 1次加法。而在一个卷积窗口内有 Kh * Kw * Ci 个元素。所以我们需要Kh*Kw*Ci - 1次加法操作。
卷积的参数可以理解为在一个卷积窗口内的计算个数,即输出一个卷积结果元素产生的运算操作。
CNN参数:(KhKwCi + KhKwCi - 1)* Co = (2KhKwCi - 1) Co (没有偏置bias的情况)
要知道,偏置项只有在输出特征图上才有效。
所以,如果输出才有偏置的话,那么CNN参数应该在每个输出通道上 加上一个偏置项。
CNN参数:(KhKwCi + KhKwCI - 1)* Co + Co = 2KhKw*Co
CNN的计算量就是对所有输出特征图的所有元素的求和。
CNN的计算量 = CNN参数 * Ho * Wo
CNN的计算量: (2KhKwCi - 1) Co * Ho*Wo (无偏置bias的情况)
CNN的计算量: 2KhKwCi * Co * HoWo (有偏置bias的情况)
FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为计算速度。是一个衡量硬件性能的指标。
FLOPs:注意s小写,是floating point operations的缩写(s表复数),意指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。
这里FLOPs就等于CNN的计算量。
FLOPs = (2KhKwCi - 1) Co * Ho*Wo (无偏置bias的情况)
FLOPs = 2KhKwCi * Co * HoWo (有偏置bias的情况)
通道变化:
1:输入通道个数 等于 卷积核通道个数
2:卷积核个数 等于 输出通道个数
参考:
【1】http://cs231n.github.io/convolutional-networks/
【2】https://www.zhihu.com/question/65305385
【3】https://blog.csdn.net/weixin_40671425/article/details/98057135