【目標檢測】【深度學習】【Pytorch版本】YOLOV1模型算法詳解
文章目錄
- 【目標檢測】【深度學習】【Pytorch版本】YOLOV1模型算法詳解
- 前言
- YOLOV1的模型結構
- YOLOV1模型的基本執行流程
- YOLOV1模型的網絡參數
- YOLOV1模型的訓練方式
- YOLOV1的核心思想
- 前向傳播階段
- 網格單元(grid cell)的概念及其作用
- 輸出結果的后處理過程以及作用
- 反向傳播階段
- 總結
前言
YOLOV1是由華盛頓大學的Joseph Redmon等人《You Only Look Once:
Unified, Real-Time Object Detection【CVPR-2016】》【論文地址】一文中提出的首個單階段目標檢測模型,核心思想是將目標檢測轉化為回歸問題求解,并基于一個單獨的端到端(end-to-end)網絡,利用全卷積神經網絡直接從整張原始圖像中預測物體的位置和類別,無需生成候選區域,從而大大提高了檢測速度。
傳統的目標檢測方法通常包括候選區域生成、特征提取、分類和邊界框回歸等步驟,這些步驟通常是分開進行的,導致處理速度較慢。隨著深度學習技術尤其是卷積神經網絡(CNN)的發展,研究人員開始嘗試將CNN應用于目標檢測任務中。在YOLOv1出現之前,主流的目標檢測算法如R-CNN系列采用了兩階段的方法:首先生成一系列可能包含物體的候選區域(region proposals),然后對這些候選區域進行分類和邊界框回歸。這種方法雖然精度較高,但計算成本大、速度慢,因為它們需要對每個候選區域單獨處理。
YOLOV1的模型結構
YOLOV1模型的基本執行流程
下圖是博主根據原論文提供的YOLOV1模型結構重新繪制的詳細結構示意圖:
基本流程: 將圖像reshape成448×448的圖像,24個卷積層對輸入圖像進行特征提取生成一個7×7×1024的特征圖,將這個特征圖拉平后,第1個全連接層將卷積得到的分布式特征映射到樣本標記空間,把輸入圖像的所有卷積特征整合到一起,第二個全連接層將所有神經元得到的卷積特征進行維度轉換,最后reshape成7×7×30的特征圖,其中包含了檢測框的位置、大小、置信度以及分類條件概率。
YOLO網絡借鑒了GoogLeNet,結構簡單,包含卷積、池化、激活函數以及全連接層,其中使用了1x1卷積用于多通道信息融合。
YOLOV1模型的網絡參數
YOLOV1網絡參數: YOLOV1網絡借鑒了GoogLeNet,結構簡單,包含卷積、池化、激活函數以及全連接層,其中使用了1x1卷積用于多通道信息融合。除了最后一全連接層使用了線性激活函數外(可以理解成沒有進行任何激活操作),其余卷積層和全連接層的激活函數為Leaky ReLU。
YOLOV1模型的訓練方式
YOLOV1訓練分為兩個階段:
- 在ImageNet分類數據集上預訓練分類模型。網絡模型的輸入為224x224,前20層卷積層作為模型的特征提取網絡,隨后利用全局平均池化層進行池化操作,最后利用全連接層進行1000分類;
- 將分類模型調整為檢測模型。將網絡模型的輸入調整為448x448,去除全局平均池化層,并新加入4個卷積層和2個全連接層,最后將模型的輸出調整為7×7×30這樣的向量大小。
在訓練中使用了Dropout與數據增強方法來防止過擬合。
YOLOV1的核心思想
前向傳播階段
網格單元(grid cell)的概念及其作用
網格單元的劃分: YOLOV1模型輸出7×7分辨率大小的特征圖,標記出輸出特征圖每個像素在原始圖片上的對應區域,即將原始圖片劃分為7×7個小方格大小的圖片區域塊,每個區域塊大小為64×64。
將原始圖片劃分為7×7個小方格并不是真正的將圖片劃分為7×7塊小圖像區域,只不過是輸出的特征圖的分辨率大小為7×7,其中每個1×1的特征像素都有對應的圖像區域。
網格單元的作用: 每個grid cell預測多個邊界框(YOLOV1中選擇2個),預測結果包含倆部分信息:
- 邊界框的基本信息:每個框固定包含5個元素,分別為是中心坐標x和y,檢測框的寬高w和h以及對應檢測框的置信度c;
- 多類別物體的概率值:類似于圖像分類任務,根據實際的任務需求的不同,類別物體個數是不固定,因此YOLOV1最終的輸出是5×2+類別物體個數,當前任務的是30=2×5+20。
當前任務的每個grid cell輸出的數據維度為30×1,而7×7個方格輸出的維度即為7×7×30,檢查框的個數為7×7×2。
注意:這里一個grid cell只能預測一個物體類別,而不是一個檢測框預測一個類別,因為倆個檢測框通用(綁定)同一個多類別物體的概率值,后續的YOLO版本對其進行了改進。
網格單元邊界框位置解析: 紅色區域指定當前grid cell,白點表示當前grid cell左上角坐標(0,0);橙色和淺綠色代表當前grid cell的倆個邊界框;橙色點和淺綠色表示這兩個邊界框的中心坐標,且中心坐標一定在當前grid cell內部;邊界框左邊和上邊的不同顏色的值分別表示對應的邊界框的高和寬。
坐標值是經過歸一化后的值(在0-1之間),以左上坐標(0,0)的為坐標起始點參考;同樣邊界框的寬高也是經過歸一化后的值,表示邊界框的寬高相對于原始圖像的寬高(448×448)的比值。
網格單元邊界框置信度解析: 置信度 C C C用于評估模型預測的邊界框內包含某個對象的可能性以及該邊界框的準確性。
C = Pr ? ( O b j e c t ) × I O U p r e d t r u t h C = \Pr (O{\rm{bject}}) \times IOU_{{\rm{pred}}}^{{\rm{truth}}} C=Pr(Object)×IOUpredtruth?
- 包含對象的可能性 P r ( O b j e c t ) Pr (O{\rm{bject}}) Pr(Object):指的是模型對于某個邊界框內存在特定對象的確信程度,反映了模型認為該邊界框確實包含了某個對象的信心水平,認為在當前邊界框內有一個或多個對象存在的概率。這個概率,并非指具體某個類別對象在邊界框內的概率,而是任意一個類別對象在邊界框內的概率,只要不是背景的;
- 邊界框的準確性 I O U p r e d t r u t h IOU_{{\rm{pred}}}^{{\rm{truth}}} IOUpredtruth?:通過計算預測邊界框與真實邊界框(ground truth)之間的交并比(Intersection over Union, IoU)來衡量的,IoU是介于0到1之間的值,表示兩個邊界框重疊面積占它們合并面積的比例。值越接近1,說明預測的邊界框與真實邊界框越吻合。同時在非極大值抑制計算中IOU作為其中的重要指標。
網格單元類別概率值解析: 每個小方格都會輸出對應的20個類別中概率最高的類別,輸出的概率利用Softmax函數進行映射,維度為20×1。20個類別個數并不是固定的,而是隨任務不同而不同,只是當前博文展示的任務類別是20,
注意:如上圖,邊界框并不是每個相同分類的小方格拼接在一起后繪制出的總區域,而是前面提到的每個小方格單獨預測的。
網格單元內容總結: 在邊界框示意圖中,置信度越大,邊界框越粗,證明其中存在目標的可能性越大;在概率圖中,標記出物體類別概率的最大的類。
到此為止,網格單元(grid cell)的所扮演的角色以及其作用已經全部講解完成,下一步則是對網格單元的輸出結果進行篩選。
輸出結果的后處理過程以及作用
類別置信度篩選: 在有物體的情況下,對應類別的物體的置信度,其公式為:
C i = Pr ? ( C l a s s i ∣ O b j e c t ) × Pr ? ( O b j e c t ) × I O U p r e d t r u t h {C_i} = \Pr (Clas{s_i}|O{\rm{bject}}) \times \Pr (O{\rm{bject}}) \times IOU_{{\rm{pred}}}^{{\rm{truth}}} Ci?=Pr(Classi?∣Object)×Pr(Object)×IOUpredtruth?
從公式中不難理解論文作者表達的含義:置信度即表示一種自信程度,包含了邊界框內有物體的自信程度、物體歸屬于某個類型的自信程度以及邊界框將將整個物體包括進來的自信程度。下圖中框上的數值表示類別置信度的值,可以通過設置類別置信度閾值,剔除一部分置信度低于閾值的邊界框。
根據博主的經驗,因為類別置信度和置信度的性質和作用相似,因此一般不會通過設置類別置信度閾值來篩選合格的邊界框,而是直接通過設置置信度閾值就進行篩選,可以省略計算類別置信度這個步驟。
非極大值抑制篩選: NMS(Non-Maximum Suppression)主要目的是在檢測到的多個重疊邊界框中選擇最準確的一個作為最終結果,去除多余的重疊框。每個類別的所有邊界框之間單獨進行互相比較,不同類別邊界框之間不會互相比較,并且不同類別間是并行處理的。
以檢測狗為例,NMS算法流程:
- 得分排序:根據每個邊界框的置信度得分對所有框進行排序作為候選列表;
- 選擇最高分:選取得分最高的邊界框作為一個確定有效的檢測結果,加入到已選列表中成為已選框,并從候選列表中移除它;
- 抑制操作:計算所有候選框與所有已選框之間的IoU。依次取出刪除候選列表中的候選框,和所有已選框進行IoU比較,假設當前候選框與某個已選框的IoU大于設定的閾值,則認為這兩個框高度重合,刪除得分較低的那個框,保留得分高的框在已選列表中;反之,假設當前候選框與某個已選框的IoU小于設定的閾值,則將候選框加入到已選列表中成為新的已選框。
后處理總結: 所有輸出的邊界框經過置信度閾值過濾和NMS過濾后得到最終確定有效的篩選結果。
反向傳播階段
損失函數: YOLOV1原論文作者提供的損失函數公式為:
L o s s = λ c o o r d ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j [ ( x i ? x i ∧ ) 2 ? ( y i ? y i ∧ ) 2 ] + λ c o o r d ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j [ ( w i ? w i ∧ ) 2 ? ( h i ? h i ∧ ) 2 ] + ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j ( C i ? C i ∧ ) 2 + λ n o o b j ∑ i = 0 S 2 ∑ j = 0 B 1 i j n o o b j ( C i ? C i ∧ ) 2 + ∑ i = 0 S 2 1 i j o b j ∑ c ∈ c l a s s e s ( p i ( c ) ? p i ∧ ( c ) ) 2 L{\rm{oss}} = {\lambda _{{\rm{coord}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } \left[ {{{\left( {{x_i} - \mathop {{x_i}}\limits^ \wedge } \right)}^2} - {{\left( {{y_i} - \mathop {{y_i}}\limits^ \wedge } \right)}^2}} \right] + {\lambda _{{\rm{coord}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } \left[ {{{\left( {\sqrt {{w_i}} - \sqrt {\mathop {{w_i}}\limits^ \wedge } } \right)}^2} - {{\left( {\sqrt {{h_i}} - \sqrt {\mathop {{h_i}}\limits^ \wedge } } \right)}^2}} \right] + \sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } {\left( {{C_i} - \mathop {{C_i}}\limits^ \wedge } \right)^2} + {\lambda _{{\rm{noobj}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{{\rm{noobj}}}} } {\left( {{C_i} - \mathop {{C_i}}\limits^ \wedge } \right)^2} + \sum\limits_{{\rm{i}} = 0}^{{S^2}} {1_{ij}^{obj}\sum\limits_{c \in classes} {{{\left( {{p_i}\left( c \right) - \mathop {{p_i}}\limits^ \wedge \left( c \right)} \right)}^2}} } Loss=λcoord?i=0∑S2?j=0∑B?1ijobj?[(xi??xi?∧?)2?(yi??yi?∧?)2]+λcoord?i=0∑S2?j=0∑B?1ijobj? ?(wi???wi?∧??)2?(hi???hi?∧??)2 ?+i=0∑S2?j=0∑B?1ijobj?(Ci??Ci?∧?)2+λnoobj?i=0∑S2?j=0∑B?1ijnoobj?(Ci??Ci?∧?)2+i=0∑S2?1ijobj?c∈classes∑?(pi?(c)?pi?∧?(c))2
- ∑ i = 0 S 2 \sum\limits_{{\rm{i}} = 0}^{{S^2}} {} i=0∑S2?表示遍歷所有網格單元并進行累加;
- ∑ j = 0 B \sum\limits_{{\rm{j}} = 0}^B {} j=0∑B?表示遍歷所有預測邊界框并進行累加;
- ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j \sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{{\rm{obj}}}} } i=0∑S2?j=0∑B?1ijobj?表示第 i i i個網格中第 j j j個邊界框有對象時為1,否則為0;
- ∑ i = 0 S 2 ∑ j = 0 B 1 i j n o o b j \sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{{\rm{noobj}}}} } i=0∑S2?j=0∑B?1ijnoobj?表示第 i i i個網格中第 j j j個邊界框沒有對象時為1,否則為0;
- ∑ i = 0 S 2 1 i j o b j ∑ c ∈ c l a s s e s \sum\limits_{{\rm{i}} = 0}^{{S^2}} {1_{ij}^{obj}\sum\limits_{c \in classes} {} } i=0∑S2?1ijobj?c∈classes∑?表示第 i i i個網格中有對象時為1,否則為0;
- λ c o o r d {\lambda _{{\rm{coord}}}} λcoord?和 λ n o o b j {\lambda _{{\rm{noobj}}}} λnoobj?是平衡系數(分別是5和0.5),通常情況下,圖片中只有少數幾個目標,而絕大部分區域是沒有目標的,因此加上平衡系數以避免過渡學習到沒有目標的區域。
坐標損失: 包含了兩個損失值,一個是邊界框中心點坐標損失,一個是邊界框大小損失。
λ c o o r d ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j [ ( x i ? x i ∧ ) 2 ? ( y i ? y i ∧ ) 2 ] + λ c o o r d ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j [ ( w i ? w i ∧ ) 2 ? ( h i ? h i ∧ ) 2 ] {\lambda _{{\rm{coord}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } \left[ {{{\left( {{x_i} - \mathop {{x_i}}\limits^ \wedge } \right)}^2} - {{\left( {{y_i} - \mathop {{y_i}}\limits^ \wedge } \right)}^2}} \right] + {\lambda _{{\rm{coord}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } \left[ {{{\left( {\sqrt {{w_i}} - \sqrt {\mathop {{w_i}}\limits^ \wedge } } \right)}^2} - {{\left( {\sqrt {{h_i}} - \sqrt {\mathop {{h_i}}\limits^ \wedge } } \right)}^2}} \right] λcoord?i=0∑S2?j=0∑B?1ijobj?[(xi??xi?∧?)2?(yi??yi?∧?)2]+λcoord?i=0∑S2?j=0∑B?1ijobj? ?(wi???wi?∧??)2?(hi???hi?∧??)2 ?
邊界框中心點坐標損失采用的是平方差,容易理解的常規操作,不再解釋。邊界框大小損失則先對寬 w w w,高 h h h進行開根
號,然后再計算平方差。原因如下圖所示,以寬 w w w為例,寬度相差一致的情況下,不開根號計算標注框和預測框的損失,大目標檢測和小目標檢測沒有任何區別,損失都是一樣的;但在開根計算損失時,小目標檢測的損失是比大目標檢測的損失大,加強了小目標損失的影響,抑制了大目標損失的影響,這種設計更符合實際情況。
舉個例子,滿分10分和滿分100分的倆種評價體系中,9分和8分之間1分的影響,遠比90分和89分的之間1分的影響更為突出,更應該關注8分到9分的提升。
置信度損失: 當有對象時, P r ( O b j e c t ) = 1 Pr (O{\rm{bject}})=1 Pr(Object)=1,因此置信度的標簽值 C i ∧ {\mathop {{C_i}}\limits^ \wedge } Ci?∧?是預測框和標注框之間的交并比 I o U IoU IoU;當沒對象時, P r ( O b j e c t ) = 0 Pr (O{\rm{bject}})=0 Pr(Object)=0,因此標簽值 C i ∧ {\mathop {{C_i}}\limits^ \wedge } Ci?∧?為0。
注意!!!這里并非是有對象時置信度的標簽值 C i ∧ = 1 {\mathop {{C_i}}\limits^ \wedge }=1 Ci?∧?=1。但后續yolo版本對這里作出了調整,改成了 C i ∧ = 1 {\mathop {{C_i}}\limits^ \wedge }=1 Ci?∧?=1。
∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j ( C i ? C i ∧ ) 2 + λ n o o b j ∑ i = 0 S 2 ∑ j = 0 B 1 i j n o o b j ( C i ? C i ∧ ) 2 \sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{obj}} } {\left( {{C_i} - \mathop {{C_i}}\limits^ \wedge } \right)^2} + {\lambda _{{\rm{noobj}}}}\sum\limits_{{\rm{i}} = 0}^{{S^2}} {\sum\limits_{{\rm{j}} = 0}^B {1_{ij}^{{\rm{noobj}}}} } {\left( {{C_i} - \mathop {{C_i}}\limits^ \wedge } \right)^2} i=0∑S2?j=0∑B?1ijobj?(Ci??Ci?∧?)2+λnoobj?i=0∑S2?j=0∑B?1ijnoobj?(Ci??Ci?∧?)2
概率損失: 所有網格單元中,只讓有目標對象的網格單元參與計算。
∑ i = 0 S 2 1 i j o b j ∑ c ∈ c l a s s e s ( p i ( c ) ? p i ∧ ( c ) ) 2 \sum\limits_{{\rm{i}} = 0}^{{S^2}} {1_{ij}^{obj}\sum\limits_{c \in classes} {{{\left( {{p_i}\left( c \right) - \mathop {{p_i}}\limits^ \wedge \left( c \right)} \right)}^2}} } i=0∑S2?1ijobj?c∈classes∑?(pi?(c)?pi?∧?(c))2
總結
盡可能簡單、詳細的介紹了YOLOV1模型的結構,深入講解了YOLOV1核心思想。