目錄:
模型的整個前向傳播過程
train.py入手
detector子產品
backbone子產品
build_box_head
先驗框/資料集生成有關
build子產品
transform子產品
prior_bbox的生成
box_utils
餘下的一些子產品
loss子產品
配置檔案子產品
SSD源碼解析
本片文章主要是承接上一篇,記錄了對pytorch SSD源碼的一個解析(主要是怕自己過段時間忘了,當然也希望發出來和大家分享一下學習心得),過于細枝末節的東西不是很多,主要是對整個流程的結構進行梳理,整個梳理過程建議配合講解SSD原理的文章食用,推薦:
小小将:目标檢測|SSD原理與實作zhuanlan.zhihu.com
的這篇硬核講解
先看講原理的文章(多半是蒙圈的),然後來看這裡的代碼細節,這樣一來基本上就能夠對整個SSD的核心流程有一個大概的把握。鑒于自己水準有限,難免會有了解不到位或者錯誤的地方,希望大佬拍磚
本文所用源碼位址:
lufficc/SSDgithub.com
模型的整個前向傳播過程
train.py入手
從train.py入手,先看模型的整個調用關系
from
detector子產品
- ssd/modeling/detector/_ init_ .py
from
- 找SSDDetector的定義位置
from
由此可知:build_backbone和build_box_head是關鍵,下面分别解釋
backbone子產品
- build_backbone:對于backbone部分的定義在ssd.modeling.backbone檔案夾下面,作者提供了vggnet, mobileNetv2,efficient_net三個backbone。可以在代碼中看到具體的定義,最需要關注的是從backbone不同階段取出來(進行下一步卷積得到框的類别,位置)的幾個特征圖。以vggnet為例:
build_box_head
- build_box_head,這部分是最不好了解但又是極為關鍵的,
# ssd/modeling/box_head/下面定義的 SSDBoxHead 類
- make_box_predictor :上面的計算預測值的過程由ssd/modeling/box_head/box_predictor 中的make_box_predictor來執行,這是一個相當關鍵的步驟
這樣一來,基本就理清楚了整個網絡的前向過程,接下來需要搞清楚的是上面提到的我們的target是怎麼來的,我們現在知道了模型總共預測了8732個框,
也知道target中對應的gt_labels和gt_boxes負責和預測得到的cls_logits ,bbox_pred一一對應計算loss是以接下來就是要知道target中的gt_labels([32, 8732])和gt_boxes[32, 8732, 4]是怎麼來的。這裡也就引出了SSD中很關鍵的一部分了,那就是prior boxes的産生。
先驗框/資料集生成有關
target中對應的gt_labels和gt_boxes負責和預測得到的cls_logits ,bbox_pred一一對應計算loss。是以接下來從源碼中來解讀target中的gt_labels([32, 8732])和gt_boxes[32, 8732, 4]是怎麼來的
build子產品
還是回到train.py
from
下面要仔細的解釋一下為什麼我們的原始标簽和bbox的坐标就突然和先驗框聯系起來了。上面的整個追溯流程中make_data_loader的定義是關鍵,
'''
transform子產品
雖然說transform子產品的工作就是對原始的标注資料作出各種資料增強的變換:随機裁剪,鏡像,對比度/亮度,通道交換順序等操作。但是在build_target_transform中還調用到了PriorBox,進而聯系到了target_transform.py中調用的 box_utils子產品,這其實就突破點。
要把這個說清楚,還得先搞清楚一個東西,那就是prior_bbox的産生
prior_bbox的生成
這個在網上許多講SSD原理的文章中都會重點講,其實前面的代碼分析中也出現過一些鋪墊。簡而言之:就是在原圖的尺度下産生了8732個先驗框,這些框和我們取的6個特征圖大小是有關的,按照這六個的大小設計會産生出原圖尺度上的8732個框
#在ssd/modeling/anchors/prior_box.py
box_utils
- /ssd/data/transforms的init.py : 繼續回到transform子產品,可以在/ssd/data/transforms的init.py中第30行看到調用了Prior_box類!
def
- ssd/data/transforms/target_transform.py下面的SSDTargetTransform類 :
#ssd/data/transforms/target_transform.py下面的SSDTargetTransform類
- 顯然,這一步就需要去研究 box_utils子產品
#convert_locations_to_boxes其實是把ssd的輸出location(這裡的輸出其實是位置的偏置)
前面理順了網絡的整體前向結構,剛剛又分析了prior_boxes有關的datasets的一系列操作,最後就是來分析一下loss和一些配置檔案了
餘下的一些子產品
loss子產品
整個關于loss的定義在loss.py子產品下的MultiBoxLoss類,具體的計算公式在許多的講SSD原理的文章中都有提到,結合下面原作者已經很詳細的注釋了的源碼,其實也不難了解,是以此處不再贅述
class
配置檔案子產品
defaults.py:這個是整個工程的基本配置檔案,有了上面的一系列鋪墊,現在來看配置檔案裡面的各項參數設定就顯得明了多了
#......