繼上一篇YOLOv4建置流程 within Windows10 & VS2019
建置完成Darknet.exe並實際執行了照片辨識以及影片辨識後
這篇繼續往下走流程,來玩玩自定義物件辨識
流程乃參考 yolo v4 的Readme:
https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects
(中間會加上自己過去學習時使用的工具,所以並非全部照著Readme走)
以下的內容是建立一個模型,希望可以準確分析家人中的兩位
先說用途,這樣的目的會很像人臉辨識,也就是都在「人類」這個大項下
希望可以明確區分每個個體差異,進而辨識出不同的目標
但最初級的應用應該是以分辨不同大項為主
例如「人類」、「貓」、「狗」
感覺這樣的成功率應該會比我下面要跑的family模型還輕鬆且正確
不多說,以下先記錄建立的過程:
1.下載預訓練權重 yolov4.conv.137
2.複製D:\YOLOv4\darknet-master\build\darknet\x64\cfg\yolov4-custom.cfg
另存為D:\YOLOv4\darknet-master\build\darknet\x64\cfg\yolov4-family.cfg
這裡我以家人為辨識,只分類其中2人
3.打該yolov4-family.cfg
修改以下7個地方:
3-1.batch改為64
3-2.subdivisions改為16,而我的電腦即使改成16也跑不動,所以可以再向上改為32,或者64
3-3.width和height都改為416,或者32的倍數,而我再把這個數字向下改到192
3-4.max_batchs改為Max((分類項數*2000),6000)
以我的模型為例,我只有兩個Class,所以分類項數=2
所以max_batchs=Max(4000,6000)=6000
官方寫是不要少於6000次的模擬(雖然最後我覺得跑太久,只跑了2000次就給他中斷了...)
3-5.steps輸入兩個數字,分別為max_batchs的80%以及90%
所以我這裡會輸入4800,5400
3-6.按下Ctrl+F搜尋 [yolo] (含中括號)
cfg中共有三個地方需修改
下方會出現classes,將它改成2,因為本次模型只有兩個類別
3-7.其上方的[convolutional]之下,把filterse改成(classes+5)*3=21
整份文件裡有許多[convolutional],而只有[yolo]正上方第一個[convolutional]要調整
所以也僅調整三個filters
4.在D:\YOLOv4\darknet-master\build\darknet\x64\data建立family.names
裡面紀錄classes的名稱(Label)
以我的設定,裡面就留兩個人名,一人一行
輸入符停在第二行尾
5.在D:\YOLOv4\darknet-master\build\darknet\x64\data建立family.data
裡面紀錄classes數量、train檔案路徑檔、valid檔案路徑檔、names檔、backup位置
classes=2 這次只有要分析兩個類別
names裡存了這兩個類別的Label,指向剛剛建立的data/family.names(路徑寫法以相對於darknet.exe的位置來簡寫)
train和valid都是路徑檔,內存稍後要拿來訓練和驗證的圖片路徑,可以先在data下建立兩個空白的txt
分別命名為family_train.txt和family_valid.txt
backup是在訓練過程與訓練結束後會產生的權重檔(*.weights)的路徑,就寫著預設的backup/
完成的family.data如下圖
6.在D:\YOLOv4\darknet-master\build\darknet\x64\data下建立一個資料夾obj
再於obj下建立資料夾family
然後在family下丟入照片
在這裡我放進59張照片
照片名稱從簡,就是編號1~59
副檔名依照Readme說明是要用*.jpg
我沒嘗試其他格式,所以也是照規矩只用*.jpg格式
階段圖如下
選用的照片全是手機拍的,但是從不同手機而來
所以大小不一、畫質不一、品質不一
也都不是正方形
我不知道會不會有影響
總之,就先這樣湊合著用吧~
(7.在D:\YOLOv4\darknet-master\build\darknet\x64\data下建立資料夾valid
再於valid之下建立資料夾family
在裡面丟幾張跟obj/family不同的照片
數量上可以大概1/3的量就好
然後這個步驟我沒有做,導致後面只有train沒有valid
所以這個步驟是先括號起來,未來有機會再做)
8.打開剛剛在D:\YOLOv4\darknet-master\build\darknet\x64\data預先建立的空白文字檔family_train.txt
將剛剛建立的59張照片的路徑都記錄在裡面
(同樣的動作在family_valid.txt做一遍,紀錄放在valid/family下的另外驗證照片路徑)
9.建立標籤位置
這一步驟我沒照Readme的內容
而是採用LabelImg
可以到 https://tzutalin.github.io/labelImg/ 下載
當前版本是Windows_v1.8.0
解壓縮後我放在D:\YOLOv4\LabelImg\windows_v1.8.0下
先打開檔案下的data資料夾,可以看到predefined_classes.txt這個檔案
這是LabelImg在建立Label時所用的依據檔
原始裡面有15個預設標籤
這些我都用不到
所以我將之改名為predefined_classes_origin.txt
然後將原本的predefined_classes.txt的內容改成與D:\YOLOv4\darknet-master\build\darknet\x64\data\family.names一致
這裡必須保持一致,稍後說明
開啟LabelImg.exe
點擊Open Dir,選擇到D:\YOLOv4\darknet-master\build\darknet\x64\data\obj\family
成功後會直接讀取圖像檔
再點擊Change Save Dir,選擇同一路徑D:\YOLOv4\darknet-master\build\darknet\x64\data\obj\family
然後從Menu-->View-->Auto Saving勾起來
然後在PascalVOC上點一下,會變成YOLO,這樣才會符合yolo的定位格式
接下來就要開始定位照片物件的位置了
點擊Create RectBox(快捷鍵是W,需切換至英打,快捷鍵才有效果)
然後在照片上的定位區間拉出一個方框,同時會自動跳出預定義的Label清單
完成後就可以按Next Image切換下一張
而因為有勾選Auto Saving,所以會自動儲存該照片的物件定位檔於Change Saving Dir的路徑之下
我們可以去該路徑下看是否有生成檔案
而檔案內容長這樣
其中0 代表第0個Class,在這裡是指Paggy
後面四個是0的位置
第一、二個數字是定位左上角的點
第一個數字是將照片寬度設為1,左上角的點自左為0起,定位在0.393502的位置
第二個數字是將照片高度設為1,左上角的點自上為0起,定位在0.340663的位置
第三個數字是方框的寬度,第四個數字是方框的高度
如此,就可以定位出方框右下角的位置是(x, y) = (1+3, 2+4)
如果沒有在設定LabelImg的predefined_classes.txt這個步驟將預設的15個Label清除
則Paggy會變成第15號Class,這樣就會跟family.names對不上
自然就如法正確辨識
一張照片可以有多個Label框
產出的txt檔則有兩行
(如果有在valid/family下放照片,也必須對該資料夾下的照片進行標籤定位)
10.從cmd移動到Darknet.exe所在路徑之下,執行
darknet.exe detector train data/family.data cfg/yolov4-family.cfg yolov4.conv.137
只要不要出現CUDA記憶體不足的錯誤,基本就是開始執行模型訓練了
當模型開始訓練後,會跳出一張Loss_batchsTimes圖,會顯示當前的總偏誤跟訓練次數
不知道是不是我把subdivisions設為64的關係,基本沒有享受到批次訓練的優勢
6000次就預計要跑28小時,當然這跟電腦配備太渣絕對有直球關係
A few of thousands years...
經過一個晚上
後來我還是沒給他等下去,大概再過4個小時後跑過2000次,我就把訓練停掉了
這些圖每執行100batchs會自動存在D:\YOLOv4\darknet-master\build\darknet\x64
因為我在這次的訓練中沒有建立valid資料,所以沒有出現第二條線
Avg Loss從一開始的570左右降到0.2453,我也不想再跑了
就對cmd按下Ctrl+C中斷(Ctrl+C在cmd中不是複製,而是中斷的訊號)
可以到family.data中指定的backup路徑下找到weights檔案
每1000次會自動存一次,以及每100次會更新一次last.weights
(2000後面有個_keep是我自己手動改名的結果)
假如之後你想在停止後再繼續訓練,則可以把train指令改成
darknet.exe detector train data/family.data cfg/yolov4-family.cfg backup/yolov4-family_last.weights
將原本的yolov4.conv.137改成backup/yolov4-family_last.weights即可
若是覺得2000或last有overfitting的現象,想從1000重新訓練,就改成backup/yolov4-family_1000.weights即可
11.測試模型結果
輸入test指令
darknet.exe detector test data/family.data cfg/yolov4-family.cfg backup/yolov4-family_2000_keep.weights
跑完後會再要輸入欲預測的圖片路徑
我在D:\YOLOv4\darknet-master\build\darknet\x64\data\test\family有丟了幾張跟train完全不同的照片
(若有valid資料集,則test資料也應該跟valid完全不同)
裡面有家人、朋友、路人、Logo人= =
將路徑輸入後可以得出以下結果
如果test相片中只有目標家人的話,看起來是可以正確辨識
而從cmd的log中來看的話,被框出的最高Label機率分別是
Wingel:99%
Paggy:100%
看起來很不錯
但是如果是照片內有朋友的話
正確的Paggy是99%
錯誤的辨識中
Paggy是61%
Wingel是39%
看得出來,在分析同一大項中
要分辨個體差異,以這樣簡單訓練不足的情況下
仍有很大的挑戰
最後,雖然沒截圖了,但還好Logo人沒有被辨識出來
小小欣慰,然後路人不出意外以92%被辨識為Wingel..
以上就是這次的自定義模型訓練筆記
若有增修就再更新了!!