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的各层结构做了详细介绍。

  来验证博客点击打开链接中的推导值:

  

 首先来验证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。


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

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

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

   首先来验证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

  验证正确

   看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

  验证正确!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章