目标检测,即在一幅图里框出某个目标位置.有2个任务.算法
一种暴力的目标检测方法就是使用滑动窗口,从左到右,从上到下扫描图片,而后用分类器识别窗口中的目标.为了检测出不一样的目标,或者同一目标但大小不一样,必须使用不一样大小,不一样宽高比的滑动窗口.
windows
把滑动窗口框出来的图片块resize(由于不少分类器只接受固定大小的图片输入)后,送给CNN分类器,CNN提取出4096个特征.而后使用SVM作分类,用线性回归作bounding box预测.
网络
伪代码以下性能
for window in windows patch = get_patch(image, window) results = detector(patch)
提升性能的一个明显的方法就是减小window数量.测试
相比于暴力搜索,咱们使用一种区域建议(region proposal)方法去建立roi(感兴趣区域region of intrest).在selective search(SS)中,咱们从将每个像素做为一个group开始,接下来咱们计算每个group的texture,而后合并最接近的group.为例避免某个区域吞并了其余区域,咱们优先合并较小的group,不断的合并各个group直到不能再合并了.以下图:第一行图显示了region是怎么不断地增加的,第二行的蓝色框显示了在不断地合并的过程里,是怎么产生ROI的.
ui
R-CNN采起区域建议方法建立2000个ROI.而后这些区域的图片被送到CNN,提取特征,而后送给全链接层作边界框预测和类别预测
流程以下:
3d
因为有了数量少质量高的ROI,R-CNN相比于暴力的滑动窗口搜索,要快的多,也准确的多.rest
ROIs = region_proposal(image) for ROI in ROIs patch = get_patch(image, ROI) results = detector(patch)
区域建议方法是须要大量算力的.为了加速ROI寻找的过程,咱们每每选择一个不须要巨量算力的区域建议方法来建立ROI,再用线性回归器(使用全链接层)对边界框作微调.
code
R-CNN须要大量的ROI,而且这些ROI不少都是重叠的.因此R-CNN在不管是训练仍是推理都很慢.若是咱们有2000个建议区域,每个都要被CNN处理一次,也就是说,对于不一样的ROI,特征提取重复了2000次.orm
换个思路,对整幅图片作特征提取,而后在特征图的基础上作ROI的查找.经过池化层作resize,而后送给全链接层作边界框预测和分类.因为只作了一次特征提取,Fast R-CNN的性能显著提升.
流程以下:
伪代码以下:
feature_maps = process(image) ROIs = region_proposal(image) for ROI in ROIs patch = roi_pooling(feature_maps, ROI) results = detector2(patch)
因为把特征提取这一步抽到了for循环外部,性能大幅提高.相比R-CNN,Fast R-CNN在训练上快了10倍,推理上快了150倍.
Fast R-CNN的一个要点是整个网络(包括特征提取,分类,边界框回归)是端到端的训练,而且采用了multi-task losses(分类loss + 边界框定位loss),提升了准确率.
因为Fast R-CNN使用全链接层,咱们采用ROI池化,把不一样size的ROI转换成固定size.
以8*8的特征图转换为2*2为例
而后就能够把这些2*2的特征图送给分类器和线性回归器去作分类和边界框预测了.
Fast R-CNN依赖于区域建议方法,好比selective search.可是,这些算法只能跑在cpu上,速度很慢.在测试中,Fast R-CNN作出一次预测要2.3秒,其中2秒都花在了生成2000个ROI.
feature_maps = process(image) ROIs = region_proposal(image) # Expensive! for ROI in ROIs patch = roi_pooling(feature_maps, ROI) results = detector2(patch)
在流程上,Faster R-CNN与Fast R-CNN是一致的,只是将获得ROI的方式改成由一个region proposal network(RPN)获得.RPN效率要高的多,每张图生成ROI的时间仅在10ms.
RPN接受卷积网络输出的特征图做为输入,用以下的ZF网络作区域建议.也能够用其余的网络好比VGG或者ResNet去作更全面的特征提取,代价是速度的降低.ZF网络输出256个值,送到两个全链接层,一个用于预测边界框(boudary box),一个用于预测2个objectness scores.objectness衡量bounding box是否包含一个object.咱们能够用一个回归器去计算出一个single objectness score.可是为简单起见,Fast R-CNN使用一个分类器,分类器分出的类别有2种:即包含目标和不包含.
对特征图中的每个位置,RPN作出k个猜想.因此RPN输出4*k个坐标,2*k个score.以下表示对一个8*8的特征图,用3*3的filter,最终获得8*8*3个ROI.
后面咱们将继续微调咱们的猜想.因为咱们须要有一个正确的猜想,咱们初始化的猜想最好有不一样的shape,不一样的size.因此,Faster R-CNN不是随机乱猜的边界框,它预测相对于咱们称之为anchors的参考框(reference box)左上角的偏移.咱们限定偏移的大小,这样咱们最终预测出的bounding box依然是与anchors相似的.
为了每一个位置可以获得k个预测,每一个位置须要k个anchor.每个预测都与一个特定的anchor有关.不一样的位置共享一样的anchor shape.
这些anchors不是瞎选的,要尽量地覆盖到real-life objects,而且要尽可能有合理的尺度和宽高比.这样可使得每次的prediction更准确.这个策略使得训练的早期能够更容易更稳定.
Faster R-CNN uses far more anchors. It deploys 9 anchor boxes: 3 different scales at 3 different aspect ratio. Using 9 anchors per location, it generates 2 × 9 objectness scores and 4 × 9 coordinates per location.
假设一下咱们只有一个检测脸部中右眼的feature map,咱们能够用它来定位整张脸吗?答案是确定的,由于右眼位于面部的左上角,因此咱们能够用来定位整张脸.
若是咱们有其余专门用于检测左眼、鼻子或嘴巴的特征图,咱们能够将这些结果结合起来,更好地定位人脸.
在Faster R-CNN中,咱们最终会将整幅图片的feature map切成相应的roi对应的feature map,再送给多个全链接层去作预测.有2000个ROI的时候,这一步的代价是很高昂的.
feature_maps = process(image) ROIs = region_proposal(feature_maps) for ROI in ROIs patch = roi_pooling(feature_maps, ROI) class_scores, box = detector(patch) # Expensive! class_probabilities = softmax(class_scores)
R-FCN经过减小每个roi的处理时间提速.下面是伪代码
feature_maps = process(image) ROIs = region_proposal(feature_maps) score_maps = compute_score_map(feature_maps) for ROI in ROIs V = region_roi_pool(score_maps, ROI) class_scores, box = average(V) # Much simpler! class_probabilities = softmax(class_scores)
考虑一个5*5的feature map,其中蓝色部分的feature构成了咱们想要检测的object.咱们将蓝色部分划分为3*3的区域.如今咱们能够建立一个新的feature map,仅仅用来检测object的top left corner(TL).以下:
因为咱们将object分红了9个部分,咱们从整幅图的feature map中获得9个feature map,每个feature map负责检测object的相应区域.这些feature map咱们称之为position-sensitive score maps,由于每一个map都只detect(scores)一个object的子区域.
假设下图的红色虚线框是ROI.咱们将其划分红3*3的区域,而后考虑每一个区域包含目标的对应位置的可能性.例如,top-left ROI区域包含左眼的可能.咱们把结果存储在一个3*3的vote array里.好比,vote_array[0][0]存储了一个score,表示咱们是否发现了目标的top-left region.
这个依据score map和ROI获得vote array的过程称之为position-sensitive ROI-pool.这个过程和前文提过的ROI pool很相似.
计算出全部的值之后,取平均,就获得了class score.
假设咱们有C种目标待检测.咱们扩展为C+1种,即包含一种class for the background(non-object).每一种目标都有本身的3*3个score map.因此一共有(C+1)*3*3个score maps.使用这些score maps咱们能够为每个类别都算出一个class score.而后用softmax能够计算出每个类别的class probability.
总体流程以下,下图中k=3.
R-FCN的一个示例
原文link:https://medium.com/@jonathan_hui/what-do-we-learn-from-region-based-object-detectors-faster-r-cnn-r-fcn-fpn-7e354377a7c9