做者:ll_sunsmile
來源:CSDN
原文:https://blog.csdn.net/ll_master/article/details/81392013
版權聲明:本文爲博主原創文章,轉載請附上博文連接!python
(一、二、3在test中出現,4在train中出現)git
改darknet下makefile文件參數,修改不成功。
解決:服務器配置有問題。檢查cuda,cudnn,opencv這些版本是否兼容吧。。要是一直修改不成功,就去刪darknet,從新作一遍。要出來結果,確定要付出代價的麼。一遍不成功就再來一遍。反正我改了修也作了三遍。github
backup生成的權重文件不會用。傻裏巴嘰還用以前自帶版本的權重,結果哭唧唧,生成一大堆車、馬、人,根本不是本身須要的類別標籤。
解決:固然使用本身生成的權重文件啦,backup下每次都有會新的迭代權重。bash
好不容易解決了前面兩個,終於熬到檢測這一步,奇怪的發現仍是什麼都沒有。
解決:檢測語句有問題,細心的我特別去看了官網的檢測語句。有兩條等同的檢測語句,咱們選擇那條指明分類的語句。由於分類結果出不來,確定是沒有找到分類文件呀。咱們給他指明,就清楚咯。
選擇這種:服務器
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights data/1.jpg
不選擇這種:dom
./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_600.weights data/1.jpg
還有就是開始train的時候cuda out of memory等問題。
例如 :ide
0 CUDA Error: out of memory darknet: ./src/cuda.c:36: check_error: Assertion `0’ failed.
緣由:gpu佔用有問題,gpu所有佔用,或內存不足時會出現此問題。
解決方案1:修改batch=1與subdivision=1,減小每次的輸入量。
解決方案2:查看GPU佔用,學習
nvidia-smi #查看GPU佔用狀況, kill -9 <pid> #-9,強制執行
標註本身的數據集。根據本身劃分的類別用labelimg進行標註,保存後會生成與所標註圖片文件名相同的xml文件。測試
下載官網yolov3工程.net
git clone https://github.com/pjreddie/darknet cd darknet cd darknet
修改配置文件
打開Makefile,修改編譯選擇。
make #保存,記住必定要make才能生效
修改完成後,在darknet目錄下進行編譯。
若是服務器配置沒有問題,那麼會成功,若是不成功的話就檢查一下cuda,cudnn,opencv這些版本是否兼容的問題。
準備數據集,創建層級結構存儲目錄便於數據的管理。文件名稱的命名也是爲了之後方便修改配置文件。
Annotations中放全部的xml文件;JPEGImages中放全部的圖片;Main中放train.txt和test.txt。
然而train.txt和test.txt是如何生成的呢?
生成python文件取出訓練集和測試集的圖片名稱沒有後綴名。
import os from os import listdir, getcwd from os.path import join if __name__ == '__main__': source_folder='/home/lll/darknet/voc/VOCdevkit/VOC2018/JPEGImages/'#地址是全部圖片的保存地點 dest='/home/lll/darknet/voc/VOCdevkit/VOCClock/ImageSets/Main/train.txt' #保存train.txt的地址 dest2='/home/lll/darknet/voc/VOCdevkit/VOCClock/ImageSets/Main/test.txt' #保存val.txt的地址 file_list=os.listdir(source_folder) #賦值圖片所在文件夾的文件列表 train_file=open(dest,'a') #打開文件 val_file=open(dest2,'a') #打開文件 for file_obj in file_list: #訪問文件列表中的每個文件 file_path=os.path.join(source_folder,file_obj) #file_path保存每個文件的完整路徑 file_name,file_extend=os.path.splitext(file_obj) #file_name 保存文件的名字,file_extend保存文件擴展名 file_num=int(file_name) #把每個文件命str轉換爲 數字 int型 每一文件名字都是由四位數字組成的 如 0201 表明 201 高位補零 if(file_num<150): #保留149個文件用於訓練 #print file_num train_file.write(file_name+'\n') #用於訓練前149個的圖片路徑保存在train.txt裏面,結尾加回車換行 else : val_file.write(file_name+'\n') #其他的文件保存在val.txt裏面 train_file.close()#關閉文件 val_file.close()
下載和修改voc_label.py(這個文件就說明了爲何一開始創建層級目錄,由於能夠避免不少路徑的修改呀)
下載:
wget https://pjreddie.com/media/files/voc_label.py
修改:
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join #根據本身的須要修改,只要先後路徑對應就行。 sets=[('2018', 'train'), ('2018', 'test')] #個人類是5個(^U^)ノ~YO classes = ["m", "s","l","xl","xxl"] def convert(size, box): dw = 1./size[0] dh = 1./size[1] x = (box[0] + box[1])/2.0 y = (box[2] + box[3])/2.0 w = box[1] - box[0] h = box[3] - box[2] x = x*dw w = w*dw y = y*dh h = h*dh return (x,y,w,h) def convert_annotation(year, image_id): in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id)) out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w') tree=ET.parse(in_file) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) for obj in root.iter('object'): difficult = obj.find('difficult').text cls = obj.find('name').text if cls not in classes or int(difficult) == 1: continue cls_id = classes.index(cls) xmlbox = obj.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) bb = convert((w,h), b) out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') wd = getcwd() for year, image_set in sets: if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)): os.makedirs('VOCdevkit/VOC%s/labels/'%(year)) image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split() list_file = open('%s_%s.txt'%(year, image_set), 'w') for image_id in image_ids: list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id)) convert_annotation(year, image_id) list_file.close()
執行voc_label.py:
python voc_label.py
在voc下生成了2018_train.txt 和 2018_test.txt,分別存放了訓練集和測試集圖片的路徑。
ps:這裏用到了以前main下的train和test文本文件,使得xml和jpg文件一一對應,而且生成最後的圖片路徑。
以後訓練時候就能夠根據圖片路徑和一些配置文件信息進行訓練咯。
下載預訓練模型
wget https://pjreddie.com/media/files/darknet53.conv.74
修改 cfg/voc.data
修改data/voc.names
修改cfg/yolov3-voc.cfg
[net] #Testing #batch=1 #subdivisions=1 #Training batch=64 subdivisions=8 #---------------修改 ...... [convolutional] size=1 stride=1 pad=1 filters=30 #---------------修改 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=5 #---------------修改 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=0 #---------------修改 ...... [convolutional] size=1 stride=1 pad=1 filters=30 #---------------修改 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=5 #---------------修改 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=0 #---------------修改 ...... [convolutional] size=1 stride=1 pad=1 filters=30 #---------------修改 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=5 #---------------修改 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=0 #---------------修改 標記的地方須要修改,classes是你的分類數,filters=3*(classes+5),random=0即關閉多尺度訓練
具體每一個參數的意思,我會繼續更新總結的。怎麼調整參數,使得效果最佳,還要依靠人爲經驗。
開始訓練:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -gpus 0,1,2,3
開始測試
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_900.weights voc/VOCdevkit/VOC2018/test/169.jpg
測試權重用本身生成的backup下的,測試照片用本身測試集的。
但願可愛的你也會出現本身想要的結果哦!!
還想解釋一下訓練過程當中出現的種種參數,那都是是個啥?來來來,看一看。
參考一下
原英文地址: https://timebutt.github.io/static/understanding-yolov2-training-output/
原中文翻譯地址:https://blog.csdn.net/dcrmg/article/details/78565440
8個分組,所以有八個subdivision,每一個subdivision有八個照片
以上截圖顯示了全部訓練圖片的一個批次(batch),批次大小的劃分根據咱們在 .配置cfg 文件中設置的subdivisions參數。修改的cfg 文件中 batch = 64 ,subdivision = 8,因此在訓練輸出中,訓練迭代包含了8組,每組又包含了8張圖片,跟設定的batch和subdivision的值一致。
• Region Avg IOU: 0.326577: 表示在當前subdivision內的圖片的平均IOU,表明預測的矩形框和真實目標的交集與並集之比,這裏是32.66%,這個模型須要進一步的訓練。
Class: 0.742537: 標註物體分類的正確率,指望該值趨近於1。
Obj: 0.033966: 越接近1越好。
No Obj: 0.000793: 指望該值愈來愈小,但不爲零。
Avg Recall: 0.12500: 是在recall/count中定義的,是當前模型在全部subdivision圖片中檢測出的正樣本與實際的正樣本的比值。在本例中,只有八分之一的正樣本被正確的檢測到。(和最開始初定的閾值有關係)
count: 8:count後的值是全部的當前subdivision圖片(本例中一共8張)中包含正樣本的圖片的數量。在輸出log中的其餘行中,能夠看到其餘subdivision也有的只含有6或7個正樣本,說明在subdivision中含有不含檢測對象的圖片。
9798: 指示當前訓練的迭代次數
0.370096: 是整體的Loss(損失)
0.451929 avg: 是平均Loss,這個數值應該越低越好,通常來講,一旦這個數值低於0.060730 avg就能夠終止訓練了。
0.001000 rate: 表明當前的學習率,是在.cfg文件中定義的。
3.300000 seconds: 表示當前批次訓練花費的總時間。
627072 images: 這一行最後的這個數值是9798*64的大小,表示到目前爲止,參與訓練的圖片的總量。
做者:ll_sunsmile
來源:CSDN
原文:https://blog.csdn.net/ll_master/article/details/81392013 版權聲明:本文爲博主原創文章,轉載請附上博文連接!