目標檢測:YOLOv3: 訓練自己的數據

update:20200424

YOLOV4出來啦!!!快去把玩一下!!!

https://github.com/AlexeyAB/darknet

 

------------------------------ 本文僅供學習交流,如有錯誤,望交流指教 ------------------------------

windows       版本:請參考:https://github.com/AlexeyAB/darknet

linux               版本:請參考本文與 https://pjreddie.com/darknet/yolo

caffe-yolov3 版本:請參考:https://blog.csdn.net/Chen_yingpeng/article/details/80692018【測試可用】

第一部分:論文與代碼

第二部分:如何訓練自己的數據

第三部分:疑惑解釋

第四部分:測試相關

第一部分:論文與代碼

論  文:https://pjreddie.com/media/files/papers/YOLOv3.pdf

翻  譯:https://zhuanlan.zhihu.com/p/34945787

代  碼:https://github.com/pjreddie/darknet

官  網:https://pjreddie.com/darknet/yolo

舊  版:

 https://pjreddie.com/darknet/yolov2/

 https://pjreddie.com/darknet/yolov1/

 

第二部分:如何訓練自己的數據

 

說明:

(1)平臺 linux + 作者官方代碼 【訓練指令請參考官網教程:https://pjreddie.com/darknet/yolo】
迭代:900 次
速度:稍微慢於v2
測試:記得更改cfg文件

目的:給網友提供參考,所以樣本和迭代次數較少,僅供學習!

(2)爲了方便大家學習,這裏提供了182張訓練數據、標註以及對應的配置文件,數據是4類【人,車頭,車尾,車側身】: 

訓練數據、配置文件、模型、訓練日誌、標註工具放在QQ羣:371315462935621769

具體下載地址在羣文件的YOLOv3.txt!

羣基本滿了,進羣也是潛水,所以直接下載吧:

    百度雲:
    鏈接:https://pan.baidu.com/s/1wEtpdQBuMtXn_9CGhEvHTQ
    密碼:bwpx

    CSDN

      https://download.csdn.net/download/lilai619/11130832

【羣文件補充了training_list.txt以及labels文件】,歡迎目標檢測與語義分割的小夥伴進羣交流。

訓練自己的數據主要分以下幾步:

(0)數據集製作:

A.製作VOC格式的xml文件

工具:LabelImg 【羣文件提供了exe免安裝版本以及使用說明】

B.將VOC格式的xml文件轉換成YOLO格式的txt文件

腳本:voc_label.py,根據自己的數據集修改就行了。

(1)文件修改

(A)關於 .data .names 兩個文件修改非常簡單,參考官網或者羣文件YOLOv3.txt連接中的文件。

(B)關於cfg修改,以6目標檢測爲例,主要有以下幾處調整(藍色標出),也可參考我上傳的文件,裏面對應的是4類。#表示註釋,根據訓練和測試,自行修改。

[net]
# Testing
# batch=1
# subdivisions=1
# Training
 batch=64

 subdivisions=8

......

[convolutional]
size=1
stride=1
pad=1
filters=33###75

 

activation=linear

[yolo]
mask = 6,7,8
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=6###20
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0###1

 

......

[convolutional]
size=1
stride=1
pad=1
filters=33###75
activation=linear

[yolo]
mask = 3,4,5
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=6###20
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0###1

......

[convolutional]
size=1
stride=1
pad=1
filters=33###75
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=6###20
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0###1

A.filters數目是怎麼計算的:3x(classes數目+5),和聚類數目分佈有關論文中有說明;

B.如果想修改默認anchors數值,使用k-means即可;

C.如果顯存很小,將random設置爲0,即關閉多尺度訓練;

D.其他參數如何調整,有空再補;

E.前100次迭代loss較大,後面會很快收斂;

Region xx: cfg文件中yolo-layer的索引;

Avg IOU:   當前迭代中,預測的box與標註的box的平均交併比,越大越好,期望數值爲1;

Class:        標註物體的分類準確率,越大越好,期望數值爲1;

obj:            越大越好,期望數值爲1;

No obj:      越小越好;

.5R:            以IOU=0.5爲閾值時候的recall; recall = 檢出的正樣本/實際的正樣本

0.75R:         以IOU=0.75爲閾值時候的recall;

count:        正樣本數目。

F.模型測試:

6類測試效果模型與配置文件稍後放到羣文件,但數據暫不提供】

          

4類的測試效果,182張迭代900次時的檢測效果。【羣文件的YOLOv3.txt有百度雲盤的下載地址】

配置文件中的相關參數:完整版本見羣文件。

 

訓練指令;多GPU訓練指令;恢復訓練指令

 

第三部分:訓練問題詳解

圖片來自羣文件,侵權聯繫刪除

Tips0: 數據集問題

如果是學習如何訓練,建議不要用VOC或者COCO,這兩個數據集複雜,類別較多,復現作者的效果需要一定的功力,迭代差不多5w次,就可以看到初步的效果。所以,不如挑個簡單數據集的或者手動標註個幾百張就可以進行訓練學習。

Tips1: CUDA: out of memory 以及 resizing 問題

顯存不夠,調小batch,關閉多尺度訓練:random = 0。

Tips2: 在迭代前期,loss很大,正常嗎?

經過幾個數據集的測試,前期loss偏大是正常的,後面就很快收斂了。

Tips3: YOLOV3中的mask作用?

參考#558 #567

Every layer has to know about all of the anchor boxes but is only predicting some subset of them. This could probably be named something better but the mask tells the layer which of the bounding boxes it is responsible for predicting. The first yolo layer predicts 6,7,8 because those are the largest boxes and it's at the coarsest scale. The 2nd yolo layer predicts some smallers ones, etc.

The layer assumes if it isn't passed a mask that it is responsible for all the bounding boxes, hence the ifstatement thing.

Tips3: YOLOV3中的num作用?

#參考567

num is 9 but each yolo layer is only actually looking at 3 (that's what the mask thing does). so it's (20+1+4)*3 = 75. If you use a different number of anchors you have to figure out which layer you want to predict which anchors and the number of filters will depend on that distribution.

according to paper, each yolo (detection) layer get 3 anchors with associated with its size, mask is selected anchor indices.

Tips4: YOLOV3訓練出現nan的問題?

參考#566

You must be training on a lot of small objects! nan's appear when there are no objects in a batch of images since i definitely divide by zero. For example, Avg IOU is the sum of IOUs for all objects at that level / # of objects, if that is zero you get nan. I could probably change this so it just does a check for zero 1st, just wasn't a priority.

所以在顯存允許的情況下,可適當增加batch大小,可以一定程度上減少NAN的出現。

Tips5: Anchor box作用是?

參考#568

Here's a quick explanation based on what I understand (which might be wrong but hopefully gets the gist of it). After doing some clustering studies on ground truth labels, it turns out that most bounding boxes have certain height-width ratios. So instead of directly predicting a bounding box, YOLOv2 (and v3) predict off-sets from a predetermined set of boxes with particular height-width ratios - those predetermined set of boxes are the anchor boxes.

 

Anchors are initial sizes (width, height) some of which (the closest to the object size) will be resized to the object size - using some outputs from the neural network (final feature map):

darknet/src/yolo_layer.c

Lines 88 to 89 in 6f6e475

  b.w = exp(x[index + 2*stride]) * biases[2*n] / w;
  b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;

 

  • x[...] - outputs of the neural network

  • biases[...] - anchors

  • b.w and b.h result width and height of bounded box that will be showed on the result image

Thus, the network should not predict the final size of the object, but should only adjust the size of the nearest anchor to the size of the object.

In Yolo v3 anchors (width, height) - are sizes of objects on the image that resized to the network size (width= and height= in the cfg-file).

In Yolo v2 anchors (width, height) - are sizes of objects relative to the final feature map (32 times smaller than in Yolo v3 for default cfg-files).

 

Tips6: YOLOv2和YOLOv3中anchor box爲什麼相差很多?

參考#562 #555

 

Now anchors depends on size of the network-input rather than size of the network-output (final-feature-map): #555 (comment)
So values of the anchors 32 times more.

Now filters=(classes+1+coords)*anchors_num where anchors_num is a number of masks for this layer.
If mask is absence then anchors_num = num for this layer:

darknet/src/yolo_layer.c

Lines 31 to 37 in e4acba6

  if(mask) l.mask = mask;
  else{
  l.mask = calloc(n, sizeof(int));
  for(i = 0; i < n; ++i){
  l.mask[i] = i;
  }
  }

 

Each [yolo] layer uses only those anchors whose indices are specified in the mask=

 

 

So YOLOv2 I made some design choice errors, I made the anchor box size be relative to the feature size in the last layer. Since the network was downsampling by 32 this means it was relative to 32 pixels so an anchor of 9x9 was actually 288px x 288px.

In YOLOv3 anchor sizes are actual pixel values. this simplifies a lot of stuff and was only a little bit harder to implement

 

Tips7: YOLOv3打印的參數都是什麼含義?

 

詳見yolo_layer.c文件的forward_yolo_layer函數。

    printf("Region %d Avg IOU: %f, Class: %f, Obj: %f, No Obj: %f, .5R: %f, .75R: %f,  count: %d\n", net.index, avg_iou/count, avg_cat/class_count, avg_obj/count, avg_anyobj/(l.w*l.h*l.n*l.batch), recall/count, recall75/count, count);

剛開始迭代,由於沒有預測出相應的目標,所以查全率較低【.5R 0.75R】,會出現大面積爲0的情況,這個是正常的。

 

第四部分:測試問題

由於比較忙,評論不會及時回覆。請大家參考下方問題、評論區或者加羣討論。

(1)** Error in `./darknet': free(): invalid next size (fast): 0x000055d39b90cbb0 ***已放棄 (核心已轉儲) 

請使用以下測試指令!

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

訓練與測試指令,請參考官網連接:https://pjreddie.com/darknet/yolo/

(2)如何進行模型的評估(valid)?

評估指令,請參考官網連接:https://pjreddie.com/darknet/yolo/

(3)bounding box正確,標籤錯亂,這裏提供兩種方案供選擇。

A.不改源碼,不用重新編譯

   修改coco.names中內容,爲自己的檢測目標類別

B.改源碼,需要重新編譯[ 先 make clean ,然後再 make]

原因是作者在代碼中設置了默認,所以修改 examples/darknet.c文件,將箭頭指示的文件替換成自己的。然後重新編譯即可。

(4)模型保存問題

A:保存模型出錯?

一般是 .data 文件中指定的文件夾無法創建,導致模型保存時出錯。自己手動創建即可。

B:模型什麼時候保存?如何更改

迭代次數小於1000時,每100次保存一次,大於1000時,沒10000次保存一次。

自己可以根據需求進行更改,然後重新編譯即可[ 先 make clean ,然後再 make]

代碼位置: examples/detector.c line 138

C:使用預訓練模型直接保存問題

darknet53.conv.74作爲預訓練權重文件,因爲只包含卷積層,所以可以從頭開始訓練。

xxx.weights作爲預權重文件訓練,因爲包含所有層,相當於恢復快照訓練,會從已經保存的迭代次數往下訓練。如果cfg中迭代次數沒改,所以不會繼續訓練,直接保存結束。

(5)中文標籤問題

這個解決方案較多,我就簡單的說一下我的方案【羣文件labels提供了參考代碼】

A:首先生成對應的中文標籤,

修改代碼中的字體,將其替換成指中文字體,如果提示提示缺少**模塊,安裝就行了。

 

B:添加自己的讀取標籤和畫框函數

(6)圖片上添加置信值

代碼比較熟悉的童鞋,使用opencv在畫框的函數裏面添加一下就行了。

(7)圖片保存名稱

測試的時候,保存的默認名稱是predictions.自己改成對應的圖片名稱即可。

(8)Floating, point, exception (core, dumped)

https://github.com/pjreddie/darknet/issues/140#issuecomment-375791093

(9)多GPU訓練時模型保存問題

https://github.com/pjreddie/darknet/issues/664#issuecomment-405448653

假設你有3塊GPU,當單張GPU運行100次時【該保存模型了】,實際上迭代了100*3=300次【3塊卡嘛】,當單張GPU運行200次時【該保存模型了】,實際上迭代了200*3=600次【3塊卡嘛】,依次類推。

第五部分:論文閱讀

優點:速度快,精度提升,小目標檢測有改善;

不足:中大目標有一定程度的削弱,遮擋漏檢,速度稍慢於V2。

 

 

v2: anchors[k-means]+多尺度+跨尺度特徵融合
v3: anchors[k-means]+多尺度+跨尺度特徵融合


v2,v3兩者都是有上面的共同特點,簡單的多尺度不是提升小目標的檢測的關鍵。


v2: 32x的下采樣,然後使用anchor進行迴歸預測box
問題:較大的下采樣因子,通常可以帶來較大的感受野,這對於分類任務是有利,但會損害目標檢測和定位【小目標在下采樣過程中消失,大目標邊界定位不準】


v3: 針對這個問題,進行了調整。就是在網絡的3個不同的尺度進行了box的預測。【說白了就是FPN的思想】在下采樣的前期就進行目標的預測,這樣就可以改善小目標檢測和定位問題。
不理解的話,稍微看一下FPN,就明白了。這個纔是v3提升小目標的關鍵所在。

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