繼上一篇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\darknetd\cfg\yolov4-custom.cfg

另存為D:\YOLOv4\darknet-master\build\darknetd\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\darknetd\data建立family.names

裡面紀錄classes的名稱(Label)

以我的設定,裡面就留兩個人名,一人一行

輸入符停在第二行尾

5.在D:\YOLOv4\darknet-master\build\darknetd\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\darknetd\data下建立一個資料夾obj

再於obj下建立資料夾family

然後在family下丟入照片

在這裡我放進59張照片

照片名稱從簡,就是編號1~59

副檔名依照Readme說明是要用*.jpg

我沒嘗試其他格式,所以也是照規矩只用*.jpg格式

階段圖如下

選用的照片全是手機拍的,但是從不同手機而來

所以大小不一、畫質不一、品質不一

也都不是正方形

我不知道會不會有影響

總之,就先這樣湊合著用吧~

 

(7.在D:\YOLOv4\darknet-master\build\darknetd\data下建立資料夾valid

再於valid之下建立資料夾family

在裡面丟幾張跟obj/family不同的照片

數量上可以大概1/3的量就好

然後這個步驟我沒有做,導致後面只有train沒有valid

所以這個步驟是先括號起來,未來有機會再做)

 

8.打開剛剛在D:\YOLOv4\darknet-master\build\darknetd\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\darknetd\data\family.names一致

這裡必須保持一致,稍後說明

開啟LabelImg.exe

點擊Open Dir,選擇到D:\YOLOv4\darknet-master\build\darknetd\data\obj\family

成功後會直接讀取圖像檔

再點擊Change Save Dir,選擇同一路徑D:\YOLOv4\darknet-master\build\darknetd\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\darknetd

因為我在這次的訓練中沒有建立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\darknetd\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..

 

以上就是這次的自定義模型訓練筆記

若有增修就再更新了!!

 

文章標籤
全站熱搜
創作者介紹
創作者 wings890109 的頭像
wings890109

幽嵐飋翼

wings890109 發表在 痞客邦 留言(5) 人氣(18,939)