CNN中感受野、feature map、参数量、计算量相关知识和计算方法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/EngineerHe/article/details/98787026

CNN中感受野、feature map、参数量、计算量相关知识和计算方法

感受野的定义:

  • 卷积神经网络输出特征图上的像素点 在原始图像上所能看到区域的大小,输出特征会受感受野区域内的像素点的影响

  • 图像的空间联系是局部的,就像人是通过一个 局部的感受野 去感受外界图像一样,每一个神经元都不需要对全局图像做感受,每个神经元只感受局部的图像区域,然后在更高层,将这些感受不同局部的神经元 综合起来就可以得到全局的信息了

感受野的作用:

  • 小卷积可以代替大卷积层
  • 密集预测task要求输出像素的感受野足够的大,确保做出决策时没有忽略重要信息,一般也是越深越好
  • 一般task要求感受野越大越好,如图像分类中最后卷积层的感受野要大于输入图像,网络深度越深感受野越大性能越好
  • 目标检测task中设置anchor要严格对应感受野,anchor太大或偏离感受野都会严重影响检测性能

感受野的计算方法:

注意:

  • 第一层感受野的大小等于滤波器的大小
  • 感受野的大小和它之前所有层的滤波器大小和步长有关
  • padding不影响感受野的大小,不考虑padding

从前往后计算,公式如下
R F l + 1 = R F l + ( k e r n e l _ s i z e l + 1 1 ) × f e a t u r e _ s t r i d e l RF_{l+1} = RF_{l} + (kernel\_size_{l+1} - 1)\times feature\_stride_{l}
其中 f e a t u r e _ s t r i d e l feature\_stride_{l} 用如下公式计算,默认 R F 0 = 1 , f e a t u r e _ s t r i d e 0 = 1 RF_{0} = 1, feature\_stride_{0}=1
f e a t u r e _ s t r i d e l = i = 1 l s t r i d e i feature\_stride_{l} = \prod_{i=1}^{l}stride_{i}
如果是dilated conv,计算公式为
R F l + 1 = R F l + ( k e r n e l _ s i z e l + 1 1 ) × f e a t u r e _ s t r i d e l × d i l a t i o n l + 1 RF_{l+1} = RF_{l} + (kernel\_size_{l+1} - 1)\times feature\_stride_{l} \times dilation_{l+1}

假如输入图片的大小为200*200, 经过一层卷积(kernel size 5 * 5, padding 1, stride 2),pooling(kernel size 3 * 3, padding 0, stride = 1),又一层卷积(kernel size 3 * 3, padding 1, stride 1)之后,请问输出特征图感受野的大小是多少?

conv1 = 1 + (5-1)*1 = 5, R F 0 = 5 , f e a t u r e _ s t r i d e 1 = 2 RF_{0} = 5, feature\_stride_{1}=2

pooling = 5 + (3-1)*2 = 9, R F 1 = 9 , f e a t u r e _ s t r i d e 1 = 2 RF_{1} = 9, feature\_stride_{1}=2

conv2 = 9 + (3-1)*2 = 13 R F 2 = 13 RF_{2} = 13

所以最终感受野的输出大小为13

另一种方法是从top往下层迭代直到追溯到input image,计算公式如下:
( N 1 ) R F = f ( N R F , s t r i d e , k e r n e l ) = ( N R F 1 ) s t r i d e + k e r n e l (N-1)_{RF} = f(N_{RF}, stride, kernel) = (N_{RF} - 1) * stride + kernel
其中 N R F N_{RF} 指的是第n层的 feature 在n-1层的RF,默认 N R F = 1 N_{RF}=1 , s t r i d e k e r n e l stride,kernel 分别表示当前层的步长和滤波器大小

当包含dilated conv卷积时,需要重新计算滤波器的大小 d _ k e r n e l = ( d i l a t i o n 1 ) × ( k e r n e l 1 ) + k e r n e l d\_kernel = (dilation-1) \times (kernel-1) + kernel ,所以计算公式变为:
( N 1 ) R F = f ( N R F , s t r i d e , k e r n e l ) = ( N R F 1 ) s t r i d e + d _ k e r n e l d _ k e r n e l = ( d i l a t i o n 1 ) × ( k e r n e l 1 ) + k e r n e l (N-1)_{RF} = f(N_{RF}, stride, kernel) = (N_{RF} - 1) * stride + d\_kernel \\ d\_kernel = (dilation-1) \times (kernel-1) + kernel
同样的以上面的例子举例:

2 R F 2_{RF} = (1-1)*1 + 3 = 3

1 R F 1_{RF} = (3-1)*1 + 3 = 5

0 R F 0_{RF} = (5-1)*2 + 5 = 13

feature map特征图的计算:
H o u t = H i n + 2 × p a d d i n g [ 0 ] d i l a t i o n [ 0 ] × ( k e r n e l s i z e [ 0 ] 1 ) 1 s t r i d e [ 0 ] + 1 W o u t = W i n + 2 × p a d d i n g [ 1 ] d i l a t i o n [ 1 ] × ( k e r n e l s i z e [ 1 ] 1 ) 1 s t r i d e [ 1 ] + 1 Hout=⌊ Hin+2×padding[0]−dilation[0]×(kernel_size[0]−1)−1 stride[0] +1⌋ \\ Wout=⌊ Win+2×padding[1]−dilation[1]×(kernel_size[1]−1)−1 stride[1]+1⌋
当有小数时,卷积操作:向上取整还是向下取整,根据框架而定,如tensorflow采用的是向上取整,pytorch采用的是向下取整;
pooling是统一向上取整;

CNN 模型所需的计算力(flops)和参数(parameters)数量的计算

对于一个卷积层,假设一个图像的输入通道为 n i n n_{in} ,输出通道为 n o u t n_{out} ,kernel_size 为 k w × k h k_w \times k_h ,输出的feature map尺寸为 f w × f h f_w \times f_h ,则该卷积层的

  • paras = n o u t × ( k w × k h × n i n + 1 ) n_{out} \times (k_w \times k_h \times n_{in} + 1)
  • flops= f w × f h × n o u t × ( k w × k h × n i n + 1 ) f_w \times f_h \times n_{out} \times (k_w \times k_h \times n_{in} + 1)

乘累加操作

MADD = f w × f h × n o u t × ( k w × k h × n i n + 1 ) f_w \times f_h \times n_{out} \times (k_w \times k_h \times n_{in} + 1) + f w × f h × n o u t × ( ( k w × k h × n i n 1 + 1 ) f_w \times f_h \times n_{out} \times ((k_w \times k_h \times n_{in} - 1) + 1)

即 MADD = flops + f w × f h × n o u t × ( ( k w × k h × n i n 1 + 1 ) f_w \times f_h \times n_{out} \times ((k_w \times k_h\times n_{in}-1) + 1)

深度可分离卷积

  • paras = n i n × k w × k h + n o u t × ( n i n × 1 × 1 + 1 ) n_{in} \times k_w \times k_h + n_{out} \times (n_{in} \times 1 \times 1 + 1)
  • flops = f w × f h × n i n × k w × k h + ( n i n × 1 × 1 + 1 ) × n o u t × f w × f h f_w \times f_h \times n_{in} \times k_w \times k_h + (n_{in} \times 1 \times 1 + 1) \times n_{out} \times f_w \times f_h

猜你喜欢

转载自blog.csdn.net/EngineerHe/article/details/98787026