目标检测算法经典论文回顾(一)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了目标检测算法经典论文回顾(一)相关的知识,希望对你有一定的参考价值。

参考技术A 论文名称:Rich feature hierarchies for accurate object detection and semantic segmentation

提出时间:2014年

论文地址:https://openaccess.thecvf.com/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf

针对问题:

从Alexnet提出后,作者等人思考如何利用卷积网络来完成检测任务,即输入一张图,实现图上目标的定位(目标在哪)和分类(目标是什么)两个目标,并最终完成了RCNN网络模型。

创新点:

RCNN提出时,检测网络的执行思路还是脱胎于分类网络。也就是深度学习部分仅完成输入图像块的分类工作。那么对检测任务来说如何完成目标的定位呢,作者采用的是Selective Search候选区域提取算法,来获得当前输入图上可能包含目标的不同图像块,再将图像块裁剪到固定的尺寸输入CNN网络来进行当前图像块类别的判断。

参考博客: https://blog.csdn.net/briblue/article/details/82012575。

论文题目:OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks

提出时间:2014年

论文地址:https://arxiv.org/pdf/1312.6229.pdf

针对问题:

该论文讨论了,CNN提取到的特征能够同时用于定位和分类两个任务。也就是在CNN提取到特征以后,在网络后端组织两组卷积或全连接层,一组用于实现定位,输出当前图像上目标的最小外接矩形框坐标,一组用于分类,输出当前图像上目标的类别信息。也是以此为起点,检测网络出现基础主干网络(backbone)+分类头或回归头(定位头)的网络设计模式雏形。

创新点:

在这篇论文中还有两个比较有意思的点,一是作者认为全连接层其实质实现的操作和1x1的卷积是类似的,而且用1x1的卷积核还可以避免FC对输入特征尺寸的限制,那用1x1卷积来替换FC层,是否可行呢?作者在测试时通过将全连接层替换为1x1卷积核证明是可行的;二是提出了offset max-pooling,也就是对池化层输入特征不能整除的情况,通过进行滑动池化并将不同的池化层传递给后续网络层来提高效果。另外作者在论文里提到他的用法是先基于主干网络+分类头训练,然后切换分类头为回归头,再训练回归头的参数,最终完成整个网络的训练。图像的输入作者采用的是直接在输入图上利用卷积核划窗。然后在指定的每个网络层上回归目标的尺度和空间位置。

参考博客: https://blog.csdn.net/qq_35732097/article/details/79027095

论文题目:Scalable Object Detection using Deep Neural Networks

提出时间:2014年

论文地址:https://openaccess.thecvf.com/content_cvpr_2014/papers/Erhan_Scalable_Object_Detection_2014_CVPR_paper.pdf

针对问题:

既然CNN网络提取的特征可以直接用于检测任务(定位+分类),作者就尝试将目标框(可能包含目标的最小外包矩形框)提取任务放到CNN中进行。也就是直接通过网络完成输入图像上目标的定位工作。

创新点:

本文作者通过将物体检测问题定义为输出多个bounding box的回归问题. 同时每个bounding box会输出关于是否包含目标物体的置信度, 使得模型更加紧凑和高效。先通过聚类获得图像中可能有目标的位置聚类中心,(800个anchor box)然后学习预测不考虑目标类别的二分类网络,背景or前景。用到了多尺度下的检测。

参考博客: https://blog.csdn.net/m0_45962052/article/details/104845125

论文题目:DeepBox: Learning Objectness with Convolutional Networks

提出时间:2015年ICCV

论文地址:https://openaccess.thecvf.com/content_iccv_2015/papers/Kuo_DeepBox_Learning_Objectness_ICCV_2015_paper.pdf

主要针对的问题:

本文完成的工作与第三篇类似,都是对目标框提取算法的优化方案,区别是本文首先采用自底而上的方案来提取图像上的疑似目标框,然后再利用CNN网络提取特征对目标框进行是否为前景区域的排序;而第三篇为直接利用CNN网络来回归图像上可能的目标位置。

创新点:

本文作者想通过CNN学习输入图像的特征,从而实现对输入网络目标框是否为真实目标的情况进行计算,量化每个输入框的包含目标的可能性值。

参考博客: https://www.cnblogs.com/zjutzz/p/8232740.html

论文题目:AttentionNet: AggregatingWeak Directions for Accurate Object Detection

提出时间:2015年ICCV

论文地址:https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Yoo_AttentionNet_Aggregating_Weak_ICCV_2015_paper.pdf

主要针对的问题:

对检测网络的实现方案进行思考,之前的执行策略是,先确定输入图像中可能包含目标位置的矩形框,再对每个矩形框进行分类和回归从而确定目标的准确位置,参考RCNN。那么能否直接利用回归的思路从图像的四个角点,逐渐得到目标的最小外接矩形框和类别呢?

创新点:

通过从图像的四个角点,逐步迭代的方式,每次计算一个缩小的方向,并缩小指定的距离来使得逐渐逼近目标。作者还提出了针对多目标情况的处理方式。

参考博客: https://blog.csdn.net/m0_45962052/article/details/104945913

论文题目:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

提出时间:2014年

论文地址:https://link.springer.com/content/pdf/10.1007/978-3-319-10578-9_23.pdf

针对问题:

如RCNN会将输入的目标图像块处理到同一尺寸再输入进CNN网络,在处理过程中就造成了图像块信息的损失。在实际的场景中,输入网络的目标尺寸很难统一,而网络最后的全连接层又要求输入的特征信息为统一维度的向量。作者就尝试进行不同尺寸CNN网络提取到的特征维度进行统一。

创新点:

作者提出的SPPnet中,通过使用特征金字塔池化来使得最后的卷积层输出结果可以统一到全连接层需要的尺寸,在训练的时候,池化的操作还是通过滑动窗口完成的,池化的核宽高及步长通过当前层的特征图的宽高计算得到。原论文中的特征金字塔池化操作图示如下。

参考博客 :https://blog.csdn.net/weixin_43624538/article/details/87966601

论文题目:Object detection via a multi-region & semantic segmentation-aware CNN model

提出时间:2015年

论文地址:https://openaccess.thecvf.com/content_iccv_2015/papers/Gidaris_Object_Detection_via_ICCV_2015_paper.pdf

针对问题:

既然第三篇论文multibox算法提出了可以用CNN来实现输入图像中待检测目标的定位,本文作者就尝试增加一些训练时的方法技巧来提高CNN网络最终的定位精度。

创新点:

作者通过对输入网络的region进行一定的处理(通过数据增强,使得网络利用目标周围的上下文信息得到更精准的目标框)来增加网络对目标回归框的精度。具体的处理方式包括:扩大输入目标的标签包围框、取输入目标的标签中包围框的一部分等并对不同区域分别回归位置,使得网络对目标的边界更加敏感。这种操作丰富了输入目标的多样性,从而提高了回归框的精度。

参考博客 :https://blog.csdn.net/alfred_torres/article/details/83022967

论文题目:Fast-RCNN

提出时间:2015年

论文地址:https://openaccess.thecvf.com/content_iccv_2015/papers/Girshick_Fast_R-CNN_ICCV_2015_paper.pdf

针对问题:

RCNN中的CNN每输入一个图像块就要执行一次前向计算,这显然是非常耗时的,那么如何优化这部分呢?

创新点:

作者参考了SPPNet(第六篇论文),在网络中实现了ROIpooling来使得输入的图像块不用裁剪到统一尺寸,从而避免了输入的信息丢失。其次是将整张图输入网络得到特征图,再将原图上用Selective Search算法得到的目标框映射到特征图上,避免了特征的重复提取。

参考博客 :https://blog.csdn.net/u014380165/article/details/72851319

论文题目:DeepProposal: Hunting Objects by Cascading Deep Convolutional Layers

提出时间:2015年

论文地址:https://openaccess.thecvf.com/content_iccv_2015/papers/Ghodrati_DeepProposal_Hunting_Objects_ICCV_2015_paper.pdf

主要针对的问题:

本文的作者观察到CNN可以提取到很棒的对输入图像进行表征的论文,作者尝试通过实验来对CNN网络不同层所产生的特征的作用和情况进行讨论和解析。

创新点:

作者在不同的激活层上以滑动窗口的方式生成了假设,并表明最终的卷积层可以以较高的查全率找到感兴趣的对象,但是由于特征图的粗糙性,定位性很差。相反,网络的第一层可以更好地定位感兴趣的对象,但召回率降低。

论文题目:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

提出时间:2015年NIPS

论文地址:https://proceedings.neurips.cc/paper/2015/file/14bfa6bb14875e45bba028a21ed38046-Paper.pdf

主要针对的问题:

由multibox(第三篇)和DeepBox(第四篇)等论文,我们知道,用CNN可以生成目标待检测框,并判定当前框为目标的概率,那能否将该模型整合到目标检测的模型中,从而实现真正输入端为图像,输出为最终检测结果的,全部依赖CNN完成的检测系统呢?

创新点:

将当前输入图目标框提取整合到了检测网络中,依赖一个小的目标框提取网络RPN来替代Selective Search算法,从而实现真正的端到端检测算法。

参考博客 :https://zhuanlan.zhihu.com/p/31426458

自动驾驶激光点云 3D 目标检测 VoxelNet 论文简述

自动驾驶感知视觉有 2 个流派,分别是摄像头视觉和激光雷达视觉,本文分析激光雷达视觉当中经典的算法模型 VoxelNet。

论文:VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection

这是 2017 年的论文出自苹果公司算法团队,这篇论文对于刚学习激光雷达目标检测的同学来讲非常有参考价值。

图像和点云

摄像头对环境进行测量,产生的一般是 RGB 格式图片,图片上的一个像素通常有 rgb 3 个颜色通道的数据。
一般说图像数据是稠密的。
图像上的目标检测大多是 2D 的 bbox。
激光点云数据要做 3D 检测,效果如下图:

激光雷达也对环境进行测量,产生的是点云数据,所谓点云就是一个坐标有(x,y,z,r)这样的数据,xyz 代表 3 维坐标,r 代表信号反射强度。
一般说点云数据是稀疏的。
我在思考一个问题,稀疏和稠密是怎么区分的呢?
单论像素数量,一张分辨率为 1920*1080 的图片有 200 多万像素点,一个 128 线的激光雷达 1s 内大概传输 300 多万个点云数据,所以单论数量的话区分稀疏和稠密没有什么道理。
那大概是什么原因呢?
我认为是空间密度。

这张图片来自禾赛官网的产品效果示意。
可以看到有些地方点云很稠密,有些地方点云就很稀疏甚至没有。
而图片因为是像素排列,所以不存在稀疏的情况,透明或者黑色都是有相应的 RGB 数据进行存储的。
但点云就不一样,点云数据分布不均。
这引出来了一点问题:
用于激光点云处理的 CNN 模型必定和图像处理的模型有些不一样。
不一样的地方来自于点云数据的前期处理。

像素(pixel)和体素(voxel)

图片是 2 维的,单个点叫做像素。
点云是 3 维的,所有的点形成了点云,但可以想像用一个大的长方体能够把所有的点云装载进去。
点云是稀疏的,为了更高效处理这些数据,VoxelNet 运用了一种前期的处理手段那就是:Voxel Partition。

前面讲到可以想像用一个长方体装载所有的点云,为了更精细化处理,voxel partition 将这个长方体进行了切割,以固定的单元大小进行切割。
假设所有的点云就装载在一个盒子里面,这个盒子沿XYZ轴的尺寸分别是 WHD,假设要进行 voxel partition 操作,最小单元大小是 v w , v h , v d v_w,v_h,v_d vw,vh,vd,最终会产生一个 3D 网络,它的尺寸也可以通过数学公式求得。
D ′ = D / v d , H ′ = H / v h , W ′ = W / v w D'=D/v_d,H'=H/v_h,W'=W/v_w D=D/vd,H=H/vh,W=W/vw
一个最小的单元称为一个体素(voxel),体素中可能有点云,也可能没有点云,所以应对这种状态,最好的方法是要对每个 voxel 中的点云进行编码和特征学习。

VoxelNet 是一个端到端的网络模型,特征学习是它的第一步,它总共分为 3 大部分:

  • 特征学习网络
  • 中间卷积层
  • RPN
    论文中的示意图描述的非常清楚:

特征学习网络

VoxelNet 的特征学习分为这 5 个过程:

  1. Voxel Partition
  2. Grouping
  3. Random Sampling
  4. Stacked Voxel Feature Encoding
  5. Sparse 4D Tensor

Grouping

前面讲到 Voxel Partition,也讲到一个 Voxel 中点云的数量不一,数量不一的原因可能是因为距离、遮挡、相对位姿等等。Grouping 是将一个 Voxel 中的所有点云先进行一个简单的聚合。

Random Sampling

一般一帧点云的数量在 10W 以上,同时处理这么多数据硬件开销很大,最好的方式就是采样。
VoxelNet 采用随机采样,每个 Voxel 固定采集 T 个数量的点云,T 是超参数,在实际业务中可能根据点云数量会不同。
Random Sampling 除了能减少计算量外,还有有效降低因为每个 voxel 点云数据不均带来的信息偏差,提高训练效率。

Stacked Voxel Feature Encoding

Voxel Feature Encoding 简称 VFE,是 VoxelNet 中的核心思想,主要目的是对点云进行特征编码。

这一部分需要好好研究一下。

Stacked Voxel Feature Encoding 自然就是一系列堆栈式的编码层,其实核心思想是产生好几个层次的特征表示。


第 1 级层次是点云级的输入。

前面讲到一个非空的 Voxel 中会取样 T 个点云,VoxelNet 作者设定了如下表达式:

i 代表 Voxel 中取样的 T 个点云中的第 i 个。
x,y,z 自然是点云位置信息。
r 是反射率。
有了表达式后,首先要做的是什么呢?
计算质心.
质心用 ( v x , v y , v z ) (v_x,v_y,v_z) (vx,vy,vz)表示。
然后通过计算每个点云和质心的偏移量,得到点云的增广表达式。
V i n = p ^ i = [ x i , y i , z i , x i − v x , y i − v y , z i − v z ] T ∈ R 7 i = 1... t V_in=\\left \\\\hatp_i=[x_i,y_i,z_i,x_i-v_x,y_i-v_y,z_i-v_z]^T\\in \\mathbbR^7\\right \\_i=1...t Vin=p^i=[xi,yi,zi,xivx,yivy,zivz]TR7i=1...t
由原始输入的 4 维扩展到 7 维。
然后每个 p i p_i pi要经过一个FCN全连接处理转换到特征空间。
f i f_i fi代表特征空间中每个向量,它能从Voxel中获取到形状信息。
上面讲的是点云级别,接下来处理元素级别。
思路也很简单,就要是通过 Maxpooling 得到 Voxel 中的一些局部聚合特征(locally aggregated feature),用 f ~ \\tildef f~表示。
最后,每个 point-wise feature 和 locally aggregated feature 进行拼接,得到最终的feature,表示如下:

上面讲的是单个 Voxel 的编码操作,对于其它 Voxel 操作步骤是一样的,但所有的 Voxel 对应同一个 FCN。
前面表述的是 VFE1,而 VoxelNet 中划分了许多个 Voxel,每个Voxel 都有对应的 VFE,用 V F E − i ( C i n , C o u t ) VFE-i(C_in,C_out) VFEi(Cin,Cout)表示。
in代表输入input_feature 的通道数,out 表示编码后的通道数量。
其中,经过线性变换中需要学习一个 Matrix,尺寸是 C i n ∗ ( C o u t / 2 ) C_in*(C_out/2) Cin(Cout/2),后面通过 Maxpooling 操作补齐了 out 这个数量,具体操作参见 VFE-1 分析过程。

Sparse Tensor Representation

因为划分 Voxel 的时候,90% 的 Voxel 都是空的,所以,VoxelNet 只处理非空 Voxel 能有效节省计算量。
Voxel 编码后可以用4D Tensor 表示,尺寸 C ∗ D ′ ∗ H ′ ∗ W ′ C*D'*H'*W' CDHW
如图所示:

常规卷积层(Convolutional Middle Layers)

VFE 编码后的数据会送到一系列常规的卷积层当中,作为中间过程。


C o n v M D ( c i n , c o u t , k , s , p ) ConvMD(c_in, c_out, k, s, p) ConvMD(cin,cout,k,s,p)表示卷积操作。
M 代表卷积维度。
k 是卷积核尺寸
s 是卷积当中的 stride
p 是卷积当中的 pading

一个卷积中间层格式是:

Conv3D->BN Layer->Relu Layer

RPN

RPN 这个概念来源于 Faster R-CNN 系列,VoxelNet 中也运用到了 RPN,但经过了改良。

论文中提到,RPN 中的 FCN网络分为 3 块。

每一块都会实现 2x 效果的下采样率。
然后,又实现了向上采样,将倒数 3 块上采样到固定的尺寸,然后拼接起来。

最终,由上采样拼接后的卷积引出 2 个目标分支:

  • 分支 1:概率图
  • 分支2:回归图

注意它们的尺寸,概率图通道数是 2,代表正负 anchor 的概率,这个概率应该通过 softmax 处理过。
回归图的通道数是 7,代表的就是一个 anchor 的 3D 信息(x,y,z,l,w,h,theta)。

Loss Function

除了神经网络模型外,Loss Function 怎么设定成为最重要的事情。
因为有 Anchor 的存在,要计算 3D 框的信息自然就会引入 offset。
VoxelNet 对于 Anchor 有正负之分。
Loss 也离不开 GroundTruth。
在 VoxelNet 中 GroundTruth 表示如下:

Anchor 的正样本表示如下:

其中 θ \\theta θ是3D目标的偏航角.
u ∗ u* u代表残差。

这里不是单纯的残差,x,y,z 的残差经过了归一化操作。

分母是 da,也就是 anchorbox 的对角线长度.
求 l,w,h 的残差时是求比例然后 log 函数缩放.
求 theta 角倒是真正意义上的残差.
最终 Loss Function 定义如下:

总体 Loss 由 2 部分组成:

  1. 分类 Loss
  2. 回归 Loss

其中分类 Loss 计算的是 anchorbox 的正样本概率和负样本概率的二分交叉熵.
α \\alpha α β \\beta β是用来平衡的。
而回归当中的 loss 只计算正样本,采用 Smoth Loss L1 方法。
μ i \\mu_i μi 代表前面 RPN 的输入, μ ∗ \\mu* μ前面提到过是 Groundtruth 和 正样本的残差.

高效处理

GPU 处理稠密数据时非常有效,但点云数据是很稀疏的,所以,要高效处理就需要做一些数据处理。

VoxelNet 给出的答案是复用缓存。

缓存的尺寸是 K × T × 7。
K 代表最大数量的非空 Voxel。
T 代表一个 Voxel 中点云最多数量.
7 是指经编码后的尺寸.

核心思想就是类 HashTable 的形式。

  • 如果一个 Voxel 还未初始化,就初始化,再插入点云
  • 如果一个 Voxel 已经初始化就复用,在 < T 的情况下插入点云
  • 如果一个 Voxel 已经初始化,但其中点云数量等于 T 则不插入新的点云

经过缓存处理后,稀疏的点云能够变成稠密的数据,之后再经过中间卷积层和RPN处理,GPU能够更加高效。

训练相关

本文的重心是介绍 VoxelNet 算法思想,所以其它的就稍微带过一下。

VoxelNet 相关训练是以 KITTI 数据集为基础的,涉及到 2 大类别子数据集合

  • 汽车
  • 行人和自行车

两种子数据集对应的 Voxel size 是一样的 DHW 分别是 0.4x0.2x0.2。
但因为汽车、行人、自行车的尺寸不一样,所以,anchor 的尺寸自然也要不一样。
anchor 尺寸本质就是现实世界中某一类别的平均尺寸。

  • 汽车 anchor size: l,w,h[3.9,1.6,1.56]
  • 行人 anchor size:l,w,h[0.8,0.6,1.73]
  • 自行车 anchor sizel,w,h[1.76,0.6,1.8]

另外,为了捕捉更丰富的信息,每种大类 Voxel 中 T 的数量是不一样的。

  • 汽车 T = 35
  • 行人自行车 T= 45

IOU的计算是针对鸟瞰图而言的,汽车和行人阈值也不一样。

  • 汽车,> 0.6 正样本,< 0.45 负样本,其它忽略
  • 行人自行车,> 0.5 正样本,< 0.35 负样本,其它忽略

本质上还是因为类别的尺寸不一样。

数据增强

在论文中数据增强洋洋洒洒写了 3 段,核心思想无非就是提出一种“pertutation"的操作。

  1. 将 3D box 绕 Z 轴旋转一定角度,然后 xyz 施加随机范围内的偏移量。
  2. 对所有的点云施加全局的缩放效果。
  3. 对所有点云施加全局的旋转效果。

第一个操作无非是增加数据,后面 2 个是为了提高网络的鲁棒性表现。

更详细的操作请阅读原论文。

性能表现

因为是几年前的模型,所以,这里就不张贴相应的模型评估结果了。
但我注意到的一个细节是,在 TitanX 显卡上,VoxelNet 跑一帧需要 225ms。

对比图像目标检测的模型,yolo 系列能轻松达到 17ms 的推断时间,VoxelNet 当然不算快。

即使不与 YOLO 比,单纯这 225ms 推断时间也无法说明别人你与实时性有任何关系。

总结

VoxelNet 非常优秀,值得好好学习,它价值体现在这 4 点:

  1. 提出了一种 end-to-end 的点云处理网络模型;
  2. 有效表达了点云数据,形成了一种稀疏的数据到稠密数据的处理能力;
  3. 改良并融合了 RPN,提升了目标检测的性能。

以上是关于目标检测算法经典论文回顾(一)的主要内容,如果未能解决你的问题,请参考以下文章

论文解读Faster R-CNN 实时目标检测

Domain Adaptive Faster R-CNN:经典域自适应目标检测算法,解决现实中痛点,代码开源 | CVPR2018

自动驾驶激光点云 3D 目标检测 VoxelNet 论文简述

自动驾驶激光点云 3D 目标检测 VoxelNet 论文简述

经典论文解读YOLOv3 目标检测

目标检测 | 经典算法 Cascade R-CNN: Delving into High Quality Object Detection