1. 程式人生 > >YOLOv3訓練自己的數據

YOLOv3訓練自己的數據

roo 所有 打開終端 target label ext make rename read

1.下載官網的YOLOv3,打開終端輸入:git clone https://github.com/pjreddie/darknet

下載完成之後,輸入:cd darknet,然後再輸入:make,

make完成之後,下載預先訓練的weights文件,通過在終端裏輸入:wget https://pjreddie.com/media/files/yolov3.weights,然後就可以運行檢測器了,在終端裏輸入:./darknet detect cfg/yolov3.cfg yolov3.weights data/doa.jpg(這條命令得在darknet目錄下運行),會得到這樣的結果:

技術分享圖片

2.開始訓練自己的數據

(1)在darknet目錄下新建一個voc命名的文件夾,voc文件夾裏新建VOCdevkit文件夾,在VOCdevkit文件夾裏新建VOC2018文件夾,在VOC2018文件夾下新建Annotations,ImageSets,JPEGImages,SegmentationClass,SegmentationObject這五個文件夾,在ImageSets文件夾下新建Main文件夾。其中Annotations裏存放所有標註了圖片的xml文件,JPEGImages文件夾裏存放所有的圖片,Main中放train.txt和test.txt,至於SegmentationClass,SegmentationObject這兩個文件夾我沒有用到。

(2)圖片重命名,使用VOC的命名方式,這種:000012。重命名代碼如下,根據自己的路徑修改後就可以用:

# -*- coding: utf-8 -*-
import os
path = "/home/f/image/Aft_Original_Crack_DataSet_Second"
filelist = os.listdir(path) #該文件夾下所有的文件(包括文件夾)
count=0
for file in filelist:
print(file)
for file in filelist: #遍歷所有文件
Olddir=os.path.join(path,file) #原來的文件路徑
if os.path.isdir(Olddir): #如果是文件夾則跳過
continue
filename=os.path.splitext(file)[0] #文件名
filetype=os.path.splitext(file)[1] #文件擴展名
Newdir=os.path.join(path,str(count).zfill(6)+filetype) #用字符串函數zfill 以0補全所需位數
os.rename(Olddir,Newdir)#重命名
count+=1

(3)標註圖片,我使用的是labelImg。下載網址:https://github.com/tzutalin/labelImg

下載完成之後,再根據這個網址裏面的安裝方法進行安裝即可(我在執行最後這條語句:python labelImg.py時報錯了,然後加上sudo python labelImg.py執行就好了),然後就可以開始標註圖片了,標註方法參見:https://blog.csdn.net/cgt19910923/article/details/80211220。

(4)生成train.txt和test.txt,裏面的內容是這樣的:000606,沒有任何後綴名,我的生成後是用於測試的圖片會在train.txt裏面顯示為001234.j,同理用於訓練的圖片在test.txt裏也會這樣顯示,我們此時只需把這兩個.txt文件裏的所有.j刪除即可,否則後面會報錯。Python代碼如下,根據自己的路徑以及照片數量修改後就可以用:

# -*- coding: utf-8 -*-
import os
from os import listdir, getcwd
from os.path import join
if __name__ == ‘__main__‘:
source_folder=‘/home/f/darknet/voc/VOCdevkit/VOC2018/JPEGImages/‘#地址是所有圖片的保存地點
dest=‘/home/f/darknet/voc/VOCdevkit/VOC2018/ImageSets/Main/train.txt‘ #保存train.txt的地址
dest2=‘/home/f/darknet/voc/VOCdevkit/VOC2018/ImageSets/Main/test.txt‘ #保存test.txt的地址
file_list=os.listdir(source_folder) #賦值圖片所在文件夾的文件列表
train_file=open(dest,‘a‘) #打開文件
test_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<1000): #保留1000個文件用於訓練


#print file_num
train_file.write(file_name+‘\n‘) #用於訓練前149個的圖片路徑保存在train.txt裏面,結尾加回車換行
else :
test_file.write(file_name+‘\n‘) #其余的文件保存在test.txt裏面
train_file.close()#關閉文件
test_file.close()

(5)下載和修改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‘)] #根據自己的數據修改

classes = ["bridgecrack"] #根據自己的類別進行修改


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(‘/home/f/darknet/voc/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(‘/home/f/darknet/voc/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()

運行:在終端裏輸入:python voc_label.py 之後會在Main文件夾下生成2018_train.txt和2018_test.txt,以及文件夾VOCdevkit(這裏用到了之前main下的train和test文本文件,使得xml和jpg文件一一對應,並且生成最後的圖片路徑。)

(6)下載預訓練模型:在終端裏輸入:wget https://pjreddie.com/media/files/darknet53.conv.74

(7)修改cfg/voc.data

classes= 1 #根據自己的類型修改
train = /home/f/darknet/voc/2018_train.txt #根據自己的路徑修改
valid = /home/f/darknet/voc/2018_test.txt #根據自己的路徑修改
names = /home/f/darknet/data/voc.names #根據自己的路徑修改
backup = backup

(8)修改data/voc.names

裏面把自己的類別一一列出就好,這樣子的:

car

cat

(9)修改cfg/yolov3-voc.cfg

一共修改三處filters,classes,找到每個yolo的上面的filters,以及yolo下面的classes修改為自己的即可,修改根據:calsses是分類數,filters=3*(classes+5),random=0即關閉多尺度訓練。
技術分享圖片


具體每個參數的意思,參見這裏:https://blog.csdn.net/qq_33485434/article/details/80907040

(10)開始訓練

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74

訓練時,我的報cannot load image的錯誤,因為我的2018_train.txt裏面的圖片路徑下沒有照片,所以我就按裏面的路徑吧我的照片移動到了相應的路徑下,就沒有錯誤了。

(11)測試數據

在終端裏輸入:./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_600.weights data/001335.jpg

轉自:
---------------------
作者:FJY_sunshine
來源:CSDN
原文:https://blog.csdn.net/FJY_sunshine/article/details/82590440
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

YOLOv3訓練自己的數據