zoukankan      html  css  js  c++  java
  • Ubuntu16+GPU环境训练yolov3-tiny

    参考链接:https://www.cnblogs.com/xieqi/p/9818056.html

    参考链接:https://www.cnblogs.com/shuiyj/p/13185303.html

     参考链接:YOLOV3中Darknet中cfg文件说明和理解:https://www.cnblogs.com/hls91/p/10911997.html

    辛辛苦苦搭载好GPU环境,环境搭载参考这个

    现在要开始测试下效果

    参考链接:https://pjreddie.com/darknet/yolo/

    一,测试

    (1),如果尚未安装Darknet,则应先进行安装

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

    您已经在cfg/子目录中拥有YOLO的配置文件您将必须在此处下载预训练重量文件(237 MB)或只是运行此:

    wget https://pjreddie.com/media/files/yolov3.weights

    然后运行检测器!

    ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

    你将看到以下输出:

    layer     filters    size              input                output
        0 conv     32  3 x 3 / 1   416 x 416 x   3   ->   416 x 416 x  32  0.299 BFLOPs
        1 conv     64  3 x 3 / 2   416 x 416 x  32   ->   208 x 208 x  64  1.595 BFLOPs
        .......
      105 conv    255  1 x 1 / 1    52 x  52 x 256   ->    52 x  52 x 255  0.353 BFLOPs
      106 detection
    truth_thresh: Using default '1.000000'
    Loading weights from yolov3.weights...Done!
    data/dog.jpg: Predicted in 0.029329 seconds.
    dog: 99%
    truck: 93%
    bicycle: 99%

    这说明没有问题。

    (2)更改检测阈值

    默认情况下,YOLO仅显示置信度为.25或更高的对象。您可以通过将-thresh <val>标志传递yolo命令来更改此设置例如,要显示所有检测,可以将阈值设置为0:

    ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg -thresh 0

    (3) 训练YOLO VOC

    要培训YOLO,您需要2007年至2012年的所有VOC数据。(如果你和我一样用自己的数据训练yolo,则不需要下面这一步)

    要获取所有数据,请创建一个目录以存储所有数据,然后从该目录运行:

    wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar
    wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar
    wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar
    tar xf VOCtrainval_11-May-2012.tar
    tar xf VOCtrainval_06-Nov-2007.tar
    tar xf VOCtest_06-Nov-2007.tar

    现在将有一个VOCdevkit/子目录,其中包含所有VOC培训数据。

    生成VOC标签

    现在我们需要生成Darknet使用的标签文件。Darknet希望.txt为每个图像提供一个文件,并在图像中为每个地面真实对象添加一行,如下所示:

    <object-class> <x> <y> <width> <height>

    下载预训练的卷积权重(用自己的数据训练则可以不需要这一步)

    为了进行训练,我们使用在Imagenet上预先训练的卷积权重。我们使用darknet53模型的权重您可以在此处下载卷积层的权重(76 MB)。也可以自行选择其他权重文件。

    wget https://pjreddie.com/media/files/darknet53.conv.74

    训练模型

    现在我们可以训练!运行命令(官方指导文件中命令):

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

     这上面基本上都是参考链接中有的,我把要用到的重要步骤给翻译整理了一下。

    二,训练自己的数据

    (1),标注图像

    在标注前可以使用脚本对图像进行重命名,参考链接:https://www.cnblogs.com/gezhuangzhuang/p/10539792.html

    推荐使用labelimg工具进行标注,参考我的博文链接:https://www.cnblogs.com/vincent212212/p/13262109.html

    (2),制作数据集

    我们可以仿照VOCdevkit的格式存储我们标注的xml文件和图像。

    例如,建立traindata数据集文件夹,将VOCdevkit复制到traindata下,并且在traindata文件夹下添加voc_label.py脚本,参考如下:(你可以修改为自己的classes)

    import xml.etree.ElementTree as ET
    import pickle
    import os
    from os import listdir, getcwd
    from os.path import join
    
    sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
    
    classes = ["corner","tcorner","crosscorner"]
    
    
    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]) + '
    ')
    
    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
    '%(wd, year, image_id))
            convert_annotation(year, image_id)
        list_file.close()
    
    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")

    在VOCdevkit中建立VOC2007中添加test.py脚本,内容如下,仅供参考(你可以修改分配比例和文件路径)

    import os
    import random
    
    trainval_percent = 0.3
    train_percent = 0.7
    xmlfilepath = 'Annotations'
    txtsavepath = 'ImageSetsMain'
    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] + '
    '
        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()

    将自己标注的xml文件放到Annotations文件夹下,将图像放到JPEGImages文件夹下。

    1,cd到VOC2007下,运行test.py

    先运行这个脚本将Annotations里的xml文件随机的分发到对应文件夹里,分发到比例是可以改的。

    2,然后cd到traindata下,运行voc_label.py

    这几个py文件都比较好理解,可以稍微看一下代码

    运行完之后会得到2007_train.txt,2007_test.txt等txt文件。

    3,修改Cfg以获取Pascal数据,(不要在windows环境中修改)

    在cfg文件夹中的voc.data中,下面以我的路径举例

      1 classes= 3
      2 train  = /home/.../mydarknet/darknet/traindata/train.txt
      3 valid  =/home/.../mydarknet/darknet/traindata/2007_test.txt 
    4 names =/home/.../mydarknet/darknet/traindata/voc.names
    5 backup =/home/.../mydarknet/darknetbackup

     4,修改cfg文件夹下的voc.names文件,(不要在windows环境中修改)

    修改为自己分类的class名字。

    比如,我这里改为:

    corner
    tcorner
    crosscorner

    5,修改cfg文件夹下的yolov3-tiny.cfg文件,如下是我的cfg文件,供大家参考(不要在windows环境中修改)

    [net]
    # Testing
    #batch=1
    #subdivisions=1
    # Training
    batch=32
    subdivisions=2
    
    width=416
    height=416
    channels=3
    momentum=0.9
    decay=0.0005
    angle=0
    saturation = 1.5
    exposure = 1.5
    hue=.1
    tee result/log/training.log
    learning_rate=0.001
    burn_in=1000
    max_batches = 240000 # 5200000
    policy=steps
    steps=400000,450000
    scales=.1,.1
    
    [convolutional]
    batch_normalize=1
    filters=16
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=32
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=64
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=128
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=512
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=1
    
    [convolutional]
    batch_normalize=1
    filters=1024
    size=3
    stride=1
    pad=1
    activation=leaky
    
    ###########
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=1
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    batch_normalize=1
    filters=512
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    size=1
    stride=1
    pad=1
    filters=24 # (class+5)*3
    activation=linear
    
    
    
    [yolo]
    mask = 3,4,5
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes=3
    num=6
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1
    
    [route]
    layers = -4
    
    [convolutional]
    batch_normalize=1
    filters=128
    size=1
    stride=1
    pad=1
    activation=leaky
    
    [upsample]
    stride=2
    
    [route]
    layers = -1, 8
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    size=1
    stride=1
    pad=1
    filters=24 # (class+5)*3
    activation=linear
    
    [yolo]
    mask = 0,1,2
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes= 3 
    num=6
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1

    几点注意:

    1,训练时注销掉testing(前面添加#),同理测试时注销掉training

    # Testing
    #batch=1
    #subdivisions=1

    2,yolotiny训练过程中有两个输出层,要将输出层之前的卷积滤波修改为自己合适的,例如

    filters=24 # (class+5)*3

    3,在两个输出层中要把class改成合适自己的,例如,我的训练分为三类,我就改为了3

    (3),开始训练

    训练指令:./darknet detector train <data_cfg> <model_cfg> <weights> -gpus <gpu_list> 

    我的训练命令如下,(文件路径可修改为自己的)

    ./darknet detector train mycfg/voc.data mycfg/yolov3-tiny.cfg yolov3-tiny.conv.15



    如果需要生成loss-iter曲线,在执行训练命令的时候加一下管道,tee一下log:命令如下:
    ./darknet detector train mycfg/voc.data mycfg/yolov3-tiny.cfg yolov3-tiny.conv.15 | tee result/log/training.log

    生成的training文件需要绘制曲线的话,可以参考此链接的脚本:https://blog.csdn.net/qq_34806812/article/details/81459982

    3,补充注意事项

     1,在mycfg中的yolov3-tiny.cfg文件中,可以修改训练参数。

    比如中的max_batches = 250000,表示最大训练步数,可以自己修改。

    还可以把training下面的batch改小一点,以免报错,我这里batch=32.

    2,训练中,在mycfg中的yolov3-tiny.cfg文件中,testing下面的batch和subdivisions前面要加#号注释掉。training下面的两项要保留。

    测试时,在mycfg中的yolov3-tiny.cfg文件中,training下面的batch和subdivisions前面要加#号注释掉。testing下面的两项要保留。

    3,在不同的环境下,还要更改darknet中的makefile文件配置,例如,用的GPU训练,可以参考如下配置。

    makefile中的配置如下。

    GPU=1

    CUDNN=1

    OPENCV=1

    OPENMP=1

    DEBUG=0

    4,如果在训练中出现无法找到训练文件的情况,Couldn't open file: train.txt

    很有可能是你的文件格式不对,很可能是因为你在windows环境下修改了这些文件。

    请检查生成的几个txt文件的格式,检查方法参考链接:https://liumin.blog.csdn.net/article/details/99687482

    如果txt文件没问题,请检查voc.data,cfg等文件内容格式是否有问题。

     5,训练的过程中,出现部分nan是正常的,但是全部是nan的话,就是你的数据集的问题了。

    6,训练过程中,什么时候训练的可以了,可以关注avg指标,训练收敛后,一般会降低到0.1一下。

    不断更新ing

  • 相关阅读:
    DECLARE
    deallocvt
    科研院所
    jQuery Ajax 确定 form 表单 submit 提交成功
    Java实现 LeetCode 10 正则表达式匹配
    Java实现 LeetCode 10 正则表达式匹配
    Java实现 LeetCode 9 回文数
    Java实现 LeetCode 9 回文数
    Java实现 LeetCode 9 回文数
    Java实现 LeetCode 8 字符串转换整数(atoi)
  • 原文地址:https://www.cnblogs.com/vincent212212/p/13164194.html
Copyright © 2011-2022 走看看