首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原始图片中的ROI如何映射到到feature map?

原始图片中的ROI如何映射到到feature map?

作者头像
用户1908973
发布2018-07-24 17:16:08
1.1K0
发布2018-07-24 17:16:08
举报
文章被收录于专栏:CreateAMindCreateAMindCreateAMind

https://zhuanlan.zhihu.com/p/24780433

首发于晓雷机器学习笔记

原始图片中的ROI如何映射到到feature map?

晓雷

3 个月前

在SPP-net中的难点一曾提到:ROI如何对应到feature map?

这个地方遇到不少坑,看了很多资料都没有太明白,感觉太绕。

先数数遇到的坑:

  • 《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》原文是这样写的,一脸懵逼。
  • 找了张图是这样画的:有那么点意思,好像是从前向后推出各个层的感受野,可是还是不懂为啥这样。
  • 这两张图,看的有点摸不着头脑
  • 接着找了何凯明在ICCV2015上演讲的PPT:《 iccv2015_tutorial_convolutional_feature_maps_kaiminghe.》,算是有了点眉目。可是还是不造咋回事,只知道有那么个公式,却不知道怎么推出来的,满心的疑惑。

回归正题

最后找到一篇靠谱的文章 卷积神经网络物体检测之感受野大小计算 - machineLearning - 博客园,它给出了一个不错的启发,还附带了代码,最关键的是它给出了参考链接。 于是我终于在参考链接找到了这篇 Concepts and Tricks In CNN(长期更新) 最佳博文,不仅清晰易懂,而且公式详细。(不过感觉略有不足,所以下面就详细介绍一下这个大坑)

【先说说感受野的计算】

回忆一下我之前在 卷积神经网络(CNN)简介 里就曾经画图推导过的一个公式(这个公式很常见,可是竟然很少有人去讲它怎么来的,当时我在写 CNN简介就顺便画图推导了一下,没细看的同学可以回头看看)

原文里提到:隐藏层边长(输出的边长) = (W - K + 2P)/S + 1 (其中 W是输入特征的大小,K是卷积核大小,P是填充大小,S是步长(stride))

为了理解方便我就把公式先用英文写一下:

output field size = ( input field size - kernel size + 2*padding ) / stride + 1

(output field size 是卷积层的输出,input field size 是卷积层的输入)

反过来问你: 卷积层的输入(也即前一层的感受野) = ?

答案必然是: input field size = (output field size - 1)* stride - 2*padding + kernel size

再重申一下:卷积神经网络CNN中,某一层输出结果中一个元素所对应的输入层的区域大小,被称作感受野receptive field。感受野的大小是由kernel size,stride,padding , outputsize 一起决定的。

从Concepts and Tricks In CNN(长期更新) 里截张图你感受一下:

公式化一下:

  • 上面只是给出了 前一层在后一层的感受野,如何计算最后一层在原始图片上的感受野呢? 从后向前级联一下就可以了(先计算最后一层到倒数第二层的感受野,再计算倒数第二层到倒数第三层的感受野,依次从后往前推导就可以了)

卷积神经网络物体检测之感受野大小计算 - machineLearning - 博客园 中用如下核心代码计算了 Alexnet zf-5和VGG16网络每层输出feature map的感受野大小。

net_struct = {'alexnet': {'net':[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0]],
                   'name':['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5']},
       'vgg16': {'net':[[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],
                        [2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0]],
                 'name':['conv1_1','conv1_2','pool1','conv2_1','conv2_2','pool2','conv3_1','conv3_2',
                         'conv3_3', 'pool3','conv4_1','conv4_2','conv4_3','pool4','conv5_1','conv5_2','conv5_3','pool5']},
       'zf-5':{'net': [[7,2,3],[3,2,1],[5,2,2],[3,2,1],[3,1,1],[3,1,1],[3,1,1]],
               'name': ['conv1','pool1','conv2','pool2','conv3','conv4','conv5']}}

imsize = 224

def outFromIn(isz, net, layernum):#从前向后算输出维度
    totstride = 1
    insize = isz
    for layer in range(layernum):
        fsize, stride, pad = net[layer]
        outsize = (insize - fsize + 2*pad) / stride + 1
        insize = outsize
        totstride = totstride * stride
    return outsize, totstride

def inFromOut(net, layernum):#从后向前算感受野 返回该层元素在原始图片中的感受野
    RF = 1
    for layer in reversed(range(layernum)):
        fsize, stride, pad = net[layer]
        RF = ((RF -1)* stride) + fsize
    return RF

【再谈谈感受野上面的坐标映射 (Coordinate Mapping)】

为了完整性直接摘录博客内容了:

通常,我们需要知道网络里面任意两个feature map之间的坐标映射关系(一般是中心点之间的映射),如下图,我们想得到map 3上的点p3映射回map 2所在的位置p2(橙色框的中心点)

计算公式:

  • 上面是计算任意一个layer输入输出的坐标映射关系,如果是计算任意feature map之间的关系,只需要用简单的组合就可以得到,下图是一个简单的例子:

最后说一下 前面那张PPT里的公式。

SPP-net的ROI映射做法详解

SPP-net 是把原始ROI的左上角和右下角 映射到 feature map上的两个对应点。 有了feature map上的两队角点就确定了 对应的 feature map 区域(下图中橙色)。

如何映射?

个人理解采取这样的策略是因为论文中的映射方法(左上右下映射)会导致feature map上的区域反映射回原始ROI时有多余的区域(下图左边红色框是比蓝色区域大的)

参考:

《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CreateAMind 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原始图片中的ROI如何映射到到feature map?
    • 先数数遇到的坑:
      • 回归正题
        • SPP-net的ROI映射做法详解
        • 参考:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档