CNN中感受野(receptive field)计算及一层输入和输出size之间的关系计算

 之前有段时间偏向于工程实现,用CNN做classification,Detection,Segmentation都已经玩过,且在项目上有过应用,过程中也看了很多理论知识,但较浅。现在有时间再回头过下理论知识吧。

     一.感受野的计算

        点击打开链接该博客中做了完备数学公式的推导,在此引用一下:    

 

         假设第i层上对第j层的局部感受野为F(i,j),显然i>=j.假定输入层为第0层。则现在问题转化为求F(i,0)的问题。由上面分      析可知F(i,i)=1,现只需要求出F(i,j) 与F(i,j-1)层的关系,即可通过F(i,i)求出F(i,0).通过简单情况和画图分析,可得      出递归关系式:

            F(i,j-1) = kernel_size_j + (F(i,j)-1)*stride_j,

           kernel_size_j表示的第j层的kernel_size,stride_j表示第j层的stride

     分析可有如下逻辑:

     假设目前有一张原始图像(224*224*1),中间会经过两次卷积(conv1,conv2),那么conv2后的数据(即第3层)对输入层的的感受野可推导如下(假设conv1的kernel size为3*3, stride为1;conv2的kernel size为3*3,stride 为1):

     先计算conv2(第2层)对conv1(第1层)的感受野:

      则上面公式中i=2,j=2;

      F(2,1) = conv2的kernel_size + (F(2,2)-1)*(conv2的stride)

      所以F(2,1)= 3 + (1-1)*1 = 3

     接着求F(2,0),即conv2对输入图像的感受野,则上面公式中i=2,j=1,

      F(2,0) = conv的kernel_size + (F(2,1)- 1) * (conv1的stride)

      即F(2,0) = 3 + (3 -1)*2 = 7

      所以conv3对输入图像的感受野为7个像素。

博客点击打开链接中也对感受野做了介绍,并推出了主流网络vgg16和Alexnet各层的感受野,下面我也带着推导部分层来手动验证下,做这个工作需要对vgg16和Alexnet的网络结构了解(对各层的卷积和池化的kernel size以及stride了解)

 使用博客点击打开链接中的vgg16模型图:

 

  博客点击打开链接对Alexnet的各层结构做了详细介绍。

  来验证博客点击打开链接中的推导值(同时含有vgg16及Alexnet):

  

 首先来验证Alexnet的pool2层对原始图像的感受野计算。pool2是第四层。

 则F(4,3)= 第四层的kernel_size + (F(4,4)-1)*第四层的stride。了解到Alexnet的结构,这里kernel_size=3.

  所以F(4,3) = 3;

  F(4,2) = 第三层的kernrl_size + (F(4,3) - 1)*第三层的stride

  所以F(4,2) = 5 + (3 - 1)* 1 = 7

  F(4,1) = 第二层的kernel_size + (F(4,2) - 1)*第二层的stride

  所以F(4,1) = 3+ (7 - 1)* 2 = 15

  F(4,0) = 第一层的kernel_size + (F(4,1) - 1)*第一层的stride

  所以F(4, 0) = 11 + (15 - 1)* 4 = 67

  Alexnet验证正确

  接下来看Vgg16的conv1_2对输入层的感受野求解,conv1_2为第二层

  F(2,1) = 第二层的kernel_size + (F(2,2) -1)*第二层的stride

  F(2,1) = 3

  F(2,0) = 第一层的kernel_size + (F(2,1) - 1)* 第一层的stride

  F(2,0) = 3 + (3 - 1)*2 = 5。

Vgg16验证正确

 

二.各层的输出和输入图像宽度和高度大小的关系

   outsize = (insize - fsize + 2*pad)/stride + 1,前者会向下求整

这里outsizes是输出图像的宽度和高度大小,insize是输入图像的宽度和高度大小,fsize表示该层的卷积核大小,stride表示卷积核的移动步长。

 

补充说明:

Tensorflow实战Google深度学习框架书里提到

全0填充时:

out = in/stride

这里out指被滤波器卷积后的图像大小,in指滤波前的图像大小,stride指步长  ,向上取整

 不使用全0填充时:

out = (in - filter + 1)/stride

这里out指被滤波器卷积后的图像大小,in指滤波前的图像大小,stride指步长, filter指滤波器的大小,向上取整

 

   首先来验证Alexnet的pool2的输出图像的outsize.(不按照书上)

   conv1_outsize = (224 - 11 + 2*0)/4 + 1 -> 54

   pool1_outsize = (54 - 3 + 2*0)/2 + 1 -> 26

   conv2_outsize = (26 - 5 + 2*2)/1 + 1 -> 26

   pool2_outsize = (26 - 3 + 2*0)/2 + 1 -> 12

  验证正确

  按照书上来的话,如果是全0填充,则:

  conv1_outsize = 224/4 = 56

  pool1_outsize = 56/2 = 28

  可知应该不是全0填充的,就不继续推导了,假设不全使用0填充,此时

  conv1_outsize = (224 - 11 + 1)/4 = 53.5 ~~54

  pool1_outsize = (54 - 3 + 1) / 2 = 26

  conv2_outsize = (26 - 5 + 1) / 1 = 22

  和上面的不对应,改为使用全0填

  conv2_outsize = 26 / 1 = 26

  pool2_outsize = (26 - 3 + 1)/2 = 12 (不全0填)

  conv3_outsize = (12 - 3 + 1)/1 = 10

  conv3_outsize = 12 / 1= 12(全0填)

  这边验证出:pad标记为0, 为不使用全0填充

                        pad标记为1,2等,为使用前全0填

   看vgg16的conv2_1的输出size

   conv1_1 = (224 - 3 + 2*1)/1 + 1 ->224

   conv1_2 = (224 - 3 + 2*1)/1 + 1 ->224

   pool1 = (224 - 2 + 2*0)/2 + 1 -> 112

  conv2_1 = (112 - 3 + 2*1) + 1 -> 112

  验证正确!

  按照书上的推导:

   conv1_1 = 224/1 = 224

   conv1_2 = 224/1 = 224

   pool1 = (224 - 2 + 1)/2 = 111.5 ~~112

这边验证出:pad标记为0, 为不使用全0填充

                        pad标记为1,2等,为使用前全0填

最后验证下zf-5网络

conv1 = (224 - 7 + 2*3)/2 = 111.5 ~~ 112

pool1 = (112 - 3 + 2*1)/2 = 55.5 ~~56

如果按照书上的推导:

全0填充:

conv1 = 224 / 2 = 112

不使用全0填充:

pool1 =  (224 - 7 + 1)/2 = 59

所以这里也验证出:

这边验证出:pad标记为0, 为不使用全0填充

                        pad标记为1,2等,为使用前全0填

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹叶青lvye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值