1. 程式人生 > >目標檢測演算法之SSD

目標檢測演算法之SSD

碼字不易,歡迎給個贊!

歡迎交流與轉載,文章會同步釋出在公眾號:機器學習演算法全棧工程師(Jeemy110)

目錄

前言

目標檢測近年來已經取得了很重要的進展,主流的演算法主要分為兩個型別:(1)two-stage方法,如R-CNN系演算法,其主要思路是先通過啟發式方法(selective search)或者CNN網路(RPN)產生一系列稀疏的候選框,然後對這些候選框進行分類與迴歸,two-stage方法的優勢是準確度高;(2)one-stage方法,如Yolo和SSD,其主要思路是均勻地在圖片的不同位置進行密集抽樣,抽樣時可以採用不同尺度和長寬比,然後利用CNN提取特徵後直接進行分類與迴歸,整個過程只需要一步,所以其優勢是速度快,但是均勻的密集取樣的一個重要缺點是訓練比較困難,這主要是因為正樣本與負樣本(背景)極其不均衡(參見

Focal Loss),導致模型準確度稍低。不同演算法的效能如圖1所示,可以看到兩類方法在準確度和速度上的差異。

這裡寫圖片描述

圖1 不同檢測演算法的效能對比

本文講解的是SSD演算法,其英文全名是Single Shot MultiBox Detector,名字取得不錯,Single shot指明瞭SSD演算法屬於one-stage方法,MultiBox指明瞭SSD是多框預測。在上一篇文章中我們已經講了Yolo演算法,從圖1也可以看到,SSD演算法在準確度和速度(除了SSD512)上都比Yolo要好很多。圖2給出了不同演算法的基本框架圖,對於Faster R-CNN,其先通過CNN得到候選框,然後再進行分類與迴歸,而Yolo與SSD可以一步到位完成檢測。相比Yolo,SSD採用CNN來直接進行檢測,而不是像Yolo那樣在全連線層之後做檢測。其實採用卷積直接做檢測只是SSD相比Yolo的其中一個不同點,另外還有兩個重要的改變,一是SSD提取了不同尺度的特徵圖來做檢測,大尺度特徵圖(較靠前的特徵圖)可以用來檢測小物體,而小尺度特徵圖(較靠後的特徵圖)用來檢測大物體;二是SSD採用了不同尺度和長寬比的先驗框(Prior boxes, Default boxes,在Faster R-CNN中叫做錨,Anchors)。Yolo演算法缺點是難以檢測小目標,而且定位不準,但是這幾點重要改進使得SSD在一定程度上克服這些缺點。下面我們詳細講解SDD演算法的原理,並最後給出如何用TensorFlow實現SSD演算法。

這裡寫圖片描述

圖2 不同演算法的基本框架圖

設計理念

SSD和Yolo一樣都是採用一個CNN網路來進行檢測,但是卻採用了多尺度的特徵圖,其基本架構如圖3所示。下面將SSD核心設計理念總結為以下三點:

這裡寫圖片描述

圖3 SSD基本框架

(1)採用多尺度特徵圖用於檢測
所謂多尺度採用大小不同的特徵圖,CNN網路一般前面的特徵圖比較大,後面會逐漸採用stride=2的卷積或者pool來降低特徵圖大小,這正如圖3所示,一個比較大的特徵圖和一個比較小的特徵圖,它們都用來做檢測。這樣做的好處是比較大的特徵圖來用來檢測相對較小的目標,而小的特徵圖負責檢測大目標,如圖4所示,8x8的特徵圖可以劃分更多的單元,但是其每個單元的先驗框尺度比較小。

這裡寫圖片描述

圖4 不同尺度的特徵圖

(2)採用卷積進行檢測
與Yolo最後採用全連線層不同,SSD直接採用卷積對不同的特徵圖來進行提取檢測結果。對於形狀為m×n×p的特徵圖,只需要採用3×3×p這樣比較小的卷積核得到檢測值。
(3)設定先驗框
在Yolo中,每個單元預測多個邊界框,但是其都是相對這個單元本身(正方塊),但是真實目標的形狀是多變的,Yolo需要在訓練過程中自適應目標的形狀。而SSD借鑑了Faster R-CNN中anchor的理念,每個單元設定尺度或者長寬比不同的先驗框,預測的邊界框(bounding boxes)是以這些先驗框為基準的,在一定程度上減少訓練難度。一般情況下,每個單元會設定多個先驗框,其尺度和長寬比存在差異,如圖5所示,可以看到每個單元使用了4個不同的先驗框,圖片中貓和狗分別採用最適合它們形狀的先驗框來進行訓練,後面會詳細講解訓練過程中的先驗框匹配原則。

這裡寫圖片描述

圖5 SSD的先驗框

SSD的檢測值也與Yolo不太一樣。對於每個單元的每個先驗框,其都輸出一套獨立的檢測值,對應一個邊界框,主要分為兩個部分。第一部分是各個類別的置信度或者評分,值得注意的是SSD將背景也當做了一個特殊的類別,如果檢測目標共有c個類別,SSD其實需要預測c+1個置信度值,其中第一個置信度指的是不含目標或者屬於背景的評分。後面當我們說c個類別置信度時,請記住裡面包含背景那個特殊的類別,即真實的檢測類別只有c1個。在預測過程中,置信度最高的那個類別就是邊界框所屬的類別,特別地,當第一個置信度值最高時,表示邊界框中並不包含目標。第二部分就是邊界框的location,包含4個值(cx,cy,w,h),分別表示邊界框的中心座標以及寬高。但是真實預測值其實只是邊界框相對於先驗框的轉換值(paper裡面說是offset,但是覺得transformation更合適,參見R-CNN)。先驗框位置用d=(dcx,dcy,dw,dh)表示,其對應邊界框用b=(bcx,bcy,bw,bh)表示,那麼邊界框的預測值l其實是b相對於d的轉換值:

lcx=(bcxdcx)/dw,lcy=(bcydcy)/dhlw=log(bw/dw),lh=log(bh/dh)
習慣上,我們稱上面這個過程為邊界框的編碼(encode),預測時,你需要反向這個過程,即進行解碼(decode),從預測值l中得到邊界框的真實位置b
bcx=dwlcx+dcx,bcy=dylcy+dcybw=dwexp(lw),bh=dhexp(lh)
然而,在SSD的Caffe原始碼