基于Tensorflow学习神经网络-目标检测

8. Object Detection(RCNN-RPN-YOLO-)
https://handong1587.github.io/deep_learning/2015/10/09/object-detection.html
http://blog.csdn.net/invadertroy/article/details/76253778
https://www.cnblogs.com/skyfsm/p/6806246.html
http://blog.csdn.net/hx921123/article/details/55804685?locationNum=3&fps=1
任务:找出图像中所有目标的位置,包含一个或多个目标。如下图


DPM(Deformable Part Model-传统算法)
http://blog.csdn.net/ttransposition/article/details/12966521
思路:用Hog算子计算梯度方向直方图,提取特征,用SVM训练得到物体的梯度主模型(模型1)。将模型拆分成多个子模型(模型2,子模型分辨率是主模型分辨率的两倍),应对目标动作变化;建立多个模型应对视角变化。计算模型的匹配度,减去子模型位置偏移(模型3)损失,即目标得分。
子模型得分如下,在一定分为内寻找综合匹配和形变最优的位置。
缺点:传统算法提取人工设定特征(如Haar、Hog),检测时需滑动窗口依次判断所有可能区域,RCNN网络则会预先提取可能性高的目标候选区域,在候选区域提取特征进行判断;并用神经网络提取特征代替人工特征。
RCNN(Region CNN,2013.11)
http://www.cnblogs.com/soulmate1023/p/5530600.html
http://blog.csdn.net/hjimce/article/details/50187029
http://blog.csdn.net/shenxiaolu1984/article/details/51066975
RCNN算法步骤:为每张图像生成1K-2K个候选区域,对候选区域用深度网络提取特征,用SVM分类器进行分类(与传统方法相同),适用回归器修正候选框位置。

候选区域
数据:PASCAL训练集。
a.将图像分割成小区域,b.合并区域(规则:颜色、纹理、合并后面积小、占BBox面积大)直到全部合并,c.所有中间区域都是候选区域。
特征提取
预训练:直接用AlexNet网络(直接采用其参数)对ILVCR数据进行训练,分类网络。
调优训练:将PASCAL数据的候选区域归一化(尺寸归一化对性能有所影响,采用直接缩放的方式,无视横纵比)作为训练集,候选区A与PASCAL数据对应标签区域B的IOU大于0.5(作者调优测试0.3最佳)即认为是目标,否则认为是背景,训练优化AlexNet网络参数。

分类
PASCAL数据对应标签区域B作为正样本,候选区A与B的IOU小于0.3作为负样本,AlexNet网络F7层作为特征,训练SVM分类器进行分类。
为什么不直接用CNN分类?因为测试效果好。。。
区域选取和修正
区域选取:极大值抑制选取目标矩形框(选择所有矩形中分值最大的区域,将与其重叠较大的区域去掉,在剩下的区域中迭代进行上述操作,找到所有保留的矩形)。
区域修正:训练线性回归器,样本为与B的IOU大于0.6的候选区,输入为AlexNet网络Pool5特征,输出为xy方向缩放和平移。用该回归器进行位置修正。
缺点
输入图像尺寸需要归一化,可能导致信息丢失。(SPPNet改进)
训练测试时速度慢,一张图像内候选大量重叠,提取特征操作冗余。(SPPNet改进)
训练所需空间大,分类器和回归器独立。(Fast-RCNN改进)
预选区域与CNN分离。(Faster-RCNN改进出RPN网络,YOLU真正将两问题融合)
SPPNet(Spatial Pyramid Pooling,空间金字塔池化网络,2014.6)
Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
http://blog.csdn.net/v1_vivian/article/details/73275259
对图像进行裁剪或变形缩放,会导致信息丢失,SPPNet可接收任意尺度输入;改进特征提取,解决计算冗余导致效率低的缺陷。解决缺陷1、2,其它与RCNN一致。
Spatial Pyramid Pooling
在卷积层和全连接层之间加入金字塔池化层,使输出特征维度一致。实现见下图:将4*4、2*2、1*1三个网格放到特征图上,每个块提取一个特征,共21维特征,作为全连接层输入。

特征提取优化
原图一次卷积得到整张Feature map,然后找到候选框在Feature map上对应位置(卷积后尺寸有所变化,计算对应坐标)的映射patch,节省大量时间。
FRCNN(Fast RCNN,2015.4)
http://blog.csdn.net/shenxiaolu1984/article/details/51036677
http://blog.csdn.net/u010678153/article/details/46891655


最大改进在于将SVM分类器和区域修正的线性回归融入了神经网络,并共享特征。
Roi pooling layer
Roi pooling layer即single-level spp,仅取一个M×N的网格进行特征提取。作者实验发现使用多尺度的图像金字塔,性能有所提高,但不是很大,但速度要慢不少,因此只选了1层(预选区域投票的方法预选区域时已经将小目标选出来了,所有对浅层特征的需求相对较低,所以Fast RCNN把多尺度扔掉了;而SSD【单尺度多比例】和YOLOv2【聚类5个boxes】又把多层特征用上了,增强对小目标的检测)。
Multi-task loss
多任务损失:loss_cls分类损失(N类目标+1类背景)和loss_bbox回归损失(x,y方向缩放和偏移=4)。去掉svm分类,实验发现softmax性能较SVM略好。通过multi-task loss(两种损失求和)将区域修正的回归分类器放到了神经网络内部,作者实验发现,二者可共享卷积特征并相互促进。

其它改进细节
调优训练:min_batch(N=2张完整图像,选取R=128个候选框【IOU[0.5,1)为前景R中占比25%,[0.1,0.5)为背景,R中占比75%】)。另作者观点tuning-fine浅层没必要更新,可减少训练时间。
SVD:全连接层做SVD分解性能下降0.3%,可提速约30% 。
proposal:增加proposal个数对网络没有好处。
Faster RCNN(2015.6)
http://blog.csdn.net/shenxiaolu1984/article/details/51152614
http://blog.csdn.net/Seven_year_Promise/article/details/60954553
目的:a.将区域预选放到神经网络中,训练RPN(Region Proposal Network)网络;b.将RPN与识别修正神经网络相结合,且共用特征,将RPN放到Fast-RCNN中卷积层后面。总体来说就是用PRN网络代替Fast-RCNN中卷基层后输入的预选区域,有神经网络内部训练。

RPN
卷积得到Feature map(M×N),对每个特征点生成9个anchor(3种大小3种比例=9,此处anchor个数很多,先按规则选取【anchor样本选取规则:边界弃之,IOU(0.7,1)为前景,(0,0.3)为背景,[0.3,0.7]弃之】,再通过Non-Maximum Suppression减少后再分类回归,适用nms可能导致遮盖的同类物体无法被同时检出?),加一层conv+Relu,训练判断每个anchor是前景或背景的概率(二分类),以及anchor区域回归(x、y、w、h,4回归)。RPN是FCN全卷积网络。

anchor这个概念有很多限制,为什么是9个?大小和比例是否可以变更?
RPN和Fast-RCNN训练
轮流训练
a. 从W0开始,训练RPN。用RPN提取训练集上的候选区域
b. 从W0开始,用候选区域训练Fast RCNN,参数记为W1
c. 从W1开始,训练RPN…
具体操作时,仅执行两次迭代,并在训练时冻结部分层。
联合训练(公开代码用此方法训练,时间比上面减少20%-25%)

在backward计算梯度时,把提取的ROI区域当做固定值看待;在backward更新参数时,来自RPN和来自Fast RCNN的增量合并输入原始特征提取层。
四个损失函数
RPN Classification(anchor good|bad)
RPN regression(anchor → proposal)
Fast RCNN Classification(over classes)
Fast RCNN Classification(proposal → bbox)
Faster RCNN 中的RPN和fast RCNN网络特征共享,但仍然是两个网络。
YOLO(You Only Look Once,2015.6)
https://pjreddie.com/darknet/yolo/
https://www.cnblogs.com/fariver/p/7446921.html
http://blog.csdn.net/hrsstudy/article/details/70305791
https://zhuanlan.zhihu.com/p/24916786?refer=xiaoleimlnote
之前的方法(如RCNN,SPPNet,FastRCNN,FasterRCNN)都是先找到区域,再对区域内图像做识别。YOLO将物体检测作为一个回归问题处理,一个网络直接预测BBox坐标、是否包含物体和物体类别,检测速度很快,达到实时,但一代YOLO精度略低。


YOLO算法步骤:
将输入图像归一化到统一尺寸448 * 448;
GoogLeNet特征提取(1*1+3*3卷积替换Inception结构),网格预测 → BBox定位、物体识别;
NMS 过滤合并BBox。

网格预测
将图像分成S×S(7*7)个cell,每个cell负责检测中心落在该网格内的物体,且设定每个cell可预测B(2)个BBox。则YOLO网络负责a.预测S×S×2=98个BBox坐标(x,y,w,h)以及是否包含物体的概率 b.预测S×S=49个cell所属物体的概率,作者验证20个分类。则每个cell预测的数据维度=2×(4+1)+20 = 30,总回归数据维度=7×7×30。
每个bbox只负责一个object,一个cell生成两个bbox,这两个bbox是用来定位的,一个cell只表示一个object是指分类。不同bbox之间是会有交集的,作者认为相交部分的cell图像也只能属于一个分类(此处cell中可能是一个object将另一个遮挡,也可能是某一object占比大于另一个,就算各占一半也只表示一个object)。
为什么是7*7,因为最后特征尺寸就是7*7.

训练
特征提取网络改自GoogLeNet。
预训练分类:与RCNN系列一致,先在分类数据集上训练分类网络,便于后续应用网路卷积特征提取部分。预训练时输入为224*224,训练网络为前20层卷积+额外(average pooling layer+FC)。
训练检测:训练输入改为448*448(区域检测要求精度高...),修改模型=>GoogLeNet20层+4个卷积层+2FC(毕竟任务有所不同【分类->坐标回归+分类】,作者实验在预训练网络后加卷积层效果好,SSD对此处进行修改结合了不同分辨率的特征,增强了对小目标的检测能力),执行检测训练。
损失
损失函数的设计宗旨:让坐标(x,y,w,h),confidence,classification 这个三个方面达到很好的平衡。
在训练时我们希望每个object(ground true box)只有一个bbox专门负责(一个object 一个bbox)。具体做法是与ground true box(object)的IOU最大的bbox 负责该ground true box(object)的预测。这种做法称作bounding box predictor的specialization(专职化)。每个预测器会对特定(sizes,aspect ratio or classed of object)的ground true box预测的越来越好。
坐标,w,h为何开方?因为对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏相同的尺寸对IOU的影响更大。目的思路是对的,但方法有待改进。另由于对bbox坐标预测更为重视,其位置便宜影响后续loss,因此赋予坐标较高权重。
置信度,归一化,然而大部分BBox没有目标,可能导致loss不平衡,因此引入,取0.5。
分类,作者设计每个cell只能同种物体。若格子中包含物体,希望预测正确的类别的概率越接近于1越好,而错误类别的概率越接近于0越好,。
另注:loss只是在训练时使用,是可以直接打上标签的。
测试
每个bbox 分类概率P(bbox)包含每个cell置信度和bbox分类概率,如下式:

依次对每个bbox进行上述操作,得到7*7*2=98个预测概率及对应坐标信息,设定阈值过滤掉低分值的bbox,然后对不同类别的bbox分别进行NMS处理,即得到最终结果。
缺点
一个网格中只预测了两个框,对相互靠的很近的物体,检测效果不好;
受限于7×7的网格限制,小尺寸目标检测不好;
损失函数坐标损失有待改进;
CNN固定尺寸输入。
YOLO v2(2016.12)
http://blog.csdn.net/jesse_mx/article/details/53925356
https://zhuanlan.zhihu.com/p/25052190
基于YOLO在网络结构上的改进得到YOLOv2,改进如下:
分类预训练与检测尺寸一致,都用448*448;
为增强对小目标的识别能力,减少了池化层,使feature map尺寸变大,则网格分辨率由7×7提升到13×13(446/2^5=14取13,必须用奇数,保证有一个cell可以看到中心的目标,13×2^5=416 将检测输入分辨率改为416×416);增加特征级联操作,融合不同层的特征,提高网络对小目标检测效果。
加入BN,网络收敛更快;基础网络修改为darknet-19;修改为全卷积网络,可接收任意尺度输入,但在训练时每10轮(epochs)修改尺寸进行训练,最终特征图尺寸即为网格尺寸;
引入faster RCNN的anchors机制,将位置由全图回归转换为anchor位置修正(召回率上升,准确率有所下降,召回率增加可提高物体检出率,但太高计算成本太大,所以anchor个数选取很重要),每个cell设置anchor个数K(类似于YOLO中的B值)由2修改为5(作者针对voc和coco数据集离线聚类计算5最合适,且给出了每个anchor的值);且根据faster RCNN 的anchors 损失修改对应的损失函数。
与SSD比较,小物体检测不如SSD,YOLOv2优点在于速度快,检测精度和准确度接近与SSD。
YOLO9000(2016.12)
https://www.leiphone.com/news/201708/7pRPkwvzEG1jgimW.html
基于YOLO在训练方法上的改进得到YOLO9000:可实时检测9418种物体,可以预测没有labelled的目标检测数据 。改进如下:
基于WordNet建立WordTree(标签树)综合ImageNet和COCO数据集,实现目标分类与检测的联合训练,得到YOLO9000。每个内部节点是一个softmax,其概率为路径上条件概率乘积;wordtree路径都有class loss。

网络简化到24层,输出特征17×17;每个cell 3个anchors;则输出17×17×(3×(4+1+9418))。
注意:个人理解,YOLO中每个cell输出维度=2×5+20=30,,20表示每个cell的分类;而YOLOv2中每个cell输出维度 = 5*(5+20) = 125,20表示cell对应的bbox的分类。
SSD(Single Shot MultiBox Detector,2015.12)
http://blog.csdn.net/u010167269/article/details/52563573#reply
引用faster-RCNN 的anchor boxes思想(高召回率带来的高精度),用YOLO的cell网格减少bbox密集度&&单网络检测提高了速度,借鉴DeepLab中的空洞卷积增大感受野,提出multi-scale方法(不同分辨率的特征负责不同尺度的目标检测),优化了anchor boxes的多尺度方法,是anchor的选择更加合理,也改进了YOLO对小目标检测差的缺陷,设计出SSD,基础网络是VGG-16。
最浅层38*38,尺寸大,每个特征点(cell)用3个boxes,其它layers都用6个。共预测38*38*3+(19*19+10*10+5*5+3×3+1*1)×6=7038个box
主要介绍一下几个改进(数据增强,空洞卷积不写了)如下:
Multi-scale
YOLO只利用最后一层feature-map 7*7,SSD用了6层分别预测,最浅层尺寸大,用了3个default boxes,其它层均用6个boxes,共7038个bboxes(不同层特征的分辨率不一致,选择不同大小的default boxes预测不同大小的目标),对每层特征加一个卷积层分别预测各层特征位置和分类。
尺寸公式:S_min取0.2,S_max取0.95。
Label
如何根据GT boxes给default boxes标记?YOLOv2应该是取IOU最大的一个进行标记,SSD 将IOU大于阈值(0.5)的 default boxes都进行配对标记(一个GT box可能与多个default box配对)。
LOSS

c每类的置信度,l是predict box,g是gt box,x表示l和g是否匹配(匹配为1,不匹配为0).N是与GT box匹配个数,是softmax loss,位置损失,同fast-rcnn,权重a=1(与YOLO差别,YOLO只匹配一个,通过权重增加对位置预测的权重,而ssd多匹配同权重)。
Hard negative mining
无效boxes远大于有效boxes,导致难以收敛,选取无效boxes中confidence最高的,是正负box比例在1:3。
模型分析
数据增广、浅层特征对性能提升很大,增加default boxes效果更好,但达到一个个数后效果不是很明显,空洞卷积对检测效果有所提升,重要的是对速度提升很大。
RFCN(2016.5)
RFCN是基于faster-RCNN的一个改进。faster-RCNN用基础网络(ZFNet,ResNet)提取特征,roi pooling后分成两个网络,分别做目标定位和分类,后面用不同的全连接参数(参数多),且每个box单独跑网络(耗时),RFCN就是想解决这个问题,解决思路:改进roi pooling,把全连接(改为全卷积)操作全放在roi pooling前面共享,减少参数和计算量。


Roi pooling
http://blog.csdn.net/baidu_32173921/article/details/71741970

resnet101卷积得到feature maps(W×H×1024),后面接卷积层(C=类别 ,k=3),输出,即每个类9个位置的feature map(一个位置每个类一张feature map),表示每个点属于9个不同方位的概率。基于此特征进行Roi pooling,也是一个SPP结构,用一个3*3的网格池化ROI内的特征。最后softmax等到每类最终得分。
Roi pooling方法如下图:将ROI分成一个3*3的网格,每个格子分别对应到9张feature map中,取网格内的平均值,输出3*3*(C+1)。充分利用位置信息,挺好的想法,但感觉不太好训练回归。

loss与faster rcnn类似。
样本选取:对负样本loss排序,选取loss较小的,是正负样本更加平衡。
为什么要用3*3的位置?作者测试用1×1效果不好。不排除用别的,物体结构?4*4+3*3?
其它-NMS convnet
http://blog.csdn.net/elaine_bao/article/details/50458463
上述方法中都是选取目标box分类后,再用传统NMS合并,当同类目标靠的很近时,可能将目标合并(取决于score和IOU阈值),有人做过NMS 卷积网络,若把NMS也合并到Object Detection 的神经网络就好了,但还不成熟,据说该链接文章被拒,没看。。。


Object Detection和Semantic Segmentation在深度学习中方法上的区别:目标检测直接在缩小的feature-map上进行目标预测和分类,语义分割相对而言要求更加精确,将特征上采样到原尺寸后再进行point分类预测;由于目标大小不一,所以二者都会使用浅层特征提高对小目标的识别效果,目标检测不需要融合浅层和深层特征,预测完成后可用NMS合并,而语义分割结合浅层和深层特征后对每个点进行预测分类,再用CRF优化分类(感觉上最后这一部分二种方法是可以结合起来的)。
疑问??深层和浅层提取特征除分辨率、感受野上差距外的不同?是否特征类型相似??

你可能感兴趣的:(深度学习)