代码来源:https://github.com/amdegroot/ssd.pytorch

SSD简介:

ssd有ssd300和ssd512,一般我们都是用ssd300,意思是输入SSD网络的图片的尺寸是300x300的。

(一)SSD的网络结构:

SSD的网络结构绝不是简单的VGG16网络,如下图:

图1

它是由VGG16的网络改造而成的,具体步骤如下:

1.先把传统的VGG16网络去掉卷积层之后的池化层和全连接层,再加入2个卷积层:(使得得到的特征图是1024通道的)

图二

2.再在网络的最后加上额外的卷积层(extra_layers):

传统的VGG网络卷积后的特征图的通道数最大是512。而加上extra_layers后,就使得经过VGG卷积层后的特征图的通道数能达到1024。

那具体extra_layers加了哪些卷积层呢?如下图共加了额外的8个卷积层:

这样做的原因:

正常的VGG16 输入300x300的图片,最终输出的是512x19x19的特征图。而修改过的VGG16则可以输出1024x19x19的特征图。加上extra_layers之后,则最后输出256x1x1的特征图。图二的结构详细分解如下:

图三

3.回归框的卷积层和预测类别的卷积层。

上图三可以看出,特征图有6条横着的线

由SSD的网络结构可以看出,SSD使用6个不同特征图检测不同尺度的目标。低层预测小目标,高层预测大目标。如下图:

每条线都各自代表着2个卷积层,一个用来预测框的位置(中心坐标+长宽),另一个用来预测框的分类。

而每个特征图预测多少个框呢?首先要说明的 一点是,特征图的每个像素都要画k个框,至于k是多少,不同框的k值是不同的,当然这是人为设置的超参数,但是在ssd300里,是已经固定了的,六个特征图分别对应的k值是[4,6,6,6,4,4]。

可能有人要问了,为什么是用6个特征图来回归,分类呢?为什么不是3个4个?

作者在论文中通过实验验证了,采用多个特征图做检测能够大大提高检测精度,从上面的表格可以看出,采用6个特征图检测的时候,mAP为74.3%,如果只采用conv7做检测,mAP只有62.4%。

好了,那么一共预测多少个框呢?

从图一可以看出,六个特征图的大小分别是:38x38,19x19,10x10,5x5,3x3,1x1。每个特征图的k值是[4,6,6,6,4,4]。所以一共预测的框的数目是:

(38*38*4 + 19*19*6 +10*10*6+5*5*6 +3*3*4 + 1*1*4)= 8732。

之前说了,每条横线其实是对应着2个卷积层,一个是用来回归的(暂且叫他回归卷积层),一个是用来分类的(暂且叫分类卷积层)

我们看看这两个卷积层出来的特征图是什么样子的,以第一个特征图(尺寸为38x38)的为例:

回归卷积:

显而易见,38x38是特征图尺寸。而4x4是什么意思呢,第一个4是第一个特征图的K值,代表这个特征图每个像素要画4个框,第二个4是表示框的中心点坐标(x,y)和长宽(h,w)。因此没个像素对应16个值。

分类卷积:

(num_class是一个数据集的类别个数)

综上所言:SSD网络通过6个特征图各自进行回归卷积和分类卷积得到:

最后一步,就是各自把回归卷积图和分类卷积图都整个起来。但是问题来了,我们可以看到,由于他们的尺寸不一样(有的38x38,有的19x19)所以不能直接叠在一起,必须要做个处理。我们看到每个回归/分类出来的特征图是3维的(eg:38x38x16),有深度学习经验的朋友都知道,我们实际上送入网络训练的数据是四维的,因为还有一维是表示batchsize的,以第一个回归卷积 图为例,它维度应该是[1,16,38,38],我们把它转成[1,-1](-1其实16x38x38的值),那么四维的数据就变成两维的了,由于batchsize的位置都是1,是相同的,所以6个回归/分类卷积图可以直接叠加,把6个整合成一个。最后的回归卷积维度是[1,34928],最后的分类卷积维度是[1,num_class*8732]。有人可能问了,为什么回归卷积维度是[1,34928]呢,因为ssd一共会生成8732个框嘛,对于回归卷积,每个框有4个参数,用来确定框的位置,所以是8732x4 = 34928。

最后SSD在输出两个卷积特征时,再做了一次维度转换,例如[1,34928]的回归卷积转换成[1,8732,4]。这样就更直观了,8732表示框的总个数,4则是框的为位置信息个数。而分类卷积则是[1,8732,num_class]。综上所述SSD300网络输出的是维度为[1,8732,4]和[1,8732,num_class]的特征图。

(二)训练过程

我们知道SSD网络输出什么之后,有没有疑问,那这个输出是跟什么label一起送到损失函数里的呢?

我们看一张图:

这是一张训练数据的Ground True,里面有两个框,每个框有4个位置信息,那么这张图片的维度可以写成[1,2,4],咦,天啊~你ssd输出的边框回归信息维度已经是[1,8732,4]了,你边框个数对不上啊,你怎么进行训练啊。。。

所以,我们得出一个结论:label的Ground True并非真正输入损失函数的label。

那真正与ssd的输出一起输入损失函数的label是什么呢?我们一步步来看。。。

1. default box(也叫先验框priors)

default box就是所谓在特征图上画的框,在六个特征图上画框,一共画8732个框。特征图的每个像素画4或6个框(取决于是哪个特征图):

画框是在六个特征图框上画的,但是我们画的框最终目的是要和数据集Ground True中的框作匹配的,那在六个特征图上的画是怎么映射到原图大小的Ground True上呢?

在各个特征图上画的框,一定会做一个归一化,即长宽除以当前特征图的长宽,框的中心点也会除特征图的边长。到时候归一化后的框大小 只要乘原图的长宽,就得到该特征图上的框在原图上的映射。因此~在越大的特征图上画的框映射在原图上就越小,在越小的特征图上画的框映射在原图上就越大。这样做的好处是比较大的特征图来用来检测相对较小的目标,而小的特征图负责检测大目标。

六个特征图,各个特征图的每个像素点画的框数是[4,6,6,6,4,4],即第一个特征图每个像素画4个框,第二个特征图每个像素画6个框,如此类推。

那default box的大小尺度怎么确定呢?这里论文里有公式说明计算方式,但是代码里就直接以参数的形式写出来。这里就讲讲论文里是怎么推default box的大小尺度吧。

=====选看,因为代码中并没有计算过程,是直接使用结果作为参数============================================

要确定框的大小尺寸,首先要确定两个参数,一个是min_size,一个是max_size,框的长宽都由这两个参数组成。

min_size = 300 * Sk (300是图片输入的尺寸)

在论文中,计算Sk的公式如下:

S_min = 0.2,S_max = 0.88m=5(因为有6个特征图,而第一个特征图的min_size作者指定为30),就可以算出[60, 111, 162, 213, 264],至于30和315应该是作者自己设置的。

所以,可以得到,六个特征图的min_size 和 max_size如下:

可以看到 max_size就是min_size下一个元素,所以只要计算出min_size,max_size也出来了。max_size的最后一个值是315,是额外加上去的。

==================================================================

有了min_size 和 max_size,我们还需要长宽比,一般选取长宽比为:

宽:

高:

在这种情况下,特征图每个像素理论上来说都会有5个框(因为a_r有5个元素),每个特征图会有一个a_r = 1且尺度为s_k的先验框,除此之外,还会额外设置一个尺度为:

且 a_r=1的先验框。这样每个特征图都设置了两个长宽比为1但大小不同的正方形先验框。所以理论上特征图每个像素理论上来说都会有6个框。但在实现时,SSD的Conv4_3,Conv10_2和Conv11_2层仅使用4个先验框,它们不使用长宽比为3,1/3 的先验框。由于每个框会有中心坐标(2个值)和长宽(2个值)所以,SSD300一共要画

个边界框,那既然画出的框的值共是8732个,自然网络预测时,也要预测8732个值。

2.为什么要画框?(即为什么要有default box)

首先要明白一个叫感受野的概念:

影响某个神经元输出的输入区域就是理论感受野,也就是我们平时说的感受野,但该输入区域的每个像素点对输出的重要性不同,越靠近中心的像素点影响越大,呈高斯分布,也就是说只有中间的一小部分区域对最后的输出有重要的影响,这个中间的一小部分区域就是有效感受野

下图中:

左边黑色的区域就是理论感受野,中间呈高斯分布的白色点云区域就是有效感受野。

右边内红色圈部分对应着有效感受野,我们的default box最好能匹配到有效感受野。

SSD在6个特征图上使用2组3x3的卷积核分别做分类和boundingbox回归。我们知道每个特征图上每个像素点对应一个理论感受野,所以SSD相当于对原图中所有的理论感受野作分类和回归,由于有效感受野在理论感受野中有重要的影响,其他区域的影响可以忽略,所以这里我们认为SSD是对有效感受野作分类和回归,那么问题来了,既然是对所有的有效感受野做分类和回归,那每个有效感受野的分类的label和回归的label是如何确定的呢?default box就是用来干这个的。
简单来说就是:

K层的特征图的上的一个像素,对应着其前一层的特征图的多个像素,这就是感受野:

(红色框为Ground True框)

按照SSD的做法,画出来的8732个框,全部都要有对应的一个GroundTrue框。

(1).这个过程叫 match

把8732个框都要对应一个GroundTrue框

(2).encode:

接着就到encode过程,作用:

(对回归值的处理):

是算出default box 和这个default box对应的GroundTrue框的偏置值(offset)。偏置值包括default box的中心坐标和GroundTrue框的中心坐标的偏置值,和default box边长和GroundTrue框的边长的偏置值。得到的偏置值再与网络的输出(预测回归值)送入smooth_L1_loss函数,得到回归损失值loss_l。所以 SSD网络输出的回归值是偏置值(SSD网络 一共输出5个值,4个是回归值,一个是类别值),真正检测时,SSD的输出需要通过decode生成归一化的边框值,再乘图片的长和宽,才会形成图片的边框值。

(对分类置信度的处理):

把与GroundTrue框的IOU阈值少于0.5的default box的label设置成背景类(即0)。用conf_t来记录8732个框的类别。

(3)硬负挖掘法Hard Negative Mining(用来定义正样本和负样本的 一种方法):

详细看这里

把与GroundTrue框的IOU大于阈值(0.5)的default box作为正样本,把少于阈值的作为负样本。由于正样本与负样本比,正样本太少了(因为大部分default box都碰不到GroundTrue框的),会造成数据的不平衡,进而影响检测的精度。所以Hard Negative Mining规定正样本:负样本=1:3。(设正样本数为n)。所以在负样本中,挑选(对背景)损失大的3n个负样本作为真正的负样本。

得到正样本和负样本后,以序号为框的标识,再conf_t中抽出这些样本对应的类别作为 分类损失函数cross_entropy的label。再从SSD网络出来的类别值中,找出对应框序号的类别值,作为分类损失函数cross_entropy的预测输入,最后就可以得到分类损失值loss_c。两个损失值相加,就得到这次训练的损失值loss = loss_l + loss_c。

总结 一下:

1.SSD网络不是直接输出预测框的准确值,而是输出一个相对于default box的偏置值(也可以叫变化值),用default box结合这个偏置值才是最终预测框的值,当然最后要乘上输入图片的边长,才能把这个框映射到输入图片上去。

2.其实SSD主干网络并不复杂,复杂的是他的损失函数Multibox_loss的设计。

3.SSD的一个缺点就是 default的画法,例如default box 的长宽比不能通过学习所得,要按照不同数据集的特性人工设定不同的长宽比。

4.SSD虽然是用了多尺度的方法,但是对小物体的检测效果依旧不好。

5.可能有人问,为什么要画default box框,为什么不同直接输入 Ground True上的框作为label来训练预测框的时?因为这样做的话,训练数据量不够。SSD不仅要输出边框的回归值,还要输出边框的类别值,不仅输出数据多,而且还是多分类问题,但靠一张图的几个Ground True边框是很难的。

ssd(Single Shot MultiBox Detector)解读之(一)原理解析相关推荐

  1. SSD:Single Shot MultiBox Detector解读

    注:md文件,Typora书写,md兼容程度github=CSDN>知乎,若有不兼容处麻烦移步其他平台,github文档供下载. 发表在CSDN:https://blog.csdn.net/ha ...

  2. ssd网络结构_封藏的SSD(Single Shot MultiBox Detector)笔记

    关注oldpan博客,侃侃而谈人工智能深度酝酿优质原创文! 阅读本文需要xx分钟 ? 前言 本文用于记录学习SSD目标检测的过程,并且总结一些精华知识点. 为什么要学习SSD,是因为SSD和YOLO一 ...

  3. SSD(Single shot multibox detector)目标检测模型架构和设计细节分析

    先给出论文链接:SSD: Single Shot MultiBox Detector 本文将对SSD中一些难以理解的细节做仔细分析,包括了default box和ground truth的结合,def ...

  4. 目标检测--SSD: Single Shot MultiBox Detector

    SSD: Single Shot MultiBox Detector ECCV2016 https://github.com/weiliu89/caffe/tree/ssd 针对目标检测问题,本文取消 ...

  5. 目标检测方法简介:RPN(Region Proposal Network) and SSD(Single Shot MultiBox Detector)

    原文引用:http://lufo.me/2016/10/detection/ 最近几年深度学习在计算机视觉领域取得了巨大的成功,而在目标检测这一计算机视觉的经典问题上直到去年(2015)才有了完全使用 ...

  6. SSD论文阅读(Wei Liu——【ECCV2016】SSD Single Shot MultiBox Detector)

    本文转载自: http://www.cnblogs.com/lillylin/p/6207292.html SSD论文阅读(Wei Liu--[ECCV2016]SSD Single Shot Mul ...

  7. 深度学习之 SSD(Single Shot MultiBox Detector)

    目标检测近年来已经取得了很重要的进展,主流的算法主要分为两个类型: (1)two-stage方法,如R-CNN系算法,其主要思路是先通过启发式方法(selective search)或者CNN网络(R ...

  8. SSD( Single Shot MultiBox Detector)关键源码解析

    SSD(SSD: Single Shot MultiBox Detector)是采用单个深度神经网络模型实现目标检测和识别的方法.如图0-1所示,该方法是综合了Faster R-CNN的anchor ...

  9. SSD: Single Shot MultiBox Detector 之再阅读

    SSD: Single Shot MultiBox Detector SSD 一句话就是速度快,效果好! 第一版 8 Dec 2015,第二版是30 Mar 2016 主要改进是内容更加详实,实验更加 ...

最新文章

  1. 重磅 | 阿里开源首个 Serverless 开发者平台 Serverless Devs
  2. sqlserver 实现伪序列
  3. Linux使用lvresize扩展或缩减LV逻辑卷大小
  4. LINUX脚本报错捕捉,Linux01-BASH脚本编程之信号捕捉及任务计划53
  5. wince版本ffmpeg的编译 第四篇
  6. +++程序员高手修炼之路
  7. sqlserver有外键无法创建触发器_数据库不使用外键的 9 个理由
  8. 行高引起的行内块级元素间距
  9. 机器博弈 (四)博弈规则的设计
  10. Ubuntu 分卷压缩和解压
  11. 芯片数据分析笔记【03】 | GEO数据库使用教程及在线数据分析工具
  12. html全局背景代码,html背景代码
  13. Ubuntu18.04 MOOS-ivp 编译运行
  14. OBCA认证知识点-part3
  15. Found my pics from 2007
  16. js 混合排序(同时存在数字、字母、汉字等)
  17. 免费OCR图片文字识别小工具,一键提取图片中文字,支持多语言翻译和发票识别
  18. repost 懊悔自己没能在本科和研究生期间邂逅ACM
  19. ArcMap投影后的数据添加经纬网
  20. R语言 主成分分析 代码

热门文章

  1. 网页设计各种颜色搭配 并且哪几种颜色可以做成哪种风格
  2. 网易、百度等公司面试题整理
  3. 高通AR 的cloud研究
  4. 电脑端,PC端,微信小程序打不开,加载空白,或者提示加载失败
  5. 全网19套超热门表情包,小狗头、国王排名等我全部整理来了
  6. php消息撤回,“撤回”功能的技术方案设计尝试
  7. 调试Cello时快速清除已有容器
  8. 互联网金融诈骗不缺受害者, 有人刚被3M坑了又投入CA
  9. 大狼痛心疾首的碎碎念
  10. 跨域(什么样的请求方式才叫跨域请求?)