【目标检测】SSD:

 

slides 讲得是至关清楚了:php

http://www.cs.unc.edu/~wliu/papers/ssd_eccv2016_slide.pdfhtml

 

配合中文翻译来看:python

https://www.cnblogs.com/cx2016/p/11385009.htmlgit

 

default boxes 核心点讲解 及 .cpp 代码见:https://www.cnblogs.com/sddai/p/10206929.htmlgithub

 


 

 

小哥的后续论文:

web

PUBLICATIONS

 

Frustum PointNets for 3D Object Detection from RGB-D Data [arXiv] [code] [KITTI benchmark] 
Charles R. QiWei LiuChenxia WuHao Su and Leonidas J. Guibas 
CVPR 2018
DSSD : Deconvolutional Single Shot Detector [arXiv] [demo] 
Cheng-Yang Fu*Wei Liu*, Ananth Ranga, Ambrish Tyagi, and Alexander C. Berg 
arXiv preprint arXiv:1701.06659, *=Equal Contribution
Fast Single Shot Detection and Pose Estimation [pdf] [arXiv] 
Patrick Poirson, Phil Ammirato, Cheng-Yang FuWei LiuJana Kosecka, and Alexander C. Berg 
3DV 2016.
SSD: Single Shot MultiBox Detector [pdf] [arXiv] [code] [video] [slides (pdf)] [slides (keynote)] 
Wei LiuDragomir AnguelovDumitru ErhanChristian Szegedy
Scott ReedCheng-Yang Fu, and Alexander C. Berg 
ECCV 2016 Oral.

 

研究领域:算法

 

I did a great internship at Google Mountain View in 2014 summer. Our team GoogLeNet won the classification and detection challenge in ILSVRC2014. My research speciality is computer vision. The main focus of my current research include:markdown

  • Abrige the semantic gap of image understanding with deep neural networks
  • 用深度神经网络缩小图像理解的语义 gap 
  • Recognize and detect objects from large scale image and video dataset
  • 从大规模图像和视频数据集中识别和检测物体

 


 这篇把核心的contrib点讲清楚了网络

 

基于”Proposal + Classification”的Object Detection的方法,RCNN系列(R-CNN、SPPnet、Fast R-CNN以及Faster R-CNN)取得了很是好的效果,由于这一类方法先预先回归一次边框,而后再进行骨干网络训练,因此精度要高,这类方法被称为two stage的方法。但也正是因为此,这类方法在速度方面还有待改进。由此,YOLO[8]应运而生,YOLO系列只作了一次边框回归和打分,因此相比于RCNN系列被称为one stage的方法,这类方法的最大特色就是速度快。可是YOLO虽然能达到实时的效果,可是因为只作了一次边框回归并打分,这类方法致使了小目标训练很是不充分,对于小目标的检测效果很是的差。简而言之,YOLO系列对于目标的尺度比较敏感,并且对于尺度变化较大的物体泛化能力比较差。框架

针对YOLO和Faster R-CNN的各自不足与优点,WeiLiu等人提出了Single Shot MultiBox Detector,简称为SSD。SSD整个网络采起了one stage的思想,以此提升检测速度。而且网络中融入了Faster R-CNN中的anchors思想,而且作了特征分层提取并依次计算边框回归和分类操做,由此能够适应多种尺度目标的训练和检测任务。SSD的出现使得你们看到了实时高精度目标检测的可行性。

 

 

[目标检测]SSD:Single Shot MultiBox Detector

基于”Proposal + Classification”的Object Detection的方法,RCNN系列(R-CNN、SPPnet、Fast R-CNN以及Faster R-CNN)取得了很是好的效果,由于这一类方法先预先回归一次边框,而后再进行骨干网络训练,因此精度要高,这类方法被称为two stage的方法。但也正是因为此,这类方法在速度方面还有待改进。由此,YOLO[8]应运而生,YOLO系列只作了一次边框回归和打分,因此相比于RCNN系列被称为one stage的方法,这类方法的最大特色就是速度快。可是YOLO虽然能达到实时的效果,可是因为只作了一次边框回归并打分,这类方法致使了小目标训练很是不充分,对于小目标的检测效果很是的差。简而言之,YOLO系列对于目标的尺度比较敏感,并且对于尺度变化较大的物体泛化能力比较差

针对YOLO和Faster R-CNN的各自不足与优点,WeiLiu等人提出了Single Shot MultiBox Detector,简称为SSD。SSD整个网络采起了one stage的思想,以此提升检测速度。而且网络中融入了Faster R-CNN中的anchors思想,而且作了特征分层提取并依次计算边框回归和分类操做,由此能够适应多种尺度目标的训练和检测任务。SSD的出现使得你们看到了实时高精度目标检测的可行性。

1、网络结构

SSD网络主体设计的思想是特征分层提取,并依次进行边框回归和分类。由于不一样层次的特征图能表明不一样层次的语义信息,低层次的特征图能表明低层语义信息(含有更多的细节),能提升语义分割质量,适合小尺度目标的学习。高层次的特征图能表明高层语义信息,能光滑分割结果,适合对大尺度的目标进行深刻学习。因此做者提出的SSD的网络理论上能适合不一样尺度的目标检测。

因此SSD网络中分为了6个stage,每一个stage能学习到一个特征图,而后进行边框回归和分类。SSD网络以VGG16的前5层卷积网络做为第1个stage,而后将VGG16中的fc6和fc7两个全链接层转化为两个卷积层Conv6和Conv7做为网络的第二、第3个stage。接着在此基础上,SSD网络继续增长了Conv八、Conv九、Conv10和Conv11四层网络,用来提取更高层次的语义信息。以下图3.1所示就是SSD的网络结构。在每一个stage操做中,网络包含了多个卷积层操做,每一个卷积层操做基本上都是小卷积。

 

 

骨干网络:SSD前面的骨干网络选用的VGG16的基础网络结构,如上图所示,虚线框内的是VGG16的前5层网络。而后后面的Conv6和Conv7是将VGG16的后两层全链接层网络(fc6, fc7)转换而来。

另外:在此基础上,SSD网络继续增长了Conv8和Conv九、Conv10和Conv11四层网络。图中所示,立方体的长高表示特征图的大小,厚度表示是channel。

 

2、设计要点

1. Default Boxes生成

在目标检测网络设计中,Default Boxes生成都是重中之重,也许直接决定了网络能针对的任务以及检测的性能。在SSD中,做者充分的吸收了Faster R-CNN中的Anchors机制,在每一个Stage中根据Feature Map的大小,按照固定的Scale和Radio生成Default Boxes。这里为了方便阐述,选取了Conv9的Feature Map,输出大小为5x5。SSD网络中做者设置Conv9的每一个点默认生成6个box,以下图所示。所以在这一层上,共生成了5x5x6=150个boxes。

 

 

2. 特征向量生成

在每张特征图上获得许多Default Box后还须要生成相应的特征向量,用来进行边框回归和分类。对于边框回归,只须要4维向量便可,分别表明边框缩放尺度(坐标轴两个方向)和平移向量(坐标轴两个方向)。对于分类,SSD网络采起为每一个类别进行打分的策略,也就是说对于每一个Default Box,SSD网络会计算出相应的每一个类别的分数。假设数据集类别数为c,加上背景,那么总的类别数就是c+1类。SSD网络采用了c+1维向量来分别表明该Default Box对于每一个类别所获得的分数。这里,假设是VOC数据集,那么每一个Default Box将生成一个20 + 1 + 4 = 25维的特征向量。一样,以Conv9输出特征图5x5为例。

 

 

3. 新增卷积网络

SSD网络在VGG基础上新增长了几个卷积网络(如网络结构中所述)。SSD网络总共增长了Conv八、Conv九、Conv10和Conv11四个卷积网络层。新增的这些网络都是经过一些小的卷积核操做。引用论文所说,这些小的卷积核操做是SSD网络性能优秀的核心。下面本报告将简单的阐述一下做者对于卷积网络的简单配置。

卷积核配置

  • 假设Feature Map通道数为P,SSD网络中每一个Stage的卷积核大小统一为33P。其中padding和stride都为1。保证卷积后的Feature Map和卷积前是同样大小。

卷积滤波器

  • 每一个Feature Map上mxn个大小的特征点对应K个Default Boxes,假设类别数+背景=c,最终经过卷积滤波器获得c+4维特征向量。那么一个Feature Map上的每一个点就须要使用kx(c+4)个这样的滤波器。

4. 联合LOSS FUNCTION

 

 

3、训练策略

训练SSD和基于region proposal方法的最大区别就是:SSD须要精确的将ground truth映射到输出结果上。这样才能提升检测的准确率。文中主要采起了如下几个技巧来提升检测的准确度

  • 匹配策略
  • Default boxes生成器
  • Hard Negative Mining
  • Data Augmentation

1. 匹配策略

这里的匹配是指的ground truth和Default box的匹配。这里采起的方法与 Faster R-CNN中的方法相似。主要是分为两步:第一步是根据最大的overlap将ground truth和default box进行匹配(根据ground truth找到default box中IOU最大的做为正样本),第二步是将default boxes与overlap大于某个阈值(目标检测中一般选取0.5,Faster R-CNN中选取的是0.7)的ground truth进行匹配。

2. Default Boxes生成器

 

 

3. Hard Negative Mining

通过匹配策略会获得大量的负样本,只有少许的正样本。这样致使了正负样本不平衡,通过试验代表,正负样本的不均衡是致使检测正确率低下的一个重要缘由。因此在训练过程当中采用了Hard Negative Mining的策略,根据Confidence Loss对全部的box进行排序,使得正负样本的比例控制在1:3以内,通过做者实验,这样作能提升4%左右的准确度。

4. Data Augmentation

为了模型更加鲁棒,须要使用不一样尺度目标的输入,做者对数据进行了加强处理。

  • 使用整张图像做为输入
  • 使用IOU和目标物体为0.一、0.三、0.五、0.7和0.9的patch,这些patch在原图的大小的[0.1, 1]之间,相应的宽高比在[1/2, 2]之间。
  • 随机采起一个patch

 

4、实验结果

1. PASCAL VOC 2007

 

 

2. 模型分析

 

 

 

 

3. PASCAL VOC 2012

 

 

5、参考文献

[1]He K, Zhang X, Ren S, et al. Spatial pyramid pooling in deep convolutional networks for visual recognition[C]//European Conference on Computer Vision. Springer, Cham, 2014: 346-361.
[2]Redmon J, Divvala S, Girshick R, et al. You only look once: Unified, real-time object detection[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2016: 779-788.
[3] Liu W, Anguelov D, Erhan D, et al. Ssd: Single shot multibox detector[C]//European conference on computer vision. Springer, Cham, 2016: 21-37.
[4] https://zhuanlan.zhihu.com/p/24954433

[5] github源码地址

 


 

 

数据增广:

 

目标检测:SSD的数据加强算法

代码地址

https://github.com/weiliu89/caffe/tree/ssd

论文地址

https://arxiv.org/abs/1512.02325

数据加强:

图左是expand方法

SSD数据加强有两种新方法:(1)expand ,左图(2)batch_sampler,右图

expand_param {
      prob: 0.5 //expand发生的几率
      max_expand_ratio: 4 //expand的扩大倍数
    }
  • 1
  • 2
  • 3
  • 4

expand是指对图像进行缩小,图像的其他区域补0,下图是expand的方法。我的认为这样作的目的是在数据处理阶段增长多尺度的信息。大object经过expand方法的处理能够变成小尺度的物体训练。提升ssd对尺度的泛化性

这里写图片描述

annotated_data_param {//如下有7个batch_sampler
    batch_sampler {
      max_sample: 1
      max_trials: 1
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.1
      }
      max_sample: 1
      max_trials: 50
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.3
      }
      max_sample: 1
      max_trials: 50
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.5
      }
      max_sample: 1
      max_trials: 50
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.7
      }
      max_sample: 1
      max_trials: 50
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.9
      }
      max_sample: 1
      max_trials: 50
    }
    batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        max_jaccard_overlap: 1
      }
      max_sample: 1
      max_trials: 50
    }

batch_sampler是对图像选取一个知足限制条件的区域(注意这个区域是随机抓取的)。限制条件就是抓取的patch和GT(Ground Truth)的IOU的值。

步骤是:先在区间[min_scale,max_sacle]内随机生成一个值,这个值做为patch的高Height,而后在[min_aspect_ratio,max_aspect_ratio]范围内生成ratio,从而获得patch的Width。到此为止patch的宽和高随机获得,而后在图像中进行一次patch,要求知足与GT的最小IOU是0.9,也就是IOU>=0.9。若是随机patch知足这个条件,那么张图会被resize到300300(**在SSD300300中**)送进网络训练。以下图。

batch_sampler {
      sampler {
        min_scale: 0.3
        max_scale: 1
        min_aspect_ratio: 0.5
        max_aspect_ratio: 2
      }
      sample_constraint {
        min_jaccard_overlap: 0.9
      }
      max_sample: 1
      max_trials: 50
    }

这里写图片描述

SSD数据增广中的图像变换与裁剪

SSD在数据增广部分作了不少工做,处理方法集中在load_batch函数中,首先是对每一帧图像,即每一个datum作DistortImage处理,DistortImage包括亮度、饱和度,色调,颜色灰度扭曲等变换,再进行ExpandImage处理

 

>>>:如今的方法基本上就是靠大量训练数据(&negative sampling >>> 题外话:负采样效果好,有没有理论上的一些分析,好比稀疏、低维流形啥的),而后“分类” ;

而人类识别感受是提取到了这类物体的 backbone/sketch,后续再加上各类颜色上的交换等,是瓜熟蒂落的 —— 是否能搞一种 attention 机制;或者是 orthogonal 叠加的机制( 形状骨架 + 换肤主题,而后再叠加)

另外总以为 2-D 目标检测是伪命题——可否将calibration、透视变换、parts 组合成 object ... 这些结构性的机制引入进来?

 

seems like a fertile field

可能标注数据集也须要修正; 

 

数据曾广方法

在DistortImage函数中,首先用OpenCV的 cv_img = DecodeDatumToCVMat(datum, param_.force_color())函数将图像从Datum数据中解码出来,数据的变形是针对图片来作的,在ApplyDistort(const cv::Mat& in_img, const DistortionParameter& param)函数中,输入一个Mat格式的图片,输出一个通过DistortionParameter参数所变换后的图像,其中包括随机亮度失真变换,随机对比度失真变换,作随机饱和度失真变换,随机色调失真变换和随机图像通道变换,这里是一种排列组合的方法,变换的顺序不一样,获得的图片结果也不一样,根据随机数是否大于0.5来肯定对比度和色调失真变换的顺序。代码以下:

返回变换后的图片,再将其编码成Datum的格式,编码函数EncodeCVMatToDatum(const cv::Mat& cv_img, const string& encoding, Datum* datum),其中用到了一个opencv图像编码的接口cv::imencode("."+encoding, cv_img, buf);再把数据写入datum中。代码以下:

接着是ExpandImage(distort_datum, expand_datum)的操做,这个操做是按照百分之五十的几率发生的。ExpandImage能够理解为裁剪操做,在SSD中做者也提到裁剪至关与zoom in放大效果,可使网络对尺度更加不敏感,所以能够识别小的物体。经过将原图缩小放到一个画布上再去裁剪达到缩小的效果。在原文中的Fig.6提到了在数据加强以后SSD网络确实对小物体识别能力有很大提高。裁剪后的图像至少一个 groundtruth box 的中心(centroid) 位于该图像块中.这样就能够避免不包含明显的前景目标的图像块不用于网络训练(只有包含明显的前景目标的图像块采用于网络训练.)同时,保证只有部分前景目标可见的图片用于网络训练.例如,下面图像中,Groundtruth box 表示为红色,裁剪的图像块表示为绿色. 因为是随机裁剪(几率百分之五十),所以有些图像是包含扩展的画布,有些则不包含.

按百分之五十随机选择是否增长画布

在代码中实现ExpandImage的方法是,先按(1:max_expand_ratio)随机产生一个比例系数expand_ratio,创造一个expand_ratio*原图大小的0填充图,再按照代码里的方式肯定一个顶点,用于将原图粘贴到所创造的“画布”中,而且肯定好须要这张图须要裁剪的区域expand_bbox(这个区域我不太懂),而后用平均值进行画布填充,获得一张较大的图,用于后期的裁剪,这样作的缘由,上文提到了(参考别人说的)

接着就是把填充的图片编码成expand_datum,而后进入TransformAnnotation函数,在上面的ExpandImage中,不存在任何对原数据中的AnnotationGroup的处理,即这里所生成的expand_datum仅仅是图片的裁剪的datum格式,expand_datum中的Annotation并无作任何赋值或者更新,这一部分工做在TransformAnnotation函数中进行,主要是将原图的AnnotationGroup中的NormalizedBBox,经过映射变换后,复制到expand_datum的annotation中,注意这里所取的原图NormalizedBBox有条件,得知足这个框的中心点在裁剪图之中,其余在裁剪框以外的NormalizedBBox就直接舍弃。代码以下:

 这里就解读到ExpandImage函数,下一篇将解读Samples这块儿的操做。

 


 

 

SSD(Single Shot MultiBox Detector)笔记

为何要学习SSD,是由于SSD和YOLO同样,都是one-stage的经典构架,咱们必须对其理解很是深入才能触类旁通设计出更加优秀的框架。SSD这个目标检测网络全称为Single Shot MultiBox Detector,重点在MultBox上,这个思想很好地利用了多尺度的优点,全面提高了检测精度,以后的YOLOv2就借鉴了SSD这方面的思路才慢慢发展起来。

《SSD(Single Shot MultiBox Detector)笔记》

前言

本文用于记录学习SSD目标检测的过程,而且总结一些精华知识点。

为何要学习SSD,是由于SSD和YOLO同样,都是one-stage的经典构架,咱们必须对其理解很是深入才能触类旁通设计出更加优秀的框架。SSD这个目标检测网络全称为Single Shot MultiBox Detector,重点在MultBox上,这个思想很好地利用了多尺度的优点,全面提高了检测精度,以后的YOLOv2就借鉴了SSD这方面的思路才慢慢发展起来。

强烈建议阅读官方的论文去好好理解一下SSD的原理以及设计思路。这里也提供了相关的pdf:http://www.cs.unc.edu/~wliu/papers/ssd_eccv2016_slide.pdf

固然也有不少好的博客对其进行了介绍,在本文的最下方会有相关连接。本篇文章主要为本身的笔记,其中加了一些本身的思考。

网络构架

SSD的原始网络构架建议仍是以论文为准,毕竟平时咱们接触到的都是各类魔改版(也就是所谓的换了backbone,例如最多见的SSD-mobilenetv2),虽然与原版大同小异,不过对于理解来讲,会增大咱们理解的难度,所以,彻底有必要看一遍原始的论文描述。

SSD在论文中是采起的VGG网络做为主干结构,可是去除了VGG中的最后几层(也就是咱们常常说的分类层),随后添加了一些新的内容(在原文中叫作auxiliary structure),这些层分别是:

  • 额外的特征提取层(Extra Feature Layers),做用就是和本来backbone的层相结合共同提取出不一样尺寸的特征信息,至关于增强了以前的backbone,使其网络更深,提取能力更增强大。
  • 分类层(classification headers),对以前网络中的不一样位置网络层输出的特征层(不一样尺度),进行卷积得出每一个特征图中每一个坐标对应的分类信息(每一个坐标对应着许多default boxes)。
  • 坐标位置回归层(regression hearders),结构与分类层相仿,只是输出的通道略有不一样,经过对不一样尺度的特征图进行卷积,输出的是每一个特征图中每一个坐标对应的default boxes的偏移坐标(文章中称为shape offset)。

TIM截图20190502103338

整体来讲,SSD网络结构其实有四部分组成,backbone部分、额外添加的特征提取层、分类层以及坐标位置回归层。注意当初这篇SSD是出于Yolo一代以后二代以前,Yolo二代三代中不一样尺度的特征图思想是有借鉴于SSD的。

用于检测的多尺度特征图

多尺度特征图具体表示就是SSD在整个网络的不一样位置,取出相应的特征层进行预测,每一个特征层由于尺度不同能够检测的视野以及目标物体的大小也不一样。每一个特征图能够预测出分类信息和位置信息,以下图中能够看到整个网络使用从前到后使用了6个不一样的特征图,从38x38x5121x1x256一共六个不一样尺度的特征图。

也就是使用低层feature map检测小目标,使用高层feature map检测大目标,是SSD的突出贡献。

20170611145131140

那么default box是如何产生?

default box

论文中的原话是这样的:

We associate a set of default bounding boxes with each feature map cell, for multiple feature maps at the top of the network. The default boxes tile the feature map in a convolutional manner, so that the position of each box relative to its corresponding cell is fixed. At each feature map cell, we predict the offsets relative to the default box shapes in the cell, as well as the per-class scores that indicate the presence of a class instance in each of those boxes.

就是对于上述每个不一样尺度的特征图(38x3八、19x1九、10x十、5x五、3x三、1x1),每个特征图中的坐标中(cell)产生多个default box。对于每一个default box,SSD预测出与真实标定框的偏移(offsets,一共是4个数值,表明位置信息)以及对应于每一个类的几率confidence(c1,c2,...,cpc1,c2,...,cp)。若是一共有c类,每个坐标产生k个box,那么咱们在进行训练的时候,每一个cell就会产生(c+4)k个数据,若是特征图大小为mxn,那么总共就是(c+4)kmn,例如3x3的特征图,mxn就是3x3。

注意下,上述的那个offset不只是相对于default box,换个角度来讲,也是相对于真实标定框的偏移,通俗了说就是default box加上offsets就是真实标定框的位置。这个offsets是咱们在训练学习过程当中能够计算出来用于损失函数来进行优化的。

在实际预测中,咱们要预测出每一个default box的category以及对应的offset。

TIM截图20190429161151

这部分我看到更好的介绍,因此这里不进行赘述,能够直接看这里:解读SSD中的Default box(Prior Box)

训练过程

不光要从论文中理解一个网络的细节部分,还须要详细了解一下训练的具体过程:

由于咱们要在特征图上生成default box,那么在训练阶段咱们就须要将GT(Ground Truth)与default box相对应才能进行训练,怎么个对应法,SSD中使用了一个IOU阈值来控制实际参与计算的default box的数量,这一步骤发生在数据准备中:

TIM截图20190506164015

首先要保证每一个GT与和它度量距离最近的(就是iou最大)default box对应,这个很重要,能够保证咱们训练的正确性。另外,由于咱们有不少狠多的default box,因此不仅是iou最大的default box要保留,iou知足必定阈值大小的也要保留下来。

也就是说,训练的过程当中就是要判断哪一个default boxes和具体每一张图中的真实标定框对应,但实际中咱们在每一个特征图的每一个cell中已经产生了不少default boxes,SSD是将全部和真实标定框的IOU(也就是jaccard overlap)大于必定阈值(论文中设定为0.5)的default boxes都保留下来,而不是只保留那个最大IOU值的default box(为何要这么作,原论文中说这样有利于神经网络的学习,也就是学习难度会下降一些)。

这样咱们就在以前生成的default boxes中,精挑细选出用于训练的default boxes(为了方便,实际训练中default boxes的数量是不变的,只不过咱们直接将那些iou低于必定阈值的default boxes的label直接置为0也就是背景)。

损失函数

损失函数也是很简单,一共有俩,分别是位置损失以及分类损失:

L(x,c,l,g)=1N(Lconf(x,c)+αLloc(x,l,g))L(x,c,l,g)=N1(Lconf(x,c)+αLloc(x,l,g))

其中NN为matched default boxes的数量,这个NN就是训练过程一开始中精挑细选出来的default boxes。当NN为0的时候,此时整体的损失值也为0。而αα是经过交叉验证最终获得的权重系数,论文中的值为1。

位置损失

其中xijp={1,0}xijp={1,0}表示当前defalut box是否与真实的标定框匹配(第ii个defalut box与第jj个真实的标定框,其中类别是pp),通过前面的match步骤后,有∑ixijpixijp大于等于1。

Lloc(x,l,g)=∑i∈P os m∈{cx,cy,w,h}N∑(cx,cy,w,h}xijksmooth⁡L1(lim−g^jm)Lloc(x,l,g)=iP os m{cx,cy,w,h}N(cx,cy,w,h}xijksmoothL1(limg^jm)

注意,上式中的g^jmg^jm是进行变化后的GroundTruth,变化过程与default box有关,也就是咱们训练过程当中使用的GroundTruth值是首先经过default box作转换,转化后的值,分别为g^jcx,g^jcy,g^jw,g^jhg^jcx,g^jcy,g^jw,g^jh,这四个值,分别是真实的标定框对应default box的中心坐标x,yx,y以及宽度ww和高度hh的偏移量。

也就是下面四个转换关系,稍微花一点心思就能够看明白,在训练的时候实际带入损失函数的就是下面这四个转化后的值:

g^jcx=(gjcx−dicx)/diwg^jcy=(gjcy−dicy)/dihg^jcx=(gjcxdicx)/diwg^jcy=(gjcydicy)/dih

g^jw=log⁡(gjwdiw)g^jh=log⁡(gjhdih)g^jw=log(diwgjw)g^jh=log(dihgjh)

同理,既然咱们在训练过程当中学习到的是default box -> GroundTruth Box的偏移量,那么咱们在推测的时候天然也要有一个相反的公式给计算回来,将上面的四个公式反转一下便可。

分类损失

分类损失使用交叉熵损失,

Lconf(x,c)=−∑i∈PosNxijplog⁡(c^ip)−∑i∈Neglog⁡(c^i0) where c^ip=exp⁡(cip)∑pexp⁡(cip)Lconf(x,c)=iPosNxijplog(c^ip)iNeglog(c^i0) where c^ip=pexp(cip)exp(cip)

须要注意一点就是xijpxijp表明此时的预测box是否与真实标定框匹配,匹配则为1,也就是说分类损失前半部分只考虑与label匹配的,也就是positive boxes。然后半部分c^i0c^i0则表示背景分类的损失,即negative boxes的损失,想要让c^i0c^i0越大(背景正确被分为背景),就必须让后半部分的损失越小。

Hard negative mining

这个过程发生在实际训练过程当中,由于图像中预测出来的box有不少,并且大部分时negative boxes,因此这里将消除大部分的negative boxes从而使positive与negative的比例达到1:3。首先对以前通过match步骤,精挑细选以后的default boxes计数。这些default boxes算是positive default boxes,算出此时positive的数量,而后乘以3则是negative boxes的数量。

那么如何去挑选合适数量的negative boxes?SSD中的挑选规则是:挑选loss最大的boxes,也就是最难学的boxes,根据预测出来的confidence来判断(这段部分的实现可能与论文中会有所不一样),那么什么算最难学的,由于咱们首先已经根据label(这个label是以前matching过程后的label,label得数量与整张特征图中的boxes数量相同,只不过其中的label已经根据matching步骤进行了调整)获得了positive boxes,这些positive boxes与实际目标都知足必定的条件,并且其中很大几率都有物体。那么最难学的boxes该如何挑选呢?

咱们在其他的boxes中,由于其他的这些boxes已经不可能包含目标(由于有目标的在matching中都已经被挑选了,这些是剩下的),因此这些boxes的label理应被预测为background也就是背景,因此这些boxes关于背景的损失值应该是比较小的,也就是模型较为正确预测了背景。那么咱们要选最难识别的boxes,也就是最难识别为背景的boxes,这些叫作negative boxes,首先咱们将其他的这些boxes关于背景的loss排序,而后选取前面必定数量(与positive boxes的比值是3:1)的boxes做为negative boxes便可。

这段描述可能有些抽象,配上代码可能更好看一些:

def hard_negative_mining(loss, labels, neg_pos_ratio): """ It used to suppress the presence of a large number of negative prediction. It works on image level not batch level. For any example/image, it keeps all the positive predictions and cut the number of negative predictions to make sure the ratio between the negative examples and positive examples is no more the given ratio for an image. Args: loss (N, num_priors): the loss for each example. labels (N, num_priors): the labels. neg_pos_ratio: the ratio between the negative examples and positive examples. """ pos_mask = labels > 0 num_pos = pos_mask.long().sum(dim=1, keepdim=True) num_neg = num_pos * neg_pos_ratio loss[pos_mask] = -math.inf # put all positive loss to -max _, indexes = loss.sort(dim=1, descending=True) # sort loss in reverse order (bigger loss ahead) _, orders = indexes.sort(dim=1) neg_mask = orders < num_neg return pos_mask | neg_mask 

图像加强

SSD中已经采起了一些比较好的图像加强方法来提高SSD检测不一样大小不一样形状的物体,那就是randomly sample,也就是随机在图像片进行crop,提早设定一些比例,而后根据这个比例来对图像进行crop,可是有一点须要注意那就是这个randomly sample中须要考虑到IOU,也就是咱们crop出来的图像必须和原始图像中的GT box知足必定的IOU关系,另外crop出来的图像也必须知足必定的比例。

经过randomly sample后的图像其中一定包含原始的GT boxes(不必定全包含),并且crop后的boxes也是正确的。

这部分提及来比较抽象,能够看看这篇文章,我本身懒得进行演示了:

学习率设置

  • 官方:优化器使用SGD,初始的学习率为0.001momentum0.9weight-decay0.0005batch-size32
  • 我我的和官方使用的优化器相同,只不过在学习率上经过multi-step的方式(具体能够看Pytorch相关实现部分),在80和150个epoch阶段将学习率衰减至以前的1/10。一共训练300个epoch。

训练部分的系数设置仅供参考,不一样数据的训练系数略有不一样。

预训练权重

我的使用mobilenetv2-SSD的构架对本身的数据进行了训练,在全部超参数和训练系数不变的状况下,若是采用预训练好的mobilenetv2的权重(在ImageNet上),那么训练速度和最终的训练精度都会高出一截(相同epoch下),因此采用预训练好的权重信息很重要。

总结

SSD是一个优雅的目标检测结构,到如今依然为比较流行的目标检测框架之一,值得咱们学习,可是SSD对小目标的检测效果有点差,召回率不是很高,这与SSD的特征图以及semantic语义信息有关,另外SSD中也提到了一些对于提高mAP的缘由,其中很大部分是由于图像加强部分,以前提到的random patch能够变相地理解为对图像进行"zoom in"或者"zoom out",也就是方法或者缩小,这样加强了网络监测大目标和小目标的能力(但监测小目标的能力仍是稍微差一点)。

对于SSD的更多讨论,我这里也收集了一些其余优秀的文章,这里就不赘述了:

参考连接

https://arleyzhang.github.io/articles/786f1ca3/
https://www.cnblogs.com/sddai/p/10206929.html

相关文章
相关标签/搜索