因為最近在複習yolo系列的演算法,就藉著這個機會總結一下自己對這個演算法的理解,由於是第一次寫演算法類的部落格,文中有什麼錯誤和行文不通的地方還希望大家指正。
yolov2與yolov1有很多改變。
最重要的改動:引入了anchor機制。v1通過最後接一個全連線層直接輸出bbox的座標。在yolov2中參考了fast-rcnn中的先驗框機制,通過卷積層來學習anchor的offsets避免了全連線層。為了試應anchor這一操作,作者在網路中移除了一個池化層,來獲得更高的網路輸出,並且為了得到奇數個grid cell,將網路的的輸入解析度從448轉為416.yolo網路降取樣32倍,所以最後輸出是13x13. 在引入了anchor機制後,每一個anchor都生成類別與空間的預測,而不是yolov1中每一個grid cell生成一個Bx5+C的預測,這一點的引入加強了yolo對密集小目標的檢測。在加入anchor後一張圖從原來生成98個boxes改為生成上千個anchor boxes。這樣做網路的Accuracy有所下降,但是recall召回率得到了顯著的提升,因為目前在自動駕駛行業工作,聯想到特斯拉之前在高速高速公路上把正樣本識別成負樣本所以在我看來自動駕駛中的目標檢測召回率是要比準確率更重要的一個指標。
使用k-means聚類得出anchor。在距離時如果修正函式選擇的還是歐氏距離的話,就會產生那個很經典的問題,大的目標框會比小目標框產生更大的error。所以為了使聚類時的distance不受框的大小影響,作者使用的一種新的距離計算方式:
這一操作有效的提高了最後結果的avg IOU,在自動駕駛的視覺方面,最後檢測框的位置精度很大程度上會影響測距的精度。
對於 location predict輸出內容的修改:對比RPN接面構,RPN輸出的是對anchor box的偏移量,這導致在模型訓練初期會有很多bbox出現在影像的任意位置,這導致了訓練初期模型的不穩定性,就是的訓練需要更長的時間達到收斂。yolov2使用了對grid cell的偏移量來作為最後結果的輸出,這使得與ground truth的差別落在了0和1直接,並在後面使用了sigmoid作為啟用函式來限制輸出。
最後網路輸出5個值 tx ty tw th 和to,其中tx ty是之前介紹過的對於grid cell的偏移量,tw和th是對預測框的寬高和anchor的修正值。to是和yolov1一樣是判定是否在grid cell中有物體並計算iou。最後輸出預測框結果如下:
其中Cx和Cy是產生這個bbox的grid cell對於影像左上角的偏移量。pw和ph是anchor的寬和高。
使用了更細顆粒化的特徵圖:yolov2沒有像ssd那樣使用多尺度的特徵圖來產生anchor去使用不同大小的物體。而實使用了passthrough層來結合之前的26x26的特徵圖來講最後的head部分特徵圖更finer-grained。
動態調整輸入圖片大小:由於yolov2的主幹網路只使用了卷積層和池化層,這使得網路可以動態的調整特徵圖大小。為了使演算法在不同解析度上的圖片表現的更好,在訓練階段,作者採用的了每10個batch就改變一下輸入影像的尺度,因為網路的降取樣是32倍,所以輸入也都是32的倍數,從308到608.
backbone方面的改變:
YOLOV2中作者提出了自己的網路Darknet-19,而不是像v1中在googLEnet上做修改。正如絕大多數目標檢測演算法的backbone一樣,darknet是一個分類網路,它把最後的全連線層換成了global average pooling層再接softmax層。整個網路只有卷積層和池化層,所以可以對輸入靈活修改。下圖為darknet的網路結構:
yolov2在每一個卷積層後都加入了BN層,在加入bn層後移除了訓練中dropout的操作
yolov2在分類資料集ImageNet上預訓練模型時直接使用了448x448解析度的網路輸入。在yolov1中預訓練模型時輸入的解析度是224x224,在檢測時才把解析度轉換成448x448
整個網路使用了19個卷積層和5個池化層。目前深度學習的網路設計思路就是加深加多引數,然後再去解決過擬合問題。