YOLOv3: 训练自己的数据(绝对经典版本1)
為什么80%的碼農都做不了架構師?>>> ??
windows版本:請參考:https://github.com/AlexeyAB/darknet
linux ? ? ? 版本:請參考本文與?https://pjreddie.com/darknet/yolo
第一部分:論文與代碼
第二部分:如何訓練自己的數據
第三部分:疑惑解釋
第四部分:測試相關
第一部分:論文與代碼
論? 文: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】
環境:centos6.5 ? ?
顯卡:1080Ti ? ??
時間:很快,具體時間記不清了 ? ?
迭代:900?
優點:小目標檢測
速度:稍微慢于v2
測試:記得更改cfg文件
目的:給網友提供參考,所以樣本和迭代次數較少,僅供學習!
(2)為了方便大家學習,這里提供了182張訓練數據、標注以及對應的配置文件,數據是4類【人,車頭,車尾,車側身】:?
訓練數據、配置文件、模型、訓練日志、標注工具放在QQ群:371315462,請看完本文再加群!!!具體下載地址在群文件的YOLOv3.txt!
友情提醒:如果加群之后,還在提問本博文中已經列舉出來的問題,將會被清理出去!
?
【群文件補充了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有百度云盤的下載地址】
配置文件中的相關參數:完整版本見群文件。
H.如果訓練還有問題或其他疑問,請參考第三部分或者網絡搜索。
I.如何測試以及測試中的問題,請參考第四部分或者網絡搜索。
?
訓練指令;多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的情況,這個是正常的。
?
第四部分:測試問題
由于比較忙,評論不會及時回復。請大家仔細參考下方問題、評論區或者加群討論。
ps1.好多評論都是重復的,可能喜歡不看文章或他人評論,就留言了。針對重復的問題,不再回復,抱歉!
ps2.關于優化以及工程化的問題,這些都是需要你自己去弄,我沒時間和精力幫你解決,抱歉!
ps3.大家要善用網絡搜索,不會的先搜索,找不到答案再提問!
?
(0)部分童鞋在使用CPU前向時出現段錯誤(核心已轉儲)問題
代碼本身的問題,暫時還沒時間去定位這個問題,先盡量用GPU做前向。
(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.自己改成對應的圖片名稱即可。
?
第五部分:論文閱讀
優點:速度快,精度提升,小目標檢測有改善;
不足:中大目標有一定程度的削弱,遮擋漏檢,速度稍慢于V2。
v2: anchors[k-means]+多尺度+跨尺度特征融合
v3: anchors[k-means]+多尺度+跨尺度特征融合
v2,v3兩者都是有上面的共同特點,簡單的多尺度不是提升小目標的檢測的關鍵。
v2: 32x的下采樣,然后使用anchor進行回歸預測box
問題:較大的下采樣因子,通常可以帶來較大的感受野,這對于分類任務是有利,但會損害目標檢測和定位【小目標在下采樣過程中消失,大目標邊界定位不準】
v3: 針對這個問題,進行了調整。就是在網絡的3個不同的尺度進行了box的預測。【說白了就是FPN的思想】在下采樣的前期就進行目標的預測,這樣就可以改善小目標檢測和定位問題。
不理解的話,稍微看一下FPN,就明白了。這個才是v3提升小目標的關鍵所在。
--------------------- 本文來自 馬衛飛 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/maweifei/article/details/81137563?utm_source=copy
轉載于:https://my.oschina.net/farces/blog/2209444
總結
以上是生活随笔為你收集整理的YOLOv3: 训练自己的数据(绝对经典版本1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务架构详谈
- 下一篇: 可能是全网把 ZooKeeper 概念讲