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

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

感受野的定义:

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

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

感受野的作用:

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

感受野的计算方法:

注意:

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

从前往后计算,公式如下
RFl+1=RFl+(kernel_sizel+1−1)×feature_stridel RF_{l+1} = RF_{l} + (kernel\_size_{l+1} - 1)\times feature\_stride_{l} RFl+1=RFl+(kernel_sizel+11)×feature_stridel
其中feature_stridelfeature\_stride_{l}feature_stridel用如下公式计算,默认 RF0=1,feature_stride0=1RF_{0} = 1, feature\_stride_{0}=1RF0=1,feature_stride0=1
feature_stridel=∏i=1lstridei feature\_stride_{l} = \prod_{i=1}^{l}stride_{i} feature_stridel=i=1lstridei
如果是dilated conv,计算公式为
RFl+1=RFl+(kernel_sizel+1−1)×feature_stridel×dilationl+1 RF_{l+1} = RF_{l} + (kernel\_size_{l+1} - 1)\times feature\_stride_{l} \times dilation_{l+1} RFl+1=RFl+(kernel_sizel+11)×feature_stridel×dilationl+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, RF0=5,feature_stride1=2RF_{0} = 5, feature\_stride_{1}=2RF0=5,feature_stride1=2

pooling = 5 + (3-1)*2 = 9, RF1=9,feature_stride1=2RF_{1} = 9, feature\_stride_{1}=2RF1=9,feature_stride1=2

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

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

另一种方法是从top往下层迭代直到追溯到input image,计算公式如下:
(N−1)RF=f(NRF,stride,kernel)=(NRF−1)∗stride+kernel (N-1)_{RF} = f(N_{RF}, stride, kernel) = (N_{RF} - 1) * stride + kernel (N1)RF=f(NRF,stride,kernel)=(NRF1)stride+kernel
其中 NRFN_{RF}NRF 指的是第n层的 feature 在n-1层的RF,默认NRF=1N_{RF}=1NRF=1, stride,kernelstride,kernelstridekernel分别表示当前层的步长和滤波器大小

当包含dilated conv卷积时,需要重新计算滤波器的大小 d_kernel=(dilation−1)×(kernel−1)+kerneld\_kernel = (dilation-1) \times (kernel-1) + kerneld_kernel=(dilation1)×(kernel1)+kernel,所以计算公式变为:
(N−1)RF=f(NRF,stride,kernel)=(NRF−1)∗stride+d_kerneld_kernel=(dilation−1)×(kernel−1)+kernel (N-1)_{RF} = f(N_{RF}, stride, kernel) = (N_{RF} - 1) * stride + d\_kernel \\ d\_kernel = (dilation-1) \times (kernel-1) + kernel (N1)RF=f(NRF,stride,kernel)=(NRF1)stride+d_kerneld_kernel=(dilation1)×(kernel1)+kernel
同样的以上面的例子举例:

2RF2_{RF}2RF = (1-1)*1 + 3 = 3

1RF1_{RF}1RF = (3-1)*1 + 3 = 5

0RF0_{RF}0RF = (5-1)*2 + 5 = 13

feature map特征图的计算:
Hout=⌊Hin+2×padding[0]−dilation[0]×(kernelsize[0]−1)−1stride[0]+1⌋Wout=⌊Win+2×padding[1]−dilation[1]×(kernelsize[1]−1)−1stride[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⌋ Hout=Hin+2×padding[0]dilation[0]×(kernelsize[0]1)1stride[0]+1Wout=Win+2×padding[1]dilation[1]×(kernelsize[1]1)1stride[1]+1
当有小数时,卷积操作:向上取整还是向下取整,根据框架而定,如tensorflow采用的是向上取整,pytorch采用的是向下取整;
pooling是统一向上取整;

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

对于一个卷积层,假设一个图像的输入通道为ninn_{in}nin,输出通道为noutn_{out}nout,kernel_size 为kw×khk_w \times k_hkw×kh,输出的feature map尺寸为fw×fhf_w \times f_hfw×fh ,则该卷积层的

  • paras = nout×(kw×kh×nin+1)n_{out} \times (k_w \times k_h \times n_{in} + 1)nout×(kw×kh×nin+1)
  • flops= fw×fh×nout×(kw×kh×nin+1)f_w \times f_h \times n_{out} \times (k_w \times k_h \times n_{in} + 1)fw×fh×nout×(kw×kh×nin+1)

乘累加操作

MADD = fw×fh×nout×(kw×kh×nin+1)f_w \times f_h \times n_{out} \times (k_w \times k_h \times n_{in} + 1)fw×fh×nout×(kw×kh×nin+1) + fw×fh×nout×((kw×kh×nin−1)+1)f_w \times f_h \times n_{out} \times ((k_w \times k_h \times n_{in} - 1) + 1)fw×fh×nout×((kw×kh×nin1+1)

即 MADD = flops + fw×fh×nout×((kw×kh×nin−1)+1)f_w \times f_h \times n_{out} \times ((k_w \times k_h\times n_{in}-1) + 1)fw×fh×nout×((kw×kh×nin1+1)

深度可分离卷积

  • paras = nin×kw×kh+nout×(nin×1×1+1)n_{in} \times k_w \times k_h + n_{out} \times (n_{in} \times 1 \times 1 + 1)nin×kw×kh+nout×(nin×1×1+1)
  • flops = fw×fh×nin×kw×kh+(nin×1×1+1)×nout×fw×fhf_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_hfw×fh×nin×kw×kh+(nin×1×1+1)×nout×fw×fh

欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步
在这里插入图片描述

### 计算深度学习模型的参数数量 对于卷积神经网络(CNN),参数主要包括卷积核权重其他需要学习的权值。具体来说: - 卷积层中的每个滤波器(即卷积核)都有自己的权重矩阵,以及偏置项。 - 对于全连接层而言,则由输入节点到输出节点之间的连接权重构成。 以AlexNet的第一个卷积层(CONV1)为例,假设该层有96个大小为\(11 \times 11\)且通道数为3的过滤器,并带有bias,则CONV1的总参数量可表示为\[ (11\times11\times3+1)\times96=34944\]这里额外加上了1是因为每一个filter还有一个对应的bias term[^1]。 ### 浮点运算次数(FLOPs) FLOPs代表完成一次正向传播过程中涉及的所有浮点操作的数量。它通常用来评估算法效率硬件需求。针对特定类型的层,比如卷积层,可以按照如下方式估算: 给定一个尺寸为\(H_i\times W_i\)的特征图经过具有\(K_h\times K_w\)感受野、步幅stride s padding p 的卷积处理后得到的新特征图为 \(H_o\times W_o\) ,那么单次卷积操作产生的FLOP数目大约等于\[2\times C_{in}\times C_{out} \times H_k \times W_k \times H_o \times W_o\] 其中因子2来源于每次乘法都会伴随至少一次加法;而当涉及到批量归一化(Batch Normalization)等其他组件时还需进一步增加相应的计算开销[^2]。 回到之前提到的例子,在不考虑激活函数等因素的情况下,如果输入图像分辨率为\(227\times227\)像素,通过上述公式可知CONV1层总的FLOPs约为\[34944\times55\times55=108249600\]。 需要注意的是实际应用中往往还会考虑到更多细节因素来精确统计整个网络架构下的总体FLOPs数值。 ```python def calculate_flops(input_size, kernel_size, output_channels, stride=1, padding=0): """ Calculate the number of floating point operations for a convolutional layer. Args: input_size (tuple): Input feature map size as tuple (height, width). kernel_size (int or tuple): Kernel dimensions either single value or pair (height,width). output_channels (int): Number of filters/output channels. stride (int or tuple, optional): Stride length(s). Defaults to 1. padding (int or str, optional): Padding applied before convolution ('same', 'valid' or int values). Default is no padding. Returns: float: Estimated FLOPs count per forward pass through this conv layer. """ if isinstance(kernel_size,int): kh,kw = kernel_size,kernel_size elif isinstance(kernel_size,(list,tuple)): kh,kw = kernel_size hi,wi=input_size ho=int((hi-kh+(2*padding))/stride)+1 wo=int((wi-kw+(2*padding))/stride)+1 flops_per_conv=(kh*kw)*output_channels*(ho*wo)*2 # Multiply by two because each multiply has an associated add operation return flops_per_conv print(f"FLOPs for Conv Layer with given specs:{calculate_flops((227,227),(11,11),96)}") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值