当前位置: 首页>編程日記>正文

目标检测 SSD论文理解

目标检测 SSD论文理解

此文章只是自己看论文和博客的一些总结和通过代码得到的一些细节,为了以后自己方便查阅,如有错误,欢迎指正。

1.论文和SSD-tensorflow代码

论文地址:https://arxiv.org/abs/1512.02325

代码链接:https://github.com/balancap/SSD-Tensorflow

2.yolo算法与SSD算法区别

 two-stage方法:主要用到的是faster RCNN,此算法主要是通过RPN网络产生一些候选框,然后再对这些候选框进行分类和回归,此算法的MPA很高,但是相比one-stage方法来说,他的速度很低。

one-stage方法:主要是yolo算法与SSD算法,他们都是利用CNN提取特征后直接分类与回归,整个过程只需要一步,所以其优势是速度比较快。Yolo V1算法是直接将图片分成了SxS 个网格(grid cell),在对SxS每个单元产生bbox, 因此yolo的缺点是难以检测小目标,而且定位不准,但是相比SSD几点重要改进使得在一定程度上克服Yolo的缺点:

(1)  SSD提取了不同尺度的特征图来做检测,CNN网络前面的特征图由于含有丰富的特征信息因此可以用来检测小目标,而CNN网络后面的特征图则可以检测大目标;

(2)  SSD采用了不同尺度和长宽比的先验框(Prior boxes在Faster R-CNN中是Anchors)。

(3)  SSD采用的是CNN直接进行检测,而不是像Yolo在全连接之后作检测。

3.SSD网络结构

SSD采用VGG16作为基础模型,然后在VGG16的基础上新增了卷积层来获得更多的特征图以用于检测。SSD的网络结构如下图所示。上面是SSD模型,下面是Yolo模型,可以明显看到SSD利用了多尺度的特征图做检测。模型的输入图片大小是 300×300 ,也可以是512×512。

VGG16中的Conv4_3层将作为用于检测的第一个特征图。conv4_3层特征图大小是 38\times38 ,但是该层比较靠前,其值较大,所以在其后面增加了L2 Normalization层,目的是为了和后面的特征图的值差异不大,他和Batch Normalization层不一样,其仅仅是对每个像素点在channle维度做归一化,而Batch Normalization层是在[batch_size, width, height]三个维度上做归一化。然后就是后面卷积层中提取Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2作为检测所用的特征图,加上Conv4_3层,共提取了6个特征图,其特征图的大小分别是 (38,38),(19,19),(10,10),(5,5),(3,3),(1,1)。

4.如何设置先验框

先验框其实是文章的重点,6不同的特征图他们每个单元产生的anchors的数量是不同的,第一个特征图和后两个特征图每个单元是生成4个anchors,其余三个每个单元生成的是6个anchors。我们先拿第2个特征图为例(第一个特征图是单独设置的)也就是conv7提取到的特征图,来说明如何生成anchors(也就是前面说的先验框),特征图的的大小是19×19。首先需要设置anchors的尺度和长宽比,anchors尺度的设置用到了这样一个公式:

由于第一个特征图是单独设置的则上面公式m=5,表示的是anchors的尺度相对于原始图片的比例,s_{min}s_{max} 表示比例的最小值与最大值,paper里面取0.2和0.9(在tensorflow代码中是0.15,0.9)。对于第一个特征图,其先验框的尺度比例一般设置为 s_{min}/2=0.1 ,那么尺度为300×0.1=30(在tensorflow代码中应该是300×0.15/2约等于21),第二个特征图的尺度是300×0.2=60(在tensorflow代码中应该是300×0.15等于45),可以得到各个特征图的尺度为111,162,213,264(取得是近似值)。

对于长宽比,一般选取 a_r\in \{1,2,3,\frac{1}{2},\frac{1}{3}\} ,对于特定的长宽比,按如下公式计算先验框的宽度与高度(后面的 s_k 均指的是先验框实际尺度,而不是尺度比例):

w^a_{k}=s_k\sqrt{a_r},\space h^a_{k}=s_k/\sqrt{a_r}

默认情况下,每个特征图会有一个 a_r=1 且尺度为 s_k 的先验框,除此之外,还会设置一个尺度为 s'_{k}=\sqrt{s_k s_{k+1}}a_r=1 的先验框,这样每个特征图都设置了两个长宽比为1但大小不同的正方形先验框。注意最后一个特征图需要参考一个虚拟 s_{m+1}=300\times105/100=315 来计算 s'_{m} 。因此,每个特征图一共有 6 个先验框 \{1,2,3,\frac{1}{2},\frac{1}{3},1'\} ,但是在实现时,Conv4_3,Conv10_2和Conv11_2层仅使用4个先验框,它们不使用长宽比为 3,1/3 的先验框。在tensorflow代码中,s_{min}s_{max} 比例分别是0.15,0.9对与第1个特征图的4个anchors的w1=21×1/300=21,h1=21/1/300=21,w2=21×\sqrt{2}/300,h2=21/\sqrt{2}/300,......w4=\sqrt{21*45}×1/300,h4=\sqrt{21*45}/1/300。这里面的除以原图的尺度300都是为了归一化。确定了anchors的尺度和大小之后在确定anchors的中心坐标也就是x,y。

中心坐标x,y的确定,拿第一个特征图为例,它的维度是(38,38,512),原图像有300×300到目前的38×38,大小缩小了300/38约等于8,则知道特征图每个单元的坐标值然后再乘上8就得到了与特征图每个像素相对应的原图像得坐标值,这些坐标值也都是归一化的。

有以上可知对于SSD300则先验框的总数量是(先验框对应着预测框数量是相等的):

5.边界框的确定(也就是预测框)

在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。

SSD的检测值也与Yolo不太一样。对于每个单元的每个先验框,其都输出一套独立的检测值,对应一个边界框,主要分为两个部分。第一部分是各个类别的置信度或者评分,值得注意的是SSD将背景也当做了一个特殊的类别,如果检测目标共有 c 个类别,SSD其实需要预测 c+1 个置信度值,其中第一个置信度指的是不含目标或者属于背景的评分。后面当我们说 c 个类别置信度时,请记住里面包含背景那个特殊的类别,即真实的检测类别只有 c-1 个。在预测过程中,置信度最高的那个类别就是边界框所属的类别,特别地,当第一个置信度值最高时,表示边界框中并不包含目标。第二部分就是边界框的location,包含4个值 (cx, cy, w, h) ,分别表示边界框的中心坐标以及宽高。但是真实预测值其实只是边界框相对于先验框的转换值(paper里面说是offset)。

先验框位置用 d=(d^{cx}, d^{cy}, d^w, d^h) 表示,其对应边界框是 b=(b^{cx}, b^{cy}, b^w, b^h) ,那么边界框的预测值 l 其实是 b 相对于 d 的转换值:

l^{cx} = (b^{cx} - d^{cx})/d^w, \space l^{cy} = (b^{cy} - d^{cy})/d^h

l^{w} = \log(b^{w}/d^w), \space l^{h} = \log(b^{h}/d^h)

习惯上,我们称上面这个过程为边界框的编码(encode),预测时,你需要反向这个过程,即进行解码(decode),从预测值 l 中得到边界框的真实位置 b

b^{cx}=d^w l^{cx} + d^{cx}, \space b^{cy}=d^y l^{cy} + d^{cy}

b^{w}=d^w \exp(l^{w}), \space b^{h}=d^h \exp(l^{h})

在tensorflow代码中其offset的预测方法是:拿38×38×512这个特征图来说:

对offset位置预测首先对这个特征图进行3×3的卷积,卷积核的层数是16层,然后得到的就是维度(batch_size,38,38,16)然后再对这个矩阵在最后一维进行展开得到的是(batch_size,38,38,4,4)那么最后一维就是对每个单元的预测offset是(x,y,w,h)。

类别预测首先对这个特征图进行3×3的卷积,卷积核的层数是4×21层,然后得到的就是维度(batch_size,38,38,84)然后再对这个矩阵在最后一维进行展开得到的是(batch_size,38,38,4,21)。

6.正负样本的选择

训练过程中,首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。在Yolo中,ground truth的中心落在哪个单元格,该单元格中与其IOU最大的边界框负责预测它。但对于SSD就不同:

第一个原则是:对于图片中每个ground truth,找到与其IOU最大的先验框,该先验框与其匹配,这样,可以保证每个ground truth一定与某个先验框匹配。通常称与ground truth匹配的先验框为正样本,反之,若一个先验框没有与任何ground truth进行匹配,那么该先验框只能与背景匹配,就是负样本。一个图片中ground truth是非常少的, 而先验框却很多,如果仅按第一个原则匹配,很多先验框会是负样本,正负样本极其不平衡,所以需要第二个原则。

第二个原则是:对于剩余的未匹配先验框,若某个ground truth的 \text{IOU} 大于某个阈值(一般是0.5),那么该先验框也与这个ground truth进行匹配。这意味着某个ground truth可能与多个先验框匹配,这是可以的。但是反过来却不可以,因为一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框 \text{IOU} 大于阈值,那么先验框只与IOU最大的那个先验框进行匹配。第二个原则一定在第一个原则之后进行,仔细考虑一下这种情况,如果某个ground truth所对应最大 \text{IOU} 小于阈值,并且所匹配的先验框却与另外一个ground truth的 \text{IOU} 大于阈值,那么该先验框应该匹配谁,答案应该是前者,首先要确保某个ground truth一定有一个先验框与之匹配。但是,这种情况我觉得基本上是不存在的。由于先验框很多,某个ground truth的最大 \text{IOU} 肯定大于阈值,所以可能只实施第二个原则既可以了。这里的tensorflow就是只实施了第二个原则,但是这里的两个原则都实施了。下图为一个匹配示意图,其中绿色的GT是ground truth,红色为先验框,FP表示负样本,TP表示正样本。

尽管一个ground truth可以与多个先验框匹配,但是ground truth相对先验框还是太少了,所以负样本相对正样本会很多。为了保证正负样本尽量平衡,SSD采用了hard negative mining,就是对负样本进行抽样,抽样时按照置信度误差(预测背景的置信度越小,误差越大)进行降序排列,选取误差的较大的top-k作为训练的负样本,以保证正负样本比例接近1:3。

7.损失函数

损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和:

L(x, c, l, g) = \frac{1}{N}(L_{conf}(x,c) + \alpha L_{loc}(x,l,g))

其中 N 是先验框的正样本数量。这里 x^p_{ij}\in \{ 1,0 \} 为一个指示参数,当 x^p_{ij}= 1 时表示第 i 个先验框与第 j 个ground truth匹配,并且ground truth的类别为 pc 为类别置信度预测值。 l 为先验框的所对应边界框的位置预测值,而 g 是ground truth的位置参数。对于位置误差,其采用Smooth L1 loss,定义如下:

由于 x^p_{ij} 的存在,所以位置误差仅针对正样本进行计算。值得注意的是,要先对ground truth的 g 进行编码得到 \hat{g} ,因为预测值 l 也是编码值,若设置variance_encoded_in_target=True,编码时要加上variance:

 

 

\hat{g}^{cx}_j = (g^{cx}_j - d^{cx}_i)/d^w_i/variance[0], \hat{g}^{cy}_j = (g^{cy}_j - d^{cy}_i)/d^h_i/variance[1]

\hat{g}^{w}_j = \log(g^{w}_j/d^w_i)/variance[2], \space \hat{g}^{h}_j = \log(g^{h}_j/d^h_i)/variance[3]

对于置信度误差,其采用softmax loss:

权重系数 \alpha 通过交叉验证设置为1。

8.Data Augmentation

Data Augmentation可以提升SSD的性能,主要采用的技术有水平翻转(horizontal flip),随机裁剪加颜色扭曲(random crop & color distortion),随机采集块域(Randomly sample a patch)(获取小目标训练样本)。这个方式在识别网络中用的很多,而且这种方式确实给网络的性能带来很大的提升。

9.预测过程

预测过程比较简单,对于每个预测框,首先根据类别置信度确定其类别(置信度最大者)与置信度值,并过滤掉属于背景的预测框。然后根据置信度阈值(如0.5)过滤掉阈值较低的预测框。对于留下的预测框进行解码,根据先验框得到其真实的位置参数(解码后一般还需要做clip,防止预测框位置超出图片)。解码之后,一般需要根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。最后就是进行NMS算法,过滤掉那些重叠度较大的预测框。最后剩余的预测框就是检测结果了。

 


https://www.fengoutiyan.com/post/14683.html

相关文章:

  • ssd算法原理
  • ssd算法详解
  • 论文目标怎么写
  • 论文研究目标模板
  • ssd论文
  • 目标检测论文
  • 论文主要研究内容
  • ssd算法
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機