yolov3訓練自己的數據集


 

 

 

一.下載yolov3工程項目

git clone https://github.com/pjreddie/darknet 

cd darknet 

將makefile的相應部分參數改為1,

#如果使用GPU設置為1,CPU設置為0,GPU=0

#如果使用CUDNN設置為1,否則為0,CUDNN=0

#如果使用OPENCV設置為1,否則為0,OPENCV=1

修改后保存,再make一下。

將官網的預訓練權重先下載到darknet下

二.准備訓練數據集

按照下面文件夾的結構,將訓練數據集放到各個文件夾下面,生成2個文件一個train.txt,一個是val.txt。這里使用到的腳本為getfile.py,

VOCdevkit

 —VOC2012

  ——Annotations

  ——ImageSets

    ———Layout

    ———Main

    ———Segmentation

  ——JPEGImages

注意:其中Annotations中是所有的xml文件

JPEGImages中是所有的訓練文件

Main中是2個txt文件:train.txt與val.txt文件(前一個用來驗證,后一個用來測試)

 

三.生成2007_train.txt和2007_val.txt文件

下載voc_label.py,或者直接在scripts中找到voc_labels.py將該文件與VOCdevkit數據集放到同一級路徑下。

首先修改voc_label.py里面的值:

修改sets為自己訓練樣本集的名稱,以及classes為訓練樣本集的類標簽

 

文件最后兩行注釋掉

在當前終端運行 python voc_label.py

生成

①   訓練和驗證的文件列表(2007_train.txt和2007_val.txt)主要存儲的是圖片位置信息;

 

②   生成與Annotations等同級的label文件,label里面的文件是每張圖片位置坐標以及類別的標簽信息。

 

 

四.修改cfg/voc.data文件

#classes為訓練樣本集的類別總數:classes= 1

#train的路徑為訓練樣本集所在的路徑

train = /home/njust/darknet_model/darknet_person/2007_train.txt

#valid的路徑為驗證樣本集所在的路徑

valid  = /home/njust/darknet_model/darknet_person/2007_val.txt

#names的路徑為data/voc.names文件所在的路徑

names = data/voc.names

backup = backup

 

五.在darknet文件夾下面新建文件夾backup

六.修改voc.name為樣本集的標簽名

七.修改cfg/yolov3-voc.cfg

這里我只是以一類目標檢測為例,主要有4處地方調整:

 

[net]

# Testing

# batch=1

# subdivisions=1

# Training

 batch=64

 

 subdivisions=16

 

......

 

[convolutional]

size=1

stride=1

pad=1

filters=18###75

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=1###20

num=9

jitter=.3

ignore_thresh = .5

truth_thresh = 1

random=0###1

......

 

[convolutional]

size=1

stride=1

pad=1

filters=18###75

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=1###20

num=9

jitter=.3

ignore_thresh = .5

truth_thresh = 1

random=0###1

......

 

[convolutional]

size=1

stride=1

pad=1

filters=18###75

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=1###20

num=9

jitter=.3

ignore_thresh = .5

truth_thresh = 1

random=0###1

 

A.filters數目是怎么計算的:3x(classes數目+5),和聚類數目分布有關,論文中有說明;

 

B.如果想修改默認anchors數值,使用k-means即可;

 

C.如果顯存很小,將random設置為0,關閉多尺度訓練;

 

D.其他參數基本與V2一致,不再說明;

 

E.前100次迭代loss較大,后面會很快收斂;

八.開始訓練

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

九.識別

         ./darnket detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc.backup data/test.jpg

 

 

 

 

 

常見問題解決:

  1. 1.      什么時候停止訓練:

通常每個類(對象)有足夠的2000次迭代。但是,當你應該停止訓練時,為了更准確的定義,請使用以下指標:

 

9002:是迭代次數

0.060730:是平均損失,當看到平均損失0.xxxxx avg在許多吃迭代不再減少時,應該停止訓練。一旦停止訓練,可以得到最后的.weights文件,可以在backup里面找到最佳的文件,也可以使用yolov3-voc.backup這個文件。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

***利用YOLOv2訓練數據---https://blog.csdn.net/echoKangYL/article/details/79445587

 

1.下載YOLO

yolo的官網:https://pjreddie.com/darknet/yolo/

2.數據預處理(該處理方法與參考博客中的方法相同)該階段建立的文件夾的名稱最好與該文檔中的相同,否則需要改動圖片處理等python腳本中的文件名。a.建立文件夾"Image",並在其下存放所有圖片樣本(jpg、png均可)b.利用labelImg工具進行標注c.與Image文件件同級建立"xml"文件夾,存放利用labelImg標注后得到的所有圖片的xml文件d.下載腳本,放在Image、xml文件夾的同級腳本下載地址:http://pan.baidu.com/s/1hs22I7U 密碼:wdv0(該下載地址在參考博客中有提供,十分感謝原作者的幫助)在運行腳本之前,先做幾處改動:a.將traindata.py中大概在65行和71行的:shutil.copy(xmlolddir, newdir1);shutil.copy(xmlolddir, newdir2);兩句刪掉(或前面加‘#’)否則在訓練過程中報類似這樣的error:“Cannot load image "/home/ts/tensorflow/objectRecognition/Augmentation/KNIFE/Getdata/trainImage/000018.png"STB Reason: unknown image type”b.若之前建立文件夾時文件夾名稱並非Image和xml,那么在traindata.py中的對應文件夾名稱處將其改為自己的文件夾名稱改動之后,運行腳本運行traindata.py:生成trainImage文件夾,存放訓練圖片;生成trainImageXML文件夾,存放訓練圖片xml標簽;生成validateImage文件夾,存放驗證集圖片;生成validateImageXML文件夾,存放驗證集圖片的xml標簽;生成trainImageId.txt、validateImageId.txt,存放訓練、驗證集圖片索引(一般為文件名)。運行trans.py,生成trainImageLabelTxt文件夾,存放訓練圖片通過xml標簽轉化得到的txt文件(若在訓練過程提示txt文件找不到,則把此文件夾下的txt文件夾移動到trainImage文件夾);生成validateImageLabelTxt文件夾,道理一樣。另外,得到的trainImagePath.txt和validateImagePath.txt存放着訓練圖片和驗證圖片的路徑。此后,將生成的validateImageLabelTxt文件夾中的所有txt文件復制到validateImage文件夾中;同理,將trainImageLabelTxt文件夾中的所有txt文件復制到trainImage文件夾中。否則會在訓練過程中報類似這樣的error:“cannot open file xxxxxx.txt”

 

3.修改配置文件a.cfg/voc.data文件中:classes= 3train  = /home/ts/tensorflow/objectRecognition/YOLOv2/YOLOtraining/trainImagePath.txtvalid  = /home/ts/tensorflow/objectRecognition/YOLOv2/YOLOtraining/validateImagePath.txtnames = data/knifes.namesbackup = backupclasses存放類別總數(這里有knife、swissknife、jackknife三種,根據使用者不同的需要進行改動),train 和valid 中存的是訓練圖片集和驗證圖片集的路徑;在data文件夾中新建文件knifes.names,存放的是方框注釋,本例中有三行(根據使用者不同的需要進行改動):knifeswissknifejackknifeb.yolo-voc.cfg文件中:將[region]中的classes改為3(這里有knife、swissknife、jackknife三類,根據使用者不同的需要進行改動);將最后一個[convolutional](緊挨着[region]的前一個)中的filter改為40(filter的公式filters=(classes+coords+1)*(NUM),這里是(3+4+1)*5=30,根據使用者不同的需要進行改動)。 c.knifes.names:具體見a4.下載預訓練文件cfg/darknet19_448.conv.23以在其他數據集上pretrain的模型做為初值。下載地址:http://pan.baidu.com/s/1dFgUk4x 密碼:ynhg(該下載地址為參考博客原文作者提供,再次感謝原作者的幫助)下載之后將其放在darknet文件夾下。在訓練之前,要先在darknet文件夾下新建backup文件夾,在backup文件夾中新建一個以yolo-voc.backup為文件名的文件,以保存訓練參數。否則將在訓練過程中報類似這樣的error:“cannot open backup/yolo-voc.backup”5.訓練在darknet文件夾路徑下運行命令:./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23系統默認會迭代45000次batch,如果需要修改訓練次數,進入cfg/yolo_voc.cfg修改max_batches的值。6.測試訓練完成后,模型成功保存,輸入命令測試模型:./darknet detector test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights testpicture/001.jpg在該步驟中,將最后一個參數 testpicture/001.jpg 改為自己想要測試的圖片路徑;若提前終止訓練,則將倒數第二個參數 backup/yolo-voc_final.weights 改為backup文件夾下的最新權重備份文件名稱,例如:我提前終止后,最新權重備份文件為 backup/yolo-voc_900.weights。否則將提示error:“Couldn't open file: backup/yolo-voc_final.weights”參考原文中訓練類別為1,本文中的訓練類別為3,相互比較之下可以知道所有類別的情況下配置文件應該如何改動。

 

原文:https://blog.csdn.net/echoKangYL/article/details/79445587

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

***YOLO訓練自己的數據集---https://blog.csdn.net/qq_34484472/article/details/73135354#reply

 

1.yolo

yolo的官網:https://pjreddie.com/darknet/yolo/

yolo的官網介紹了yolo的安裝與測試。建議大家多看看英文官網,因為中文網更新的慢,而且有部分內容省略了。按照官網的步驟就不會有錯。(建議先跑一下Pscal VOC)

 

2.數據的預處理

yolo的數據包括訓練數據和驗證數據(訓練數據用來訓練模型,驗證數據用來調整模型)。訓練數據和驗證數據都包括:a.圖片;b.標簽。需要說明的是,如果采用VCC的話,標簽需要特定xml格式,還要轉化為txt。下面以我目標檢測“貓”為例講解。

 

a.在“Image”文件夾下存放所有的圖片樣本(包括訓練數據和驗證數據,而且最好是jpg格式)

 b.下載labelImg(一種圖像標記工具,給圖像中的目標打上標簽,且可以生成訓練需要的xml格式),具體的使用方法可以百度,操作起來很簡單。

 c.與“Image”文件夾同級新建“xml”文件夾,“xml”文件夾存放labelImg得到的所有圖片樣本的標簽。

標注工具labelImgUbuntu系統的安裝和使用--- https://blog.csdn.net/learning_tortosie/article/details/80947301

 

若是標中文則要進行整改--- https://www.cnblogs.com/datou-swag/articles/10658822.html

 d.現在就是要將所有的樣本分成訓練集和驗證集,而且要將訓練集和驗證集對應的xml也分開。這里下載python腳本,直接放在“Image”和“xml”文件夾同級路徑。

 

下載:

 鏈接:http://pan.baidu.com/s/1hs22I7U 密碼:wdv0

在運行腳本之前,先做幾處改動:a.將traindata.py中大概在65行和71行的:shutil.copy(xmlolddir, newdir1);shutil.copy(xmlolddir, newdir2);兩句刪掉(或前面加‘#’)否則在訓練過程中報類似這樣的error:“Cannot load image

運行traindata.py:生成trainImage文件夾,存放訓練圖片;生成trainImageXML文件夾,存放訓練圖片xml標簽;生成validateImage文件夾,存放驗證集圖片;生成validateImageXML文件夾,存放驗證集圖片的xml標簽。

運行trans.py(改一下自己的類別),生成trainImageLabelTxt文件夾,存放訓練圖片通過xml標簽轉化得到的txt文件(若在訓練過程提示txt文件找不到,則把此文件夾下的txt文件夾移動到trainImage文件夾);生成validateImageLabelTxt文件夾,道理一樣。

另外得到的trainImagePath.txt和validateImagePath.txt存放着訓練圖片和驗證圖片的路徑。

 

3.修改配置文件

 接下來就是修改配置文件了:

 a.cfg/voc.data文件中:

 classes= 1

train  = /home/pdd/pdwork/darknet2/darknet/VOC/cat/trainImagePath.txt

valid  = /home/pdd/pdwork/darknet2/darknet/VOC/cat/validateImagePath.txt

names = data/cats.names

classes存放類別總數(這里只有cat一種),train  和valid  放着的是訓練圖片和驗證圖片的路徑,cats.names存放的是方框注釋,這里只有cat一行:

 

b.yolo-voc.cfg

將[region]中的classes改為1(這里只有cat一類),將最后一個[convolutional](緊挨着[region]的前一個)中的filter改為30(filter的公式filters=(classes+ coords+ 1)* (NUM) ,我的是(1+4+1)* 5=30)。

c.cats.names

在data文件夾下新建cats.names,具體見a。

 

4.下載預訓練文件cfg/darknet19_448.conv.23

以在其他數據集上pretrain的模型做為初值,下載地址:

鏈接:http://pan.baidu.com/s/1dFgUk4x 密碼:ynhg。放在darknet文件夾下。

(最新的預訓練權中參數darknet53.conv.74---                                 wget https://pjreddie.com/media/files/darknet53.conv.74)

5.訓練

在darknet文件夾路徑下運行命令:

./darknet detector train cfg/voc.data cfg/yolo-voc.cfg cfg/darknet19_448.conv.23

系統默認會迭代45000次batch,如果需要修改訓練次數,進入cfg/yolo_voc.cfg修改max_batches的值。

6.測試

訓練完成后,模型成功保存,輸入命令測試一下這個模型吧:

./darknet detector test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights testpicture/001.jpg

 

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

 

./darknet detector test cfg/chinese.data cfg/chinese-voc.cfg  chinese_output/chinese-voc_final.weights chinese_data/Image/6420.jpg

---------------------

作者:Panda_Peng

來源:CSDN

原文:https://blog.csdn.net/qq_34484472/article/details/73135354

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 

 

 

 

 

 

 

 

 

yolo v2使用總結---http://www.cnblogs.com/shepherd2015/p/8671646.html

 

Darknet Darknet 源碼理解---https://zhuanlan.zhihu.com/p/37726435

 

 

 

【YOLO】訓練voc數據集沒有框??解決方法

https://blog.csdn.net/shangpapa3/article/details/76277869

 

如果你想保存輸出的結果,在后面加句 | tee yolo-voc.txt

./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23 | tee yolo-voc.txt

 

./darknet detector test cfg/voc.data cfg/yolo-voc.2.0.cfg yolo-voc_final.weights data/dog.jpg -thresh 0.25

 

 

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

 

 

###traindata.py###

# -*- coding: utf-8 -*-
import os;
import shutil;

def rename_by_count(path): #按序號命名
    count = 1000;
    filelist = os.listdir(path)  # 該文件夾下所有的文件(包括文件夾)
    for files in filelist:  # 遍歷所有文件
        Olddir = os.path.join(path, files);  # 原來的文件路徑
        if os.path.isdir(Olddir):  # 如果是文件夾則跳過
            continue;
        filename = os.path.splitext(files)[0];  # 文件名
        filetype = os.path.splitext(files)[1];  # 文件擴展名
        Newdir = os.path.join(path, str(count) + filetype);  # 新的文件路徑
        os.rename(Olddir, Newdir);  # 重命名
        count += 1;


def listname(path,idtxtpath):
    filelist = os.listdir(path);  # 該文件夾下所有的文件(包括文件夾)
    f = open(idtxtpath, 'w');
    for files in filelist:  # 遍歷所有文件
        Olddir = os.path.join(path, files);  # 原來的文件路徑
        if os.path.isdir(Olddir):  # 如果是文件夾則跳過
            continue;
        filename = os.path.splitext(files)[0];  # 文件名
        filetype = os.path.splitext(files)[1];  # 文件擴展名
        #Newdir = os.path.join(path, "1000" + filetype);  # 新的文件路徑: path+filename+type
        f.write(filename);
        f.write('\n');
    f.close();


def imgid_list(imgpath, savepath, num):
    #rename_by_count(imgpath);

    path1 = savepath + "/validateImage";
    path2 = savepath + "/trainImage";
    if os.path.exists(path1)== False:
        os.mkdir(path1);
    if os.path.exists(path2) == False:
        os.mkdir(path2);
    xmlpath1 = savepath + "/validateImageXML";
    xmlpath2 = savepath + "/trainImageXML";
    if os.path.exists(xmlpath1)== False:
        os.mkdir(xmlpath1);
    if os.path.exists(xmlpath2) == False:
        os.mkdir(xmlpath2);

    filelist = os.listdir(imgpath);
    count = 0;
    for files in filelist:
        olddir = os.path.join(imgpath, files);
        newdir1 = os.path.join(path1, files);
        newdir2 = os.path.join(path2, files);
        filename = os.path.splitext(files)[0];  # 文件名
        xmldir = savepath + "/xml";
        xmldir1 = savepath + "/validateImageXML";
        xmldir2 = savepath + "/trainImageXML";
        if count<num:
            shutil.copy(olddir, newdir1); #validate
            xmlolddir = os.path.join(xmldir, filename + ".xml");
            xmlnewdir = os.path.join(xmldir1,filename+".xml");
            shutil.copy(xmlolddir,xmlnewdir);
            #shutil.copy(xmlolddir, newdir1);
        else:
            shutil.copy(olddir, newdir2);
            xmlolddir = os.path.join(xmldir, filename + ".xml");
            xmlnewdir = os.path.join(xmldir2, filename + ".xml");
            shutil.copy(xmlolddir, xmlnewdir);
            #shutil.copy(xmlolddir, newdir2);
        count=count+1;

    imgidtxtpath1 = savepath + "/validateImageId.txt";
    imgidtxtpath2 = savepath + "/trainImageId.txt";
    listname(path1, imgidtxtpath1);
    listname(path2, imgidtxtpath2);





#rename_by_count;   # 給圖片按序號給名字
savepath = os.getcwd()#取得當前工作目錄
imgpath = savepath+"/Image"
val_num=16   #驗證集數量,可修改
imgid_list(imgpath,savepath,val_num);

 

 

###trans.py

import xml.etree.ElementTree as ET
import pickle
import string
import os
import shutil
from os import listdir, getcwd
from os.path import join

sets=[('2012', 'train')]

classes = ["plate"]  #分類集,我這里是識別貓,所以是一個cat


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(image_id,flag,savepath):
    #s = '\xef\xbb\xbf'
    #nPos = image_id.index(s)
    #if nPos >= 0:
     #   image_id = image_id[3:]
    if flag == 0:
        in_file = open(savepath+'/trainImageXML/%s.xml' % (image_id))
        labeltxt = savepath+'/trainImageLabelTxt';
        if os.path.exists(labeltxt) == False:
            os.mkdir(labeltxt);
        out_file = open(savepath+'/trainImageLabelTxt/%s.txt' % (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)
    elif flag == 1:
        in_file = open(savepath+'/validateImageXML/%s.xml' % (image_id))
        labeltxt = savepath + '/validateImageLabelTxt';
        if os.path.exists(labeltxt) == False:
            os.mkdir(labeltxt);
        out_file = open(savepath+'/validateImageLabelTxt/%s.txt' % (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:
    #savepath = "/home/wurui/CAR/wrz/pillar";
    savepath = os.getcwd();
    idtxt = savepath + "/validateImageId.txt";
    pathtxt = savepath + "/validateImagePath.txt";
    image_ids = open(idtxt).read().strip().split()
    list_file = open(pathtxt, 'w')
    s = '\xef\xbb\xbf'
    for image_id in image_ids:
        nPos = image_id.find(s)
        if nPos >= 0:
            image_id = image_id[3:]
        list_file.write('%s/validateImage/%s.jpg\n' % (wd, image_id))
        print(image_id)
        convert_annotation(image_id, 1, savepath)
    list_file.close()

    idtxt = savepath + "/trainImageId.txt";
    pathtxt = savepath + "/trainImagePath.txt" ;
    image_ids = open(idtxt).read().strip().split()
    list_file = open(pathtxt, 'w')
    s = '\xef\xbb\xbf'
    for image_id in image_ids:
        nPos = image_id.find(s)
        if nPos >= 0:
           image_id = image_id[3:]
        list_file.write('%s/trainImage/%s.jpg\n'%(wd,image_id))
        print(image_id)
        convert_annotation(image_id,0,savepath)
    list_file.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM