前沿
最近在用目標檢測方面的項目,所選擇的算法是yolov3(該算法的優點是:既有速度也有精度)。由於自己在實現該算法的時候遇到了不少坑,所以結合自己在該過程中遇到的問題以及對應解決思路整理一下,讓需要的人可以少走些彎路,節約時間。
總體來說,可分為四步進行操作:1.標注數據(我的上一篇博客已有詳細介紹) ;2.制作自己的數據集;3.下載並編譯源碼;4.修改參數文件;5.在操作環境下進行運行(我在LINUX環境進行的)
1.標注工具
使用的工具是LabelImg,由於YOLOV3的label標注的一行五個數分別代表類別:編號,BoundingBox 中心 X 坐標,中心 Y 坐標,寬,高。這些坐標都是 0~1 的相對坐標。由於該標注工具默認生成.xml文件屬性,這時我們可以通過LabelImg修改生成文件屬性。點擊如下紅框可直接生成yolov3算法需求的文件(.txt)


2.數據集編號
import os def rename(file_path): """ 遍歷文件並且進行重命名 :param file_path:文件的路徑(絕對) :return: """ filelist = os.listdir(file_path) total_num = len(filelist) i = 1 for item in filelist: # if item.endswith('.jpg'): if item.endswith('.txt'): src = os.path.join(os.path.abspath(file_path), item) str1 = str(i) # dst = os.path.join(os.path.abspath(file_path), str1.zfill(6) + '.jpg') # str1.zfill(x),x為一共幾位數,用0補齊,如001000 dst = os.path.join(os.path.abspath(file_path), str1.zfill(6) + '.txt') # str1.zfill(x),x為一共幾位數,用0補齊,如001000 try: os.rename(src, dst) print('converting %s to %s ...' % (src, dst)) i = i + 1 except: continue # file_path = 'D:\\ImageLabel\\TargetData\\output\\' # .jpg圖片的存儲路徑 file_path = 'D:\\ImageLabel\\SaveTxt' # .txt圖片的存儲路徑 rename(file_path)
執行上述代碼,可生成對應文件重命名。為了規划自己的數據,減少出錯的可能性,最好自己先給自己的圖片編一個合理的序號,比如0001~0999。
3.數據標注
利用軟件把自己的數據標注好。每一個圖片名對應的有一個相應名字的.txt結果如下所示:




二.制作自己的數據集
在目錄下新建VOC2007,並在VOC2007下新建labels,ImageSets和JPEGImages三個文件夾。在ImageSets下新建Main文件夾。文件目錄如下所示:


其中數據集圖片(.jpg)拷貝到JPEGImages目錄下,數據集(.txt)文件拷貝到labels目錄下.在VOC2007下新建test.py文件夾,將下面代碼拷貝進去運行
import os import random trainval_percent = 0.1 train_percent = 0.9 xmlfilepath = 'Annotations' txtsavepath = 'ImageSets\Main' total_xml = os.listdir(xmlfilepath) num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr) ftrainval = open('ImageSets/Main/trainval.txt', 'w') ftest = open('ImageSets/Main/test.txt', 'w') ftrain = open('ImageSets/Main/train.txt', 'w') fval = open('ImageSets/Main/val.txt', 'w') for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftest.write(name) else: fval.write(name) else: ftrain.write(name) ftrainval.close() ftrain.close() fval.close() ftest.close()
將生成四個文件:


三.下載並編譯源碼
1.下載代碼
git clone https://github.com/pjreddie/darknet
2.編譯代碼
YOLOV3使用一個開源的神經網絡框架Darknet53,使用C和CUDA,有CPU和GPU兩種模式。默認使用的是CPU模式,需要切換GPU模型的話,vim修改Makefile文件。
cd darknet
如果使用GPU模式,則需要修改Makefile文件
vim Makefile


make # 進行編譯
編譯成功后,可以先下載預訓練模型測試一下效果。
wget https://pjreddie.com/media/files/yolov3.weights
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
到這里,YOLOV3已經走通了,接下來只需要加入自己的數據就OK了。
3.加入訓練集
在代碼的darknet目錄下新建VOCdevkit文件夾,然后把剛才制作的VOC2007文件夾拷貝到該文件夾下。


然后在VOC2007同級目錄下添加gather_all_image.py,代碼如下:
import os #paths=['coco2014','Stanford','vehicleplate'] paths=['VOC2007'] f=open('hour_hand.txt', 'w') for path in paths: p=os.path.abspath(path)+'/JPEGImages' filenames=os.listdir(p) for filename in filenames: im_path=p+'/'+filename print(im_path) f.write(im_path+'\n') f.close()
運行gather_all_image.py文件后會生成hour_hand.txt,內容如下:


四.修改參數文件
1.修改darknet/cfg/voc.data


2.修改darknet/data/voc.names和coco.names
打開對應的文件都是原本數據集里的類,改成自己的類就行


3.修改參數文件darknet/cfg/yolov3.cfg
參數文件開頭的地方可以選訓練的batchsize,要注意!


ctrl+f搜 yolo, 總共會搜出3個含有yolo的地方。 每個地方都必須要改2處, filters=3*(5+len(classes)); 其中:classes: len(classes) = 1,該測試是以hour hand單個類do為例:filters = 18 classes = 1
可修改:random = 1:原來是1,顯存小改為0.
4.修改類別數



五.啟動訓練
1.下載darknet53的預訓練模型
wget https://pjreddie.com/media/files/darknet53.conv.74
2.開始訓練
./darknet detector train cfg/voc.data cfg/yolov3.cfg darknet53.conv.74
3.后續會總結YOLOv3訓練過程中重要參數的理解和輸出參數的含義
