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