YunYang1994/tensorflow-yolov3 训练自己的数据集
文章目錄
- 前言
- 訓(xùn)練流程
- 1、準備好`圖片`和`train.txt`、`test.txt`
- 2、修改相關(guān)路徑
- i) 修改`class.names`文件以及`__C.YOLO.CLASSES`參數(shù)路徑
- ii) 修改`__C.TRAIN.ANNOT_PATH`和`__C.TEST.ANNOT_PATH`參數(shù)路徑
- iii) `__C.YOLO.ORIGINAL_WEIGHT`和`__C.YOLO.DEMO_WEIGHT`
- iv) 清理舊的權(quán)重文件
- 3、開始訓(xùn)練
- 4、測試權(quán)重文件
- i) 修改測試權(quán)重路徑
- ii) 執(zhí)行`python evaluate.py`測試測試集
- iii) 執(zhí)行`python main.py -na`生成測試報告
- iv) 運行`video_demo.py`查看識別效果
前言
圖片啥的都準備好了,也將YOLO格式的標注轉(zhuǎn)換成PascalVOC格式的標注了,結(jié)果打開D:\Yolov3_Tensorflow\tensorflow-yolov3\data\dataset里的voc_test.txt和voc_train一看,咋是這個格式的,讓人大吃一驚Σ(っ °Д °;)っ
根據(jù)我同事小王的提示,在YunYang1994/tensorflow-yolov3 Readme 翻譯里面有一句$ python scripts/voc_annotation.py --data_path /home/yang/test/VOC,會不會就是生成這倆文件的代碼?
訓(xùn)練流程
1、準備好圖片和train.txt、test.txt
train.txt、test.txt的格式為這樣,與作者指定的格式一致,生成方法有兩種,第一種使用LabelImg標定后生成的XML文件,運行作者提供的指令$ python scripts/voc_annotation.py --data_path /home/yang/test/VOC生成,第二種為從YOLO的標定文件直接生成,生成方法見此(如何將yolo的標注(annotations).txt 坐標轉(zhuǎn)換成tensorflow-yolov3(YunYang1994)的.txt 標注坐標?):
2、修改相關(guān)路徑
根據(jù) YunYang1994/tensorflow-yolov3 Readme 翻譯 中作者給出的訓(xùn)練自己的數(shù)據(jù)集流程,將訓(xùn)練VOC數(shù)據(jù)集的流程轉(zhuǎn)換成訓(xùn)練我們自己的數(shù)據(jù)集的流程:
i) 修改class.names文件以及__C.YOLO.CLASSES參數(shù)路徑
我在D:\20191031_tensorflow_yolov3\tensorflow-yolov3\data\classes路徑下新建class.names文件,并在里面寫入一個類——object(因為我們只用識別一個類),然后保存:
接下來打開D:\20191031_tensorflow_yolov3\tensorflow-yolov3\core路徑下的config.py文件:
將__C.YOLO.CLASSES路徑參數(shù)修改成我們剛才創(chuàng)建的class.names文件路徑,保存:
ii) 修改__C.TRAIN.ANNOT_PATH和__C.TEST.ANNOT_PATH參數(shù)路徑
還是在config.py文件里,我們將這倆參數(shù)修改成我們train.txt和test.txt的文件路徑。我想了想,還是把我的train.txt和test.txt文件放到作者原路徑下算了,方便一點:
以后的步驟就是,train.txt和test.txt文件在外部生成,生成好后再扔進去。文件的上級有數(shù)據(jù)集名以及日期,不怕跟其他數(shù)據(jù)集混淆。
然后修改train.txt和test.txt的文件路徑:
iii) __C.YOLO.ORIGINAL_WEIGHT和__C.YOLO.DEMO_WEIGHT
另外,我們還看到了__C.YOLO.ORIGINAL_WEIGHT = "./checkpoint/yolov3_coco.ckpt"參數(shù)和__C.YOLO.DEMO_WEIGHT = "./checkpoint/yolov3_coco_demo.ckpt"這兩個參數(shù),按ctrl+shift+f查看__C.YOLO.ORIGINAL_WEIGHT:
再查看org_weights_path:
查看__C.YOLO.DEMO_WEIGHT:
再查看cur_weights_path:
猜測__C.YOLO.ORIGINAL_WEIGHT是convert_weights.py轉(zhuǎn)換權(quán)重文件的源文件,__C.YOLO.DEMO_WEIGHT是轉(zhuǎn)換后生成的目標權(quán)重文件(用于將COCO權(quán)重文件轉(zhuǎn)換后生成預(yù)訓(xùn)練模型,__C.YOLO.DEMO_WEIGHT就是預(yù)訓(xùn)練模型,COCO權(quán)重文件(__C.YOLO.ORIGINAL_WEIGHT)如果不轉(zhuǎn)換則只能用于識別)。
所以,我們訓(xùn)練之前需要將COCO權(quán)重轉(zhuǎn)換成預(yù)訓(xùn)練模型,作者給出的轉(zhuǎn)換指令為:
python convert_weight.py --train_from_coco于是我把以前成功轉(zhuǎn)換的COCO預(yù)訓(xùn)練模型刪除,重新運行該指令,發(fā)現(xiàn)出錯:
經(jīng)查,發(fā)現(xiàn)是checkpoint文件夾位置錯了,本來應(yīng)該放在tensorflow-yolov3根目錄下,不知怎么搞到core文件夾里了(可能是鼠標點擊不小心拖進去了!)
把它重新搞出來就好了。
然后重新執(zhí)行python convert_weight.py --train_from_coco,就能正常生成了:
iv) 清理舊的權(quán)重文件
訓(xùn)練開始后權(quán)重文件會生成在checkpoint,查看該目錄是否有之前訓(xùn)練留下的權(quán)重文件,如果有就刪除或拷貝到其他文件夾,避免被直接覆蓋掉,我把以前訓(xùn)練VOC數(shù)據(jù)集生成的權(quán)重文件拷貝到了checkpoint目錄下的VOC_Weights_Files文件夾中:
3、開始訓(xùn)練
運行python train.py,不幸的是,又報錯了:
看起來像是程序?qū)⑽募械目崭癞?dāng)成分隔符讀取了,所以報錯說沒有f_cotton_g_top文件夾,但那只是我們的文件名:
建議將圖片序號改成純數(shù)字1、2、3、4、5…的,再重新生成train.txt和test.txt。
文件批量重命名參考:python 將指定路徑(目錄)下的圖片或文本文件按給定序號重新排序,并批量重命名 yolo、tensorflow數(shù)據(jù)集批量處理
弄完后發(fā)現(xiàn)一波小失誤,不該把圖片放在tensorflow文件夾外部的,這樣很容易出問題,以后再改了。。。
再次執(zhí)行python train.py:
終于開始正常訓(xùn)練了!
不過這個train loss怎么那么高,像是我把目標坐標上下顛倒了似的,不管了,先訓(xùn)練完測試一下再說。
訓(xùn)練了大約三四個小時,訓(xùn)練完成:
4、測試權(quán)重文件
訓(xùn)練完之后只剩41-50的權(quán)重文件了,挑選42作為測試權(quán)重。(關(guān)于如何修改保留的權(quán)重文件數(shù)量參見:yunyang tensorfow-yolo3 訓(xùn)練時權(quán)重文件消失的原因和解決辦法(max_to_keep))
i) 修改測試權(quán)重路徑
編輯config.py中的__C.TEST.WEIGHT_FILE路徑參數(shù),將其改成我們測試的權(quán)重文件名:
ii) 執(zhí)行python evaluate.py測試測試集
顯示報錯:
因為之前輸出畫框坐標的時候,修改了draw_bbox()函數(shù),向其增添了兩個參數(shù),現(xiàn)在因為運行evaluate.py文件單獨調(diào)用draw_bbox(),這兩個參數(shù)沒有傳遞,所以顯示出錯。
嘗試將這倆參數(shù)設(shè)置成可選參數(shù)或none試試。
已經(jīng)將這倆參數(shù)默認設(shè)置為None,同時給涉及這里倆參數(shù)的代碼包裹上if語句:
重新執(zhí)行python evaluate.py,能夠正常測試:
iii) 執(zhí)行python main.py -na生成測試報告
iv) 運行video_demo.py查看識別效果
直接運行video_demo.py,發(fā)現(xiàn)報錯,錯誤信息:
以前我們遇到過這個問題,參考:YunYang1994/tensorflow-yolov3 IndexError: list index out of range 解決辦法
于是我們將num_classes參數(shù)改成了1(因為我們class.names文件中只有一個類):
but,改成1后,又報錯了,顯示ValueError: cannot reshape array of size 43095 into shape (6):
觀察np.concatenate()函數(shù),可能問題出在這:
concatenate()用法參考這里:Python numpy hstack() vstack() stack() dstack() vsplit() concatenate()函數(shù)用法和區(qū)別
查看pred_sbbox.shape、pred_mbbox.shape、pred_lbbox.shape的打印數(shù)據(jù):
發(fā)現(xiàn)出現(xiàn)數(shù)字85,這肯定不對,還是5+80=85,按照我們設(shè)置的應(yīng)該是5+1=6才對,猜測可能是權(quán)重文件沒設(shè)置對:
順藤摸瓜,往上面找,發(fā)現(xiàn)了這個pb字樣,幡然醒悟:
我們沒有將權(quán)重轉(zhuǎn)換為.pb文件,.pb文件才是我們最終運行所需要的,現(xiàn)在的.pb還是以前老的.pb。
直接執(zhí)行convert.py,報錯,猜測不用運行convert.py的,它只有在轉(zhuǎn)換COCO權(quán)重和生成預(yù)訓(xùn)練文件時用得到,現(xiàn)在我們已經(jīng)有權(quán)重文件了,所以直接運行freeze_graph.py將我們的權(quán)重文件轉(zhuǎn)換成.pb文件即可:
嘗試運行freeze_graph.py,先修改其中的ckpt_file:
運行freeze_graph.py:
運行成功,并且可以看到.pb文件更新了:
再次運行video_demo.py,終于不報錯能夠正常識別了,但是識別效果老差,是不是過擬合了?
看了老久代碼,實在找不出問題出在哪兒,于是干脆自己照著evaluate.py重寫一個算了,重寫后執(zhí)行,發(fā)現(xiàn)效果不錯,
具體代碼參見:如何使用yunyang tensorflow-yolov3訓(xùn)練自己的數(shù)據(jù)集并使用 Intel realsense D435 傳輸視頻流應(yīng)用于實時檢測?
那原因出在哪兒?出在video_demo.py上?反正我沒仔細看它,看也看不懂。。。。
最后執(zhí)行自己重寫的dontla_evaluate_detect.py效果:
可以說,還行。
下一步,就是要解決如何使用指定序列號調(diào)用Intel Realsense攝像頭和多線程調(diào)用的還有深度檢測區(qū)域采樣平均去除黑洞的問題了。
參考文章1:YunYang1994/tensorflow-yolov3 Readme 翻譯
參考文章2:如何使用yunyang tensorflow-yolov3訓(xùn)練自己的數(shù)據(jù)集并使用 Intel realsense D435 傳輸視頻流應(yīng)用于實時檢測?
總結(jié)
以上是生活随笔為你收集整理的YunYang1994/tensorflow-yolov3 训练自己的数据集的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 将YOLO(txt)格式的
- 下一篇: python 绝对路径