天天看點

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

(Tensorflow Object detection Api)安裝

(Tensorflow Object Detection Api)标注資料擷取及格式轉換

(Tensorflow Object Detection Api)模型訓練

通過前面三次分享,基本把Object Detection Api的入門使用方式就都陳列了出來。接下來計劃分享一下算法的具體結構和代碼的部分,以及相關的參數調試方法。畢竟,真正拿來用的話,根據場景的不同,需要不同的性能和側重點。如下,僅對ssd-mobilenet-v1進行分享。

ssd原文 MobileNet V1論文

兩個月前剛開始搞物體檢測的項目的時候,我的想法是比較naive的,由于我要檢測的物體隻有一類,我嘗試自己按照VGG-16的想法設計了簡單版的網絡的結構,然後直接預測左上角和右下角坐标。之是以這麼想,是因為覺得深度學習那麼強大,這麼簡單的功能應該很好實作想要的效果。可是,事與願違,直接預測坐标的想法在真正實踐的時候,準确率我都不好意思說出來。

在之後研讀各種物體檢測算法的過程中,發現其實神經網絡并沒有強大到傻瓜式操作的境界,它還是需要精心的喂養,并且需要盡量多的提供給它各種次元的資訊,更加要考慮如何為它減負,而不是刁難它。

提供的資訊越多,神經網絡的表現自然更好,比如在Reid中,有些人就嘗試在将原有資料集中的人的其他屬性,諸如衣服顔色,性别,年齡等加入到訓練中,這樣訓練出來的網絡在Reid上的效果有很大提升,參見Improving Person Re-identification by Attribute and Identity Learning。

閑話太多了,開始講故事。RCNN系列的故事我這裡是不講的,這裡是按着YOLO和SSD的風格來講的。

到底該如何檢測圖檔中的物體呢?看下面的圖吧。将原圖打散成7*7的格子,基于每個格子再預設2個不同長寬比的虛拟框,然後調整虛拟框的大小以使得虛拟框來拟合真實的物體邊框。大概的想法就是這樣的。模型不需要從整張圖檔的角度來預測物體的位置,而是從局部的角度來進行預測,為模型減負。而且,預設的不同長寬比的虛拟框,也是減輕模型負擔的一種方式,其實也給模型提供了更多的資訊。大概的思路就是如此。但是真正實施起來,各路大神開始各顯神通。我們先來說SSD。

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

(一)先要說一些概念:見下圖

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

(二)剛才說過,将圖檔打散成7*7的格子,然後針對每一個格子進行相應的預測。而神經網絡的不同的部分的特征圖其實就可以看作原圖像打不同細緻程度的格子的結果,因為随着網絡深度增加,每個節點的感受野增大了,是以越往後的特征圖打格子的程度越粗。反之越細緻。不同細緻程度的特征圖正好可以用來檢測不同大小的物體,正如下圖所解釋的。

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

(三)了解到這裡之後,我們就可以看SSD-300的網絡圖:

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹
(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹
(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

看到這裡應該也都不難了解,隻是對不同的特征圖進行預測。

(四)具體的邊框參數設定

剛才說了将圖檔打成格子後,每個格子會相應有若幹個不同長寬比的虛拟框,那麼這些虛拟框的大小到底是多大呢?不同特征圖上的虛拟框的大小又有何差別?有一個前提,實作我們會将物體對應的真實邊框坐标歸一化,也就是相應的除以原始圖檔的長和寬。是以,下面說到的參數都是在0,1之間。

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹
(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

這是ssd的default box的大小的設定方式。

(五)到底是怎麼訓練啊?

如果隻是看上面這些理論,估計很難搞懂。下面具體說一下,上面這些理論是怎麼具體串起來的。

1、資料歸一化

模型真正讀進去的資料是剛才說的歸一化之後的資料,也就是需要把标注的坐标和得到的物體的長和寬除以原始圖檔的長和寬。具體代碼

注意:嚴格意義上講,這裡所标注的資料,并不是真正意義上的訓練資料,因為後面ssd自己有一套方法來根據default box來産生訓練資料。

2、訓練資料生成

按照前面的說法,ssd-300共有8732個預測框,但是前期訓練的時候,并不是每一張圖檔輸進去,就基于所有的預測框給一個損失函數,然後反向傳播。而是在8732個預測框中有針對性的選擇一部分來作為訓練資料,包括正例(含有物體的框)和反例(背景框),反例(背景框)的選取還是有講究的,畢竟大部分框都是背景框,如果都拿來訓練,那麼會造成嚴重的類别不平衡。

正例的産生: tensorflow 相關代碼

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

我想上面的解釋還是不錯的,裡面的IOU稱為交并比,其實就是兩個框的交集的面積除以它們并集的面積,也稱為jaccard overlap 或者 jaccard 距離,以此來度量兩個框的相似度:

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

反例的産生—Hard example miner

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

注:背景框的定位損失預設為[0,0,0,0] 相關代碼

tensorflow給出的反例産生的代碼段的連結

config檔案中的hard_example_miner參數設定:

hard_example_miner {
        num_hard_examples: 
        iou_threshold: 
        loss_type: CLASSIFICATION
        max_negatives_per_positive: 
        min_negatives_per_image: 
      }
           

1)0.99 相當于不進行NMS,隻是單純的按損失排序。是以,這個參數盡量不要動,否則就違背了SSD模型的原意。

2)loss_type 是選擇排序所用的損失的類型:classification, localization, both,三種。相關代碼連結在這裡。

3、損失函數

損失函數分為兩部分:定位損失和分類損失,對于反例預測框,其定位損失是零。

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

(六)mobileNet v1

原文在此,核心的想法是經典的卷積操作轉化為 深度可分離卷積

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

mobilenet v1 網絡架構:

(Tensorflow Object Detection Api)ssd-mobilenet v1 算法結構及代碼介紹

相關代碼

用此網絡來替換前面ssd網絡架構中的VGG16,所得到的模型即為ssd-mobilenet v1. 最終從此網絡中選取兩個特征圖,及後續再産生4個特征圖,總共6個特征圖來作為ssd用來進行檢測的特征圖相關代碼。

繼續閱讀