ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

YOLOv4如何训练自己的数据集

2021-11-19 20:01:32  阅读:520  来源: 互联网

标签:文件 YOLOv4 训练 数据 train yolov4 2007 txt data


第一步:安装darknet

参考:Windows搭建Darknet框架环境-Yolov4-GPU_乐观的lishan的博客-CSDN博客

darknet的源码说明中也已经简单介绍了如何利用数据集训练网络

第二步:制作VOC格式数据集

网上搜集自己需要的数据集,或自己拍摄相关视频,然后提取帧图片

大部分的网络公开数据集已经附带有标注好的xml文件

推荐交通领域公开数据集(包含无人驾驶、交通标志、车辆检测三大类)链接如下:【智能交通数据集】一文道尽智能交通领域数据集合集(一) - 飞桨AI Studio - 人工智能学习与实训社区

也有一部分数据集没有xml格式的标注文件,此时需要使用其他方法将其转换为xml文件

例如BITVehicle数据集提供的就是一个mat格式的标注文件,需要编写程序读取数据并生成对应图片的xml文件

对于没有标签的数据集或者是自己拍摄的数据集,需要使用labelimg工具进行标定,生成xml文件,使用pip安装命令即可安装

pip install labelimg

打开labelimg命令

labelimg

新建一个VOCdevkit文件夹,参照VOC数据集的目录分布建立其他子文件夹(此时文件夹内还没有文件)

  1. 将数据集所有图片放到JPEGImages文件夹

  2. 将所有图片对应的xml标注文件放到Annotations

  3. 生成txt相关文件放在Main文件夹下(利用gen_files.py文件)

    文件来源于博客:Yolov4训练自己的数据集_sinat_28371057的博客-CSDN博客_yolov4训练自己的数据集

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # file: gen_files.py
    # 生成训练所需txt文件
    import os
    import random
    root_path = './VOCdevkit/VOC2007'
    xmlfilepath = root_path + '/Annotations'
    txtsavepath = root_path + '/ImageSets/Main'
    if not os.path.exists(root_path):
        print("cannot find such directory: " + root_path)
        exit()
    if not os.path.exists(txtsavepath):
        os.makedirs(txtsavepath)
    trainval_percent = 0.9   # 训练验证集占比
    train_percent = 0.8      # 训练集占比
    total_xml = os.listdir(xmlfilepath)
    num = len(total_xml)
    tv = int(num * trainval_percent)
    tr = int(tv * train_percent)
    trainval = random.sample(range(num), tv)
    train = random.sample(trainval, tr)
    print("train and val size:", tv)
    print("train size:", tr)
    ftrainval = open(txtsavepath + '/trainval.txt', 'w')
    ftest = open(txtsavepath + '/test.txt', 'w')
    ftrain = open(txtsavepath + '/train.txt', 'w')
    fval = open(txtsavepath + '/val.txt', 'w')
    for i in range(num):
        name = total_xml[i][:-4] + '\n'
        if i in trainval:
            ftrainval.write(name)
            if i in train:
                ftrain.write(name)
            else:
                fval.write(name)
        else:
            ftest.write(name)
    ftrainval.close()
    ftrain.close()
    fval.close()
    ftest.close()

  4. 生成最终的txt文件和label文件夹(利用voc_label.py文件)

    文件来源于darknet下的scripts文件夹

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # file: voc_label.py
    # 生成最终的txt文件和label文件夹
    import xml.etree.ElementTree as ET
    import pickle
    import os
    from os import listdir, getcwd
    from os.path import join
    import platform
    ​
    sets = [('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
    classes = ["Bus", "Microbus", "Minivan", "Sedan", "SUV", "Truck"]
    ​
    ​
    def convert(size, box):
        dw = 1. / (size[0])
        dh = 1. / (size[1])
        x = (box[0] + box[1]) / 2.0 - 1
        y = (box[2] + box[3]) / 2.0 - 1
        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))
            print("Processing image:  %s" % image_id)
            convert_annotation(year, image_id)
        list_file.close()
    ​
    # if platform.system().lower() == 'windows':
    #     os.system("type 2007_train.txt 2007_val.txt > train.txt")
    #     os.system("type 2007_train.txt 2007_val.txt 2007_test.txt > train.all.txt")
    # elif platform.system().lower() == 'linux':
    #     os.system("cat 2007_train.txt 2007_val.txt > train.txt")
    #     os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt > train.all.txt")
    ​
    print("done")
  5. 复制2007_test.txt、2007_train.txt、2007_val.txt到data文件夹,搜索并复制darknet下的voc.data、voc.names到data文件夹

  6. 训练yolov4时,搜索并复制darknet下的yolov4.conv.137、yolov4-custom.cfg到data文件夹,若找不到,从网上下载

    训练yolov4-tiny时,搜索并复制darknet下的yolov4-tiny.conv.29、yolov4-tiny-custom.cfg到data文件夹,若找不到,从网上下载

    1. for yolov4.cfg, yolov4-custom.cfg (162 MB): yolov4.conv.137 (Google drive mirror yolov4.conv.137 )

    2. for yolov4-tiny.cfg, yolov4-tiny-3l.cfg, yolov4-tiny-custom.cfg (19 MB): yolov4-tiny.conv.29

    备注:关于文件放置的路径可以自己决定,只要知道对应的文件代表的意义,在后续的配置过程中,指定正确的路径即可

第三步:配置网络结构和训练参数

  1. xxx..names文件

    训练类别名称指定:voc.names

    替换为自己数据集的类别名称,一行一个,不要出现空行

  2. xxx.data文件

    数据路径文件指定:voc.data

    classes:指定类别个数

    train:指定训练数据集图片路径读取txt

    valid:指定验证数据集图片路径读取txt

    test:指定测试数据集图片路径读取txt

    names:指定了类别名称读取文件

    backup:指定训练权重保存文件路径

    例如:

    classes= 6
    train  = D:\DataSet\data/2007_train.txt
    valid  = D:\DataSet\data/2007_val.txt
    test = D:\DataSet\data/2007_test.txt
    names = D:\DataSet\data/voc.names
    backup = D:\DataSet\data/backup
  3. yoloxxx.cfg

    训练网络参数配置:yolov4-tiny-custom.cfg

    注意主要修改的几处:

    [net]:

    batch:批处理大小,显卡越强,此值可以设置高一点, 否则使用默认值,或适当降低

    subdivisions:每一批次分成多少等份

    [yolo]:

    classes:类别数

    anchors:预选框大小

    备注:yolov4有3个yolo层,需要改三处,yolov4-tiny有2个yolo层,需要改两处

    [convolutional]

    filters:每一yolo层之上对应有一个convolutional,此值为:(类别数classes+5)X 3,假如类别数为6,则该值为33

    备注:yolov4有3个yolo层,对应convolutional需要改三处,yolov4-tiny有2个yolo层,对应convolutional需要改两处

  4. yoloxxx.conv.xx

    yolov4的预训练权重文件:yolov4.conv.137

    yolov4-tiny的预训练权重文件:yolov4-tiny.conv.29

  5. 创建backup文件夹

    指定网络训练权重保存位置

第四步:训练

1、修改先验框

使用K-means算法计算最优先验框大小

darknet.exe detector calc_anchors data/obj.data -num_of_clusters 9 -width 416 -height 416

命令中data/obj.data为指定的xxx.data文件路径,数字9表示类别数目,例如:

D:\darknet\build\darknet\x64\darknet.exe detector calc_anchors data/voc.data -num_of_clusters 6 -width 416 -height 416

运行后会生成anchors.txt文件,复制文件内容,修改yoloxxx.cfg文件中的[yolo]下的anchors

2、启动训练命令

darknet.exe detector train data/obj.data yolo-obj.cfg yolov4.conv.137

命令中data/obj.data为指定的xxx.data文件路径,yolo-obj.cfg为指定的网络结构文件参数,yolov4.conv.137为预训练权重文件,例如:

D:\darknet\build\darknet\x64\darknet.exe detector train data/voc.data data/yolov4-tiny-custom.cfg data/yolov4-tiny.conv.29 -map

标签:文件,YOLOv4,训练,数据,train,yolov4,2007,txt,data
来源: https://blog.csdn.net/lishan132/article/details/121429644

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有