Python影像辨識筆記(九):分別在Windows和Ubuntu 18.04上安裝並執行YOLOv3(使用GPU)

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Python影像辨識筆記(九):分別在Windows和Ubuntu 18.04上安裝並執行YOLOv3(使用GPU)Python影像辨識筆記(九之二):關於YOLOv3的一些心得Python影像辨識筆記(九之三):YOLOv3結合深度學習的Object DetectorPython影像辨識筆記(九之四):可視化YOLOv3訓練過程中的loss、IOU、avg Recall等的曲線圖Python影像辨識筆記(九之五):透過Google Colab在雲端運行YOLOv3Python影像辨識筆記(九之六):將LabelImg標記的xml檔案轉成txt檔案NVIDIA Jetson TX2學習筆記(三):執行YOLOv3The Complete YOLOv3 Reproduce List on GitHubUsing YOLOv3 Model in Python with ImageAI Library

#20200405更新一篇在Python上透過OpenCV執行YOLOv3的文章(限定使用CPU)

#20200202更新一篇在Ubuntu編譯YOLOv3的教學,寫的相當精簡卻剛剛好

#20190904更新在Github上找到使用 Tensor Cores的YOLOv3,該Repo作者還開發了一個標記工具

YOLOv3官方網站

Windows

還沒測試成功:

Side Project

Windows系統上CPU版本的安裝與使用

1.下載 Visual C++ 2015 build tools 並且安裝
2.git clone https://github.com/pjreddie/darknet
3.安裝MinGW(記住安裝路徑,後續會進入進行Makefile的編譯)
4.修改darknet-master文件①將Makefile文件中的EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o darknet.o修改為(其實就是刪除go.o)EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o darknet.o②将examples/darknet.c中的extern void run_go(int argc, char **argv);和
else if (0 == strcmp(argv[1], "go")){ run_go(argc, argv); }
修改為(其實就是做了註解)/*extern void run_go(int argc, char **argv);*/和else if (0 == strcmp(argv[1], "go")){ /*run_go(argc, argv);*/ }③在include/darknet.h中新增檔頭文件#include <time.h>④打開MinGW - W64安裝目錄中中的mingw-w64.bat並且切换到darknet-master資料夾下,輸入mingw32-make,開始編譯,編譯完成後就可以關掉CMD5.下載Pre-trained weights,並將其移動到darknet目錄下
https://pjreddie.com/media/files/yolov3.weights
6.針對照片進行偵測
darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

訓練模型

#建立annotation和images資料夾
#annotation放labelimg標記的xml檔案;images放圖片
#darknet訓練需要*.xml格式的annotation檔案
#images資料夾中圖片數量必須和xml數量一致
先使用labelimg標記資料(*.xml或*.txt格式)
#如果存成了(*.xml格式),必須透過script轉檔成(*.txt的格式),才能訓練
#訓練YOLO需要(*.txt)格式,(*.txt格式)中以下列形式排列
<object-class> <x> <y> <width> <height>
#標記完的.txt檔案要注意裡面的object-class為0才對(假設只有1個class的話)
labelimg標記流程:(1)下載圖片
使用Python批次下載Google圖片
(2)開啟labelimg
選擇Open Dir,開啟圖片資料夾
選擇Change Save Dir,設定.txt檔案存檔的位置
使用快捷鍵進行標記:
W(產生框框,進行標記)
Ctrl+S(存檔)
D(下一張)
#如果無法使用快捷鍵,檢查是否切換到英文鍵盤(而不是注音)
#
無法開啟labelimg或者閃退嗎?
刪除C:\Users\yourUserName\當中的.labelImgSettings.pkl檔案,再重新開labelimg.exe
(3)完成後將原始圖檔和TXT文件重新命名
使用Ant Renamer批量命名,檔名不能有空白或中文或特殊符號,可以用「File001.jpg、File001.txt」來命名。
(4)產生train.txt
快速在Windows中建立目錄中的所有檔案清單
透過上面連結中的方法來產生路徑檔案(list.txt),用Editor存成路徑檔案(train.txt)(不可用記事本存,在Linux上會有錯誤)(參考darknet yolov3 訓練時出現 Cannot load image 亂碼問題)
(5)將檔案傳輸至TX2上
這邊推薦使用Filezilla來進行檔案傳輸,方便目錄檔案管理
--------------------------------------------------------------------#需要修改cfg/yolo3.cfg和label.txt
cfg/yolo3.cfg:
yolov3的filters計算方式:
filters=(classes+5)*3
EX:只有2個label
filters=3*(2+5)=21,直接填寫21
classes=2,直接填寫2
label.txt:
寫出在labelimg所標記的名稱即可
EX:只有2個label
分別在第一行和第二行寫英文單字即可:
cat
dog
--------------------------------------------------------------
其餘內容與TX2上的訓練一樣,請參考NVIDIA Jetson TX2學習筆記(三):執行YOLOv3

Windows系統上GPU版本的安裝與使用

1.安裝CUDA及CUDNN參考此文2.安裝Microsoft Visual Studio 2019(進行後續編譯)下載連結3.下載opencv3.4.0下載完後打開檔案,記住檔案路徑就可以了(我的路徑是E:\opencv)4.下載darknet源碼並解壓縮https://github.com/AlexeyAB/darknet放到你想要放的位置上(我的是I:\darknet(GPU)\darknet)5.編輯文件打開build文件夾下的darknet文件夾,並用編輯器打開darknet.vcxproj,用搜索功能查找CUDA (這裡就是CUDA的版本號了),並修改為自己CUDA的版本號,我的CUDA版本是10.1,所以修改為CUDA 10.1  ###(一共有兩處需要修改的)並保存
###將文件中的CUDA 9.0.props和CUDA 9.0.targets改成將CUDA 10.1.props和CUDA 10.1.targets
6.確認C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations資料夾下面是否有以下這幾個文件(因為我的是CUDA10.1,所以文件名中帶有10.1,也就是說自己CUDA的版本號)--CUDA 10.1.props
--CUDA 10.1.targets
--CUDA 10.1.xml
6.打開build資料夾下的darknet資料夾,並用vs2015打開darknet.sln7.打開成功後,將OpenCV路徑加入至Visual Studio中
參考此文
8.進入Visual Studio的Project中進行編譯
將編譯設定改成Release和x64
建置->建置方案(Ctrl+Shift+B)
9.回到darknet的資料夾
剛才編譯的darknet會出現在darknet\build\darknet\x64當中
10.進行測試
下載yolov3.weights到darknet\build\darknet\x64中
打開CMD輸入指令進行測試:
darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
11.詳細指令可參照NVIDIA Jetson TX2學習筆記(三):執行YOLOv3

!!!20190924更新:以下為darkflow的使用指令,目前已改用darknet,故將不再使用!!!

#1)訓練
python flow --model cfg/yolo3.cfg --load bin/yolov3.weights --train --annotation train/annotations --dataset train/images
#2)上個點繼續train
python flow --model cfg/yolo3.cfg --load -1 --train --annotation train/annotations --dataset train/images
ps:遇到當機參考訓練時遇到的問題(3)進行處理:電腦當機出現藍畫面,顯示實體記憶體不足#3)使用訓練好的模型進行預測(方法1)用cfg進行預測
python flow --model cfg/yolo3.cfg --load bin/yolov3.weights --imgdir sample_img/test/
(方法2)用pb進行預測在darkflow資料夾中有一個ckpt資料夾,裡面有checkpoint和.meta和.profile檔。先產生.pb檔,再進行預測

python flow --model cfg/yolo3.cfg --load bin/yolov3.weights --savepb

python flow --pbLoad built_graph/yolo3.pb --metaLoad built_graph/yolo3.meta --imgdir sample_img/test/
(方法3)改變threshold值來提高或降低"model的敏感度",threshold值越小,model越敏感python flow --model cfg/yolo3.cfg --load bin/yolov3.weights --imgdir sample_img/test/ --threshold 0.25--------------------------------------------------------------------訓練時遇到的問題(1):YOLO運行darkflow時, 出現AssertionError: expect 203929404 bytes, found 203934260https://github.com/thtrieu/darkflow/issues/900AssertionError: expect 44948596 bytes, found 44948600修改darkflow/darkflow/utils/中的loader.py
self.offset = old_offset_value + (found_value - expected_value)
old_offset_value是16(可以嘗試改成20)
found_value是上面的44948600
expected_value是上面的44948596
所以self.offset要改成16+(44948600-44948596)=20
如果還發生第二次錯誤就以此類推繼續把數值加上去,直到可以訓練為止--------------------------------------------------------------------
訓練時遇到的問題(2):
Not detects my dataset and ZeroDivisionError: division by zero #879
Training our own data #439
修改darkflow/utils/pascal_voc_clean_xml.py.
第22行改成以下程式:
原本:annotations = glob.glob(str(annotations)+'*.xml')
修改後:annotations = glob.glob('*.xml')
--------------------------------------------------------------------
訓練時遇到的問題(3):
電腦當機出現藍畫面,顯示實體記憶體不足修改darkflow/defaults.py中的參數,將以下參數調到1就好self.define('batch', 1, 'batch size')
self.define('epoch', 1, 'number of epoch')
defaults.py中還有很多參數可以調整,可以依照需求調整#20190826-20:24更新
yolo3.cfg檔案中,將width和height都調整成416
defaults.py中的batch可以提高到8、epoch=4調整cfg/yolo.cfg中的參數:
random調整成0、subdivision調大一點(2、4、8、16、32...)
--------------------------------------------------------------------
訓練時遇到的問題(4):
用訓練好的model做預測時,沒有bounding boxSolution:讓loss快速下降剛開始訓練時,learning rate 0.01、batch 5
loss降到10時,batch調到10、learning rate調到0.0001
loss到4.5左右時,batch調到40、learning rate下降到0.00008
降低defaults.py的threshold至0.0001,讓model的偵測敏感度上升python flow --model cfg/yolo3.cfg --load bin/yolov3.weights --imgdir sample_img/test/ --threshold 0.25loss必須到 ~0.1 或 ~0.01才有可能看到辨識的框框訓練時遇到的問題(5)該怎麼看訓練的log?
每個batch都會有這樣一個輸出:
2706: 1.350835, 1.386559 avg, 0.001000 rate, 3.323842 seconds, 173184 images2706:batch是第幾組。1.350835:總損失1.386559 avg : 平均損失0.001000 rate:目前的學習率3.323842 seconds: 當前batch訓練所花的時間173184 images : 目前為止參與訓練的圖片總數 = 2706 * 64Region 82 Avg IOU: 0.798032, Class: 0.559781, Obj: 0.515851, No Obj: 0.006533, .5R: 1.000000, .75R: 1.000000, count: 2Region Avg IOU:表示在當前subdivision內的圖片的平均IOU,代表預測的矩形框和真實目標的交集與並集之比.Class:標註物體分類的正確率,期望該值趨近於1。Obj: 越接近1越好。No Obj: 期望該值越來越小,但不為零。

count: count後的值是所有的當前subdivision圖片(本例中一共4張)中包含正樣本的圖片的數量。

目前使用的參數

!!!20190924更新:以上為darkflow的使用指令,目前已改用darknet,故將不再使用!!!

Ubuntu

用GPU進行運算請參考下方連結

1.內建辨識影片擷取功能,只要在指令最後方加上這個參數即可
"
-out_filename detect-result.mp4"
2.辨識影片時會出現辨識率:除了標記框外,還會出現偵測數字
3.效能比起原版更好,在TX2上同樣cfg設定下,FPS提升 1 FPS
4.編譯前請先參考下方文章安裝OpenCV

如何用自己的數據訓練YOLOv3

用CPU進行運算請參考下方

darknet安裝

git clone https://github.com/pjreddie/darknet     下載代碼
cd darknet 進入darknet目錄
make 編譯

下載權重,存在darknet的目錄下

wget https://pjreddie.com/media/files/yolov3.weights

在darknet目錄進行辨識

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

訓練模型

1.先使用labelimg標記資料(*.xml或*.txt格式)
#如果存成了(*.xml格式),必須透過script轉檔成(*.txt的格式),才能訓練
#訓練YOLO需要(*.txt)格式,(*.txt格式)中以下列形式排列
<object-class> <x> <y> <width> <height>
1.1透過split_data.py將標記完的資料拆成訓練集90%測試集10%
2.調整Cfg檔案
(1)開啟
cfg/voc.data,裡面有5行
#classes是訓練的標記數量,如果只有1個就寫1
classes= 20
#train.txt裡面包含了想要拿來「訓練」Model的圖片絕對路徑位置(檔名、路徑位置必須確認是完全正確的,否則會出現無法讀取的問題)
train = <path-to-voc>/train.txt
#test.txt裡面包含了想要拿來「驗證」Model的圖片絕對路徑位置(檔名、路徑位置必須確認是完全正確的,否則會出現無法讀取的問題)
valid = <path-to-voc>test.txt
#voc.names裡面有label的名稱,如果只有一種,就在第一行寫上名稱即可(不可以有多的空白、空行,否則會出現錯誤)
names = data/voc.names
backup = backup
(2)修改cfg/yolov3-voc.cfg檔案
batch=1
subdivisions=1
第605行filters=18(filters改成18)
第689行filters=18(filters改成18)
第773行的filters=18(filters改成18)
第611行的classes=1(classes改成1)
第695行的classes=1(classes改成1)
第779行的classes=1(classes改成1)
yolov3的filters計算方式:
filters=(classes+5)*3
#(1+5)*3=18
3.下載Pretrained Convolutional Weights,並且放在darknet目錄中wget https://pjreddie.com/media/files/darknet53.conv.744.訓練模型#首次訓練
$ ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
#上個點繼續train
$ ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc.backup
5.使用訓練好的模型進行預測(須將cfg裡面的batch、subvision修改為1)
$ ./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_30000.weights data/bird.jpg

遇到的問題

訓練時遇到的問題(1):
darknet: ./src/parser.c:315: parse_yolo: Assertion `l.outputs == params.inputs’ failed
本次訓練是由yolo2升級至yolo3,而yolo2和yolo3的參數filters參數的計算方式不同,v2的filters:5*(classes+5),而v3:3*(classes+5),通過修改以上參數後可以正常訓練 。簡單來說v2就是(classes+5)*5;v3則是(classes+5)*3

Written by

Machine Learning / Deep Learning / Python / Flutter cakeresume.com/yanwei-liu

Get the Medium app