目标检测系列——R-CNN

R-CNN

R-CNN是最初深度神经网络为基础的物体检测的模型 之一,在VOC2007数据集上平均精度达到66%,后续的SPPNet、Fast R-CNN、Faster R-CNN等模型均是按照这个思路。
模型框架如下:
在这里插入图片描述

1、R-CNN结构

简要的讲一下算法流程:

  • 1、首先从图片中找到可能存在目标的候选区域,大约2000个,统一大小
    • 通过选择性搜索(SS)算法进行筛选
    • 大小统一:crop+wrap
  • 2、进行CNN提取特征,得到2000个特征向量
    • 使用AlexNet模型,输入尺寸为227 * 227
    • 提取出的特征保存在磁盘中
  • 3、20个SVM分类器进行分类,得到2000 * 20 的得分矩阵
    • 20:代表当前数据集一共需要检测20个类别
    • 得到[2000, 20]的得分矩阵
  • 4、进行NMS,提取候选框
  • 5、修正bbox, 对bbox做回归微调
    • 通过线性回归,特征值是候选区域坐标,目标的对应GT的坐标
    • 建立回归方程学习参数

1.1 Region Proposals

1.1.1 选择性搜索算法(Selective Search, SS)

使用SS算法 来寻找候选框,首先将每个像素作为一组。然后,计算每一组的纹理,并将两个最接近的组结合起来。但是为了避免单个区域吞噬其他区域,我们首先对较小的组进行分组。我们继续合并区域,直到所有区域都结合在一起。
使用SS算法在一张图片提取大约2000个候选区域,但是,这些 候选区域的长宽是不固定的。

1.1.1 Crop + Warp

由于传统的CNN的输入需要固定大小,所以使用Crop和Wrap来讲候选区域的尺寸统一成固定大小

  • Crop:截取原图片的一个固定大小的patch
  • warp: 将原图片的ROI缩放到一个固定大小的patch

1.2 CNN提取特征

将这2000个统一大小的候选区域,送入预训练的CNN网络中提取特征,并将这些特征保存到磁盘中(这些特征才是真正的要训练的数据)
在这里插入图片描述

1.3 特征向量训练SVM分类器

假设一张图片的2000个侯选区域,那么提取出来的就是2000 x 4096这样的特征向量(R-CNN当中默认CNN层输出4096特征向量)。那么最后需要对这些特征进行分类,R-CNN选用SVM进行二分类。假设检测20个类别,那么会提供20个不同类别的SVM分类器,每个分类器都会对2000个候选区域的特征向量分别判断一次,这样得出[2000, 20]的得分矩阵,如下图所示
在这里插入图片描述

  • 每个SVM分类器:判断2000个候选区域是属于某类别还是背景

1.4 非极大值抑制(NMS)

  • 目的:对候选区域进行筛选,得到最终的候选框
  • 算法流程:
    • 对于所有的2000个候选区域得分进行概率筛选
    • 然后对剩余的候选框,每个类别进行IOU>=0.5筛选
      举例:
      在这里插入图片描述

假设有滑动窗口A、B、C、D、E共5个候选框:

  • 首先,找到这5个候选框中得分最高的,为C,再将其余候选框与C做IOU计算,若>阈值(0.5),则删去,B和D满足该条件,故删去B和D,筛选出了候选框C
  • 循环第二次筛选,剩下了A和E两个候选框,其中A得分最高,E与A做IOU计算得到0.7,大于阈值0.5,删去E,筛选出了候选框A
  • 最终筛选出了A和C两个候选框

NMS代码

import numpy as np
import matplotlib.pyplot as plt


def plot_bbox(dets, c='k'):
    x1 = dets[:,0]
    y1 = dets[:,1]
    x2 = dets[:,2]
    y2 = dets[:,3]
    
    plt.plot([x1,x2], [y1,y1], c)
    plt.plot([x1,x1], [y1,y2], c)
    plt.plot([x1,x2], [y2,y2], c)
    plt.plot([x2,x2], [y1,y2], c)
    

    
def py_cpu_nms(dets, thresh):
    """
    dets: (m, 5)
    dets[0] = [x1, y1, x2, y2, score]
    thresh: IOU阈值
    """
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    keep = []    # 用来保存筛选出的候选框
    # argsort(): 返回数组值从小到大的索引
    index = scores.argsort()[::-1]    # index为scores中值从大到小的索引
    
    while index.size>0:
        i = index[0]  # 每次循环中剩余bbox得分最大值的索引
        keep.append(i)
        
        # 重叠区域的坐标
        x11 = np.maximum(x1[i], x1[index[1:]])
        y11 = np.maximum(y1[i], y1[index[1:]])
        x22 = np.minimum(x2[i], x2[index[1:]])
        y22 = np.minimum(y2[i], y2[index[1:]])
        
        # 重叠区域的宽高
        w = np.maximum(0, x22-x11+1)
        h = np.maximum(0, y22-y11+1)
        
        # 重叠区域面积
        overlaps = w * h
        ious = overlaps / (areas[i]+areas[index[1:]]-overlaps)
        
        idx = np.where(ious<=thresh)[0]
        index = index[idx+1]
    
    return keep

1.5 修正候选区域

对于SS算法得到的候选区域并非是非常准确的,所以需要对其进行修正

  • 默认候选框和其对应的GT框是线性关系,因为在最后筛选出来的候选区域和GT已经非常接近了
    修正过程
    候选区域(px,py,pw,ph)经过参数学习得到预测值(px’,py’,pw’,ph’), 预测值和GT(tx,ty,tw,th)计算损失,不断优化得到最终的结果
  • 给定anchor A = ( A x , A y , A w , A h ) A=(A_x,A_y, A_w, A_h) A=(Ax,Ay,Aw,Ah)和GT=(G_x, G_y, G_w, G_h)
  • 找到一种变换F,使得:
    F ( A x , A y , A w , A h ) = ( G x ′ , G y ′ , G w ′ , G h ′ ) F(A_x,A_y, A_w, A_h) = (G_x', G_y', G_w', G_h') F(Ax,Ay,Aw,Ah)=(Gx,Gy,Gw,Gh), 其中 ( G x ′ , G y ′ , G w ′ , G h ′ ) ≈ ( G x , G y , G w , G h ) (G_x', G_y', G_w', G_h') \approx (G_x, G_y, G_w, G_h) (Gx,Gy,Gw,Gh)(Gx,Gy,Gw,Gh)
    在这里插入图片描述

2、R-CNN训练过程

训练流程:正负样本准备+预训练+微调网络+训练SVM+训练边框回归

2.1 正负样本准备

对于训练集的所有图像,使用SS算法得到候选区域,对于1张图像得到2000个候选区域,但是每个图像不是所有的候选区域都会拿去训练。通常保证正负样本比例为1:3

  • 正样本:某个候选区域和当前图像上所有GT中重叠面积最大的那个GT的IOU大于等于0.5,则该候选区域作为这个GT类别的正样本
  • 负样本:某个候选区域和当前图像所有GT中重叠面积最大的那个GT的 IOU小于0.5,则该候选区域作为这个GT的负样本

2.2 预训练

拿别人已经训练好的模型拿过来,比如在ImageNet数据集上已经训练好的AlexNet模型

2.3 微调

  • 将AlexNet最后的全连接层的输出类别数,改成自己数据集的类别数
  • 把第一步得到的正负样本进行尺寸变换,统一大小,送入预训练好的网络中,继续训练网络,得到最终的CNN网络

2.4 SVM分类器

将上一步CNN网络输出的特征向量保存下来,用于训练SVM分类器,每个类别训练一个SVM分类器

2.5 bbox回归训练

  • NMS算法筛选出候选框
  • 只对筛选出的候选框进行线性回归

3 R-CNN测试过程

  • 使用SS算法在原图中提取出2000个候选区域
  • 将这2000个候选区域的尺寸统一大小,送入CNN网络中提取特征,保存下来(2000,4096)
  • 将提取的特征训练SVM分类器中,一个类别训练一个SVM分类器,20个类别训练20个SVM分类器,最终得到(2000,20)的得分矩阵
  • 根据(2000, 20)的得分矩阵,对候选区域用NMS算法筛选出最终的候选框
  • 将这最终的候选框进行bbox线性回归

4 R-CNN的缺点

1、训练阶段多:步骤繁琐: 微调网络+训练SVM+训练边框回归器。

2、训练耗时:占用磁盘空间大:5000张图像产生几百G的特征文件。(VOC数据集的检测结果,因为SVM的存在)

3、处理速度慢: 使用GPU, VGG16模型处理一张图像需要47s。

4、图片形状变化:候选区域要经过crop/warp进行固定大小,无法保证图片不变形

参考文献:
[1] 非极大值抑制的几种实现
[2] 一文读懂目标检测:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值