目標檢測方法對比及yolov3實現

YOLOv3簡介

目錄

一.目標識別的簡介... 1

二.各類方法特點簡介... 3

1.         R-CNN. 3

2.         Fast R-CNN. 4

3.         Faster R-CNN. 5

4.         SSD. 6

5.         YOLO(v1,v2,v3)... 6

三.YOLO算法訓練簡介... 9

三.YOLOV3代碼實現過程... 13

1.         新建文件目錄... 13

2.         把要訓練的圖片都複製到JPEGImages裏面... 14

3.         生成標籤文件xml. 14

4.         生成樣本及圖片定位... 14

5.         修改參數文件yolo3.cfg. 14

6.         yolo3.cfg轉換weight文件... 15

7.         修改model_data下文件文件... 15

8.         修改代碼,準備訓練... 15

9.         預測... 16

 

 

 

 

 

 

 

 

 

 

 

一.目標識別的簡介

圖像分類模型是將圖像劃分爲單個類別,通常對應於圖像中最突出的物體。但是現實世界的很多圖片通常包含不只一個物體,此時如果使用圖像分類模型爲圖像分配一個單一標籤其實是非常粗糙的,並不準確。對於這樣的情況,就需要目標檢測模型,目標檢測模型可以識別一張圖片的多個物體,並可以定位出不同物體(給出邊界框)。目標檢測在很多場景有用,如無人駕駛和安防系統。

目前主流的目標檢測算法主要是基於深度學習模型,其可以分成兩大類:(1)two-stage檢測算法,其將檢測問題劃分爲兩個階段,首先產生候選區域(region proposals),然後對候選區域分類(一般還需要對位置精修),這類算法的典型代表是基於region proposal的R-CNN系算法,如R-CNN,Fast R-CNN,Faster R-CNN等;(2)one-stage檢測算法,其不需要region proposal階段,直接產生物體的類別概率和位置座標值,比較典型的算法如YOLO。目標檢測模型的主要性能指標是檢測準確度和速度,對於準確度,目標檢測要考慮物體的定位準確性,而不單單是分類準確度。一般情況下,two-stage算法在準確度上有優勢,而one-stage算法在速度上有優勢。不過,隨着研究的發展,兩類算法都在兩個方面做改進。如下所示爲各類方法的準確率以及訓練時間的對比圖。

二.各類方法特點簡介

  1. R-CNN

R-CNN(R. Girshick et al., 2014)是基於region proposal方法的目標檢測算法系列開山之作,其先進行區域搜索,然後再對候選區域進行分類。在R-CNN中,選用Selective search方法(J.R.R. Uijlings and al. 2012)來生成候選區域,這是一種啓發式搜索算法。它先通過簡單的區域劃分算法將圖片劃分成很多小區域,然後通過層級分組方法按照一定相似度合併它們,最後的剩下的就是候選區域(region proposals),它們可能包含一個物體。

對於一張圖片,R-CNN基於selective search方法大約生成2000個候選區域,然後每個候選區域被resize成固定大小並送入一個CNN模型中,最後得到一個4096-d的特徵向量。然後這個特徵向量被送入一個多類別SVM分類器中,預測出候選區域中所含物體的屬於每個類的概率值。每個類別訓練一個SVM分類器,從特徵向量中推斷其屬於該類別的概率大小。爲了提升定位準確性,R-CNN最後又訓練了一個邊界框迴歸模型。缺點: 在R-CNN中,每個候選框先resize到統一大小,然後分別作爲CNN的輸入,這樣是很低效的。

  1. Fast R-CNN

在R-CNN選區域都要單獨送入CNN模型計算特徵向量,這是非常費時的,而對於Fast R-CNN,其CNN模型的輸入是整張圖片,然後結合RoIs(Region of Interests)pooling和Selective Search方法從CNN得到的特徵圖中提取各個候選區域的所對應的特徵。對於每個候選區域,使用RoI pooling層來從CNN特徵圖中得到一個固定長和寬的特徵圖,RoI pooling的原理很簡單,其根據候選區域按比例從CNN特徵圖中找到對應的特徵區域,然後將其分割成幾個子區域。即將池化層變成可變的。

RoI Pooling層將每個候選區域分爲m * n個塊。針對每個塊執行最大池操作,使得特徵映射上不同大小的候選區域被變換爲均勻大小的特徵向量。然後送入下一層。舉例來說,某個ROI區域座標爲(x1,y1,x2,y2),那麼輸入尺寸大小爲( y2−y1)∗( x2−x1); 如果合併輸出的大小爲池高乘池寬,即pooledheight∗pooledwidth,則每個網格的大小都是爲

https://img-blog.csdn.net/20180527162409787?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dlbnRlbHlhbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

  1. Faster R-CNN

   加入提取邊緣的神經網絡,將提取候選框的工作交給神經網絡來完成(Region Proposal Network(RPN)),提高了生成Region Proposal的速度。

  1. SSD

在Yolov1每個單元預測多個邊界框,但是其都是相對這個單元本身(正方塊),但是真實目標的形狀是多變的,Yolov1在訓練過程中自適應目標的形狀。而SSD借鑑了Faster R-CNN中anchor的理念,每個單元設置尺度或者長寬比不同的先驗框,預測的邊界框(bounding boxes)是以這些先驗框爲基準的,在一定程度上減少訓練難度。

  1. YOLO(v1,v2,v3)

在介紹Yolo算法之前,首先先介紹一下滑動窗口技術,這對我們理解Yolo算法是有幫助的。採用滑動窗口的目標檢測算法思路非常簡單,它將檢測問題轉化爲了圖像分類問題。其基本原理就是採用不同大小和比例(寬高比)的窗口在整張圖片上以一定的步長進行滑動,然後對這些窗口對應的區域做圖像分類,這樣就可以實現對整張圖片的檢測了。但是這個方法有致命的缺點,就是你並不知道要檢測的目標大小是什麼規模,所以你要設置不同大小和比例的窗口去滑動,而且還要選取合適的步長。但是這樣會產生很多的子區域,並且都要經過分類器去做預測,這需要很大的計算量,所以你的分類器不能太複雜,因爲要保證速度。解決思路之一就是減少要分類的子區域,這就是R-CNN的一個改進策略,其採用了selective search方法來找到最有可能包含目標的子區域(Region Proposal),其實可以看成採用啓發式方法過濾掉很多子區域,這會提升效率。

如果你使用的是CNN分類器,那麼滑動窗口是非常耗時的。但是結合卷積運算的特點,我們可以使用CNN實現更高效的滑動窗口方法。這裏要介紹的是一種全卷積的方法,簡單來說就是網絡中用卷積層代替了全連接層,這樣一次CNN計算就可以實現窗口滑動的所有子區域的分類預測。這其實是overfeat算法的思路。之所可以CNN可以實現這樣的效果是因爲卷積操作的特性,就是圖片的空間位置信息的不變性,儘管卷積過程中圖片大小減少,但是位置對應關係還是保存的。說點題外話,這個思路也被R-CNN借鑑,從而誕生了Fast R-cNN算法。

上面儘管可以減少滑動窗口的計算量,但是隻是針對一個固定大小與步長的窗口,這是遠遠不夠的。Yolo算法很好的解決了這個問題,它不再是窗口滑動了,而是直接將原始圖片分割成互不重合的小方塊,然後通過卷積最後生產這樣大小的特徵圖,基於上面的分析,可以認爲特徵圖的每個元素也是對應原始圖片的一個小方塊,然後用每個元素來可以預測那些中心點在該小方格內的目標,這就是Yolo算法的樸素思想

YOLOv2相比YOLOv1做了很多方面的改進,這也使得YOLOv2的mAP有顯著的提升,並且YOLOv2的速度依然很快,保持着自己作爲one-stage方法的優勢,YOLOv2和Faster R-CNN, SSD等模型的對比如圖

相比YOLOv2,YOLOv3最大的變化包括兩點:使用殘差模型和採用FPN架構。YOLOv3的特徵提取器是一個殘差模型,因爲包含53個卷積層,所以稱爲Darknet-53,從網絡結構上看,相比Darknet-19網絡使用了殘差單元,所以可以構建得更深。另外一個點是採用FPN架構(Feature Pyramid Networks for Object Detection)來實現多尺度檢測。YOLOv3採用了3個尺度的特徵圖,VOC數據集上的YOLOv3網絡結構,YOLOv3每個位置使用3個先驗框,所以使用k-means得到9個先驗框,並將其劃分到3個尺度特徵圖上,尺度更大的特徵圖使用更小的先驗框,和SSD類似。

YOLO優點:1、訓練速度快並且準確率非常高。2、邊界的精確,在各代YOLO逐漸在優化,與其它的差異不大。

缺點:1、尺度較小的目標預測較差

三.YOLO算法訓練簡介

假設我們要在圖片中檢測三種目標:行人、汽車和摩托車,同時使用兩種不同的Anchor box。

訓練集:

輸入X:同樣大小的完整圖片;

目標Y:使用網格劃分,輸出大小,或者對不同格子中的小圖,定義目標輸出向量Y。

我們先看看如何構造你的訓練集,假設你要訓練一個算法去檢測三種對象,行人、汽車和摩托車,你還需要顯式指定完整的背景類別。這裏有 3 個類別標籤,如果你要用兩個 anchor box,那麼輸出 y 就是 3×3×2×8,其中 3×3 表示 3×3 個網格,2 是anchorbox 的數量,8 是 向量維度,8 實際上先是 5(pc, bx , by , bℎ , bw)再加上類別的數量(c1, c2, c3)。你可以將它看成是 3×3×2×8,或者 3×3×16。要構造訓練集,你需要遍歷 9 個格子,然後構成對應的目標 向量y。

所以先看看第一個格子(編號 1),裏面沒什麼有價值的東西,行人、車子和摩托車, 三 個 類 別 都 沒 有 出 現 在 左 上 格 子 中 , 所 以 對 應 那 個 格 子 目 標 y就 是 這樣 的 , y=[0 ? ? ? ? ? ? ?0 ? ? ? ? ? ? ?]T,第一個 anchor box 的 pc 是 0,因爲 沒什麼和第一個 anchor box 有關的,第二個 anchor box 的 pc 也是 0,剩下這些值是 don’t care-s。所以你這樣遍歷 9 個格子,遍歷 3×3 網格的所有位置,你會得到這樣一個向量,得到一個 16 維向量,所以最終輸出尺寸就是 3×3×16。和之前一樣,簡單起見,我在這裏用的是 3×3 網格,實踐中用的可能是 19×19×16,或者需要用到更多的 anchor box,可能是 19×19×5×8, 即 19×19×40,用了 5 個 anchor box。這就是訓練集,然後你訓練一個卷積網絡,輸入是圖 片,可能是 100×100×3,然後你的卷積網絡最後輸出尺寸是,在我們例子中是 3×3×16 或者3×3×2×8。

模型預測:

輸入與訓練集中相同大小的圖片,同時得到每個格子中不同的輸出結果:

接下來我們看看你的算法是怎樣做出預測的,輸入圖像,你的神經網絡的輸出尺寸是這個 3××3×2×8,對於 9 個格子,每個都有對應的向量。對於左上的格子(編號 1),那裏沒有 任何對象,那麼我們希望你的神經網絡在那裏(第一個pc)輸出的是 0,這裏(第二個pc)是 0,然後我們輸出一些值,你的神經網絡不能輸出問號,不能輸出 don’t care-s,剩下的我 輸入一些數字,但這些數字基本上會被忽略,因爲神經網絡告訴你,那裏沒有任何東西,所 以輸出是不是對應一個類別的邊界框無關緊要,所以基本上是一組數字,多多少少都是噪音(輸出 y 如編號 3 所示)。

運行非最大值預測(NMS)

最後你要運行一下這個非極大值抑制,爲了讓內容更有趣一些,我們看看一張新的測試圖像,這就是運行非極大值抑制的過程。如果你使用兩個 anchor box,那麼對於 9 個格子中 任何一個都會有兩個預測的邊界框,其中一個的概率pc很低。但 9 個格子中,每個都有兩個

預測的邊界框,比如說我們得到的邊界框是是這樣的,注意有一些邊界框可以超出所在格子 的高度和寬度(編號 1 所示)。接下來你拋棄概率很低的預測,去掉這些連神經網絡都說,這裏很可能什麼都沒有,所以你需要拋棄這些(編號 2 所示)。

最後,如果你有三個對象檢測類別,你希望檢測行人,汽車和摩托車,那麼你要做的是,對於每個類別單獨運行非極大值抑制,處理預測結果所屬類別的邊界框,用非極大值抑制來 處理行人類別,用非極大值抑制處理車子類別,然後對摩托車類別進行非極大值抑制,運行三次來得到最終的預測結果。所以算法的輸出最好能夠檢測出圖像裏所有的車子,還有所有 的行人(編號 3 所示)。

四.YOLOV3代碼實現過程

  1. 新建文件目錄

https://img-blog.csdn.net/20181017093009220?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3piemNrYWlB/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

logs用於存放訓練後的模型,model_data用於存放標籤類別數據,Segmentationclass用於生成測試生成的圖片,VOC2007用於存放訓練數據,JPEGimages用於存放原始圖片,Annotations 用於存放生成的xml數據ImageSets用於存放生成的訓練文件目錄。

(鏈接:https://pan.baidu.com/s/1EhVeWBiS8YKBD0552g3DLg 提取碼:4zhe)

  1. 把要訓練的圖片都複製到JPEGImages裏面
  2. 生成標籤文件xml

利用網盤下載的文件labelmodel 對照片進行手動打標籤生成xml文件,生成的文件放入Annotations文件中。

  1. 生成樣本及圖片定位
   ①利用create_label_text.py生成訓練測試的圖片標籤並保存在./VOC2007/ImageSets/Main/文件夾下
②修改voc_annotation.py文件,把class中的class 修改爲你需要的分類標籤,classes= ['bee','laby..'],將VOCdevkit/路徑修改爲./(當前目錄)
  1. 修改參數文件yolo3.cfg

修改yolo3.cfg參數,ctrl+f搜 yolo, 總共會搜出3個含有yolo的地方,修改上下文中下面三處地方

每個地方都要改3處,filters:3*(5+len(classes));

②classes: len(classes) = 2,這裏以bee、ladybug三個顏色爲例

③random:原來是1,顯存小改爲0

  1. yolo3.cfg轉換weight文件

利用convert.py 轉化權重文件。權重下載地https://pjreddie.com/media/files/yolov3.weights

python convert.py -w yolov3.cfg yolov3.weights model_data/yolo_weights.h5
  1. 修改model_data下文件文件

將文件中的標籤改爲新的模型標籤,coco,voc這兩個文件都需要修改。

像這樣:

   https://img-blog.csdn.net/20180607210817261?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1BhdHJpY2tfTHhj/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

  1. 修改代碼,準備訓練

代碼以yolo3模型爲目標,tiny_yolo(準確率太低)不考慮。

代碼會加載預先對coco數據集已經訓練完成的yolo3權重文件,

https://img-blog.csdn.net/20180607211237833?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1BhdHJpY2tfTHhj/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70凍結了開始到最後倒數第N層(源代碼爲N=-2)

https://img-blog.csdn.net/20180607211432467?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1BhdHJpY2tfTHhj/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

③代碼中有兩處修改batch_size的地方,第一個地方選擇16第二個地方選擇8(電腦配置內存8g\cpu)第一處爲只開放了最後兩層進行訓練,後面那個是在這個的基礎上放開所有隱層,只保留權重重新訓練。

  1. 預測

將檢測的圖片完成的都儲存在outdir裏,運行yolo_img.py腳本。注:預測的時候要用cmd命令行運行,因爲argparse如果不適用默認參數配置,不能jupyter中執行,報錯爲unrecognized arguments process finished with exit code 2

結果展示:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章