yolo训练精简版

在darknet版的yoloV4中。data文件中train.txt中只提供了图像的路径,那标签文件是怎么对应读取的呢?

在源码中,找到下面这个函数可以看到:

void replace_image_to_label(const char* input_path, char* output_path)
{
    find_replace(input_path, "/images/train2014/", "/labels/train2014/", output_path);    // COCO
    find_replace(output_path, "/images/val2014/", "/labels/val2014/", output_path);        // COCO
    find_replace(output_path, "/JPEGImages/", "/labels/", output_path);    // PascalVOC
    find_replace(output_path, "\\images\\train2014\\", "\\labels\\train2014\\", output_path);    // COCO
    find_replace(output_path, "\\images\\val2014\\", "\\labels\\val2014\\", output_path);        // COCO
    find_replace(output_path, "\\JPEGImages\\", "\\labels\\", output_path);    // PascalVOC
    //find_replace(output_path, "/images/", "/labels/", output_path);    // COCO
    //find_replace(output_path, "/VOC2007/JPEGImages/", "/VOC2007/labels/", output_path);        // PascalVOC
    //find_replace(output_path, "/VOC2012/JPEGImages/", "/VOC2012/labels/", output_path);        // PascalVOC

    //find_replace(output_path, "/raw/", "/labels/", output_path);
    trim(output_path);

    // replace only ext of files
    find_replace_extension(output_path, ".jpg", ".txt", output_path);
    find_replace_extension(output_path, ".JPG", ".txt", output_path); // error
    find_replace_extension(output_path, ".jpeg", ".txt", output_path);
    find_replace_extension(output_path, ".JPEG", ".txt", output_path);
    find_replace_extension(output_path, ".png", ".txt", output_path);
    find_replace_extension(output_path, ".PNG", ".txt", output_path);
    find_replace_extension(output_path, ".bmp", ".txt", output_path);
    find_replace_extension(output_path, ".BMP", ".txt", output_path);
    find_replace_extension(output_path, ".ppm", ".txt", output_path);
    find_replace_extension(output_path, ".PPM", ".txt", output_path);
    find_replace_extension(output_path, ".tiff", ".txt", output_path);
    find_replace_extension(output_path, ".TIFF", ".txt", output_path);

    // Check file ends with txt:
    if(strlen(output_path) > 4) {
        char *output_path_ext = output_path + strlen(output_path) - 4;
        if( strcmp(".txt", output_path_ext) != 0){
            fprintf(stderr, "Failed to infer label file name (check image extension is supported): %s \n", output_path);
        }
    }else{
        fprintf(stderr, "Label file name is too short: %s \n", output_path);
    }
}

以PascalVOC数据集为例,程序会自动把图像路径中的/JPEGImages/ 替换为 /labels/
然后把文件扩展名替换为txt 就得到对应的标签文件路径了

所以我们在任一路径下可以新建两个文件夹


-JPEGImages   #放入所有的训练图片文件
-labels   #放入所有的txt文件,会自动生成此文件夹

后来想想,只要得到图像的全路径就可以,文件夹都不用创建,标签文件也不用分开,直接放在一个文件夹,执行下面的程序,会自动给你划分出训练集和验证集,更简单!

执行下面的Python程序

import os

# iter floder
def iter_files(rootDir, extend_name):
    file_list = []
    fileName = []
    #Iterate over the roots
    for root,dirs,files in os.walk(rootDir):
        for file_name in files:
            root = os.path.normpath(root) #格式化路径 斜杠问题  / -> \
            file_path = os.path.join(root, file_name)  # 连接路径
            file_path = file_path.replace("\\", "/")
            flag = file_path.endswith(extend_name)
            if flag:
                file_list.append(file_path)
                fileName.append(os.path.splitext(file_name)[0])

    return file_list, fileName

# split train and val
def  split_train_val(fileList):
    trainFile = open('train.txt', 'a')
    validFile = open('val.txt', 'a')
    num = 0
    for files in fileList:
        num = num + 1
        if num % 4 == 0:
            validFile.write(files + '\n')
        else:
            trainFile.write(files + '\n')
    trainFile.close()
    validFile.close()

if __name__ == '__main__':

    root = 'D:/Python/images/JEPGImages'  #训练图像的路径
    [fileList, fileName] = iter_files(root, 'png')
    split_train_val(fileList)

这样我们就直接得到了训练集和验证集的txt文件,前提是你直接有txt格式的标注文件,不是xml的。不然还是需要之前的那篇教程。

后面就简简单单改几个地方,就能训练起来了!

新建obj.names

复制data目录下的voc.name,改为obj.name,里面写标签的名字,每行一个

新建obj.data

复制cfg文件夹下的voc.data,重命名为obj.data

classes= 1				# 类别的数量	
train  = train.txt 	# 上一步生成的train.txt的相对路径或绝对路径		
valid  = val.txt		# 上一步生成的val.txt的相对路径或绝对路径		
names = data/obj.names		# 保存的类别标签		
backup = backup/	 # 权重保存的位置

修改cfg文件


把第三行batch改为batch=64

把subdivisions那一行改为 subdivisions=16

将max_batch更改为(数据集标签种类数(classes)*2000 但不小于训练的图片数量以及不小于6000)

将第20的steps改为max_batch的0.8倍和0.9倍

把位于8-9行设为width=416 height=416 或者其他32的倍数:

将classes=80 改为你的类别数 (有三个地方,969行,1056行,1143行)

改正[filters=255]filters=(classes + 5)x3 (位置为查找yolo,每个yolo前的[convolutional]里,注意只修改最接近yolo的那个filters需要修改,一共应该有三处)

如果使用 [Gaussian_yolo] 层,修改 filters=(classes + 9)x3 (位置为CRRL+F查找Gaussian_yolo,每个Gaussian_yolo前的[convolutional]里,注意只修改最接近Gaussian_yolo的那个filters需要修改,一共应该有三处)

训练数据

开始训练

yolov4.conv.137为预训练权重,没有的话会随机初始化权重
预训练权重,密码:jirs

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

mAP(均值平均精度) = 所有类别的平均精度求和除以所有类别

每4个Epochs计算一次map

训练生成的权重文件在<backup>目录下:

last_weights 每迭代100次保存一次
xxxx_weights 每迭代1000次保存一席

继续训练

每迭代100步可以手动停止,下次训练加载此次的权重文件便可以接着训练。
eg:从2000步停止训练后,可以使用如下命令继续训练

darknet.exe detector train data/obj.data yolo-obj.cfg backup\yolo-obj_2000.weights

停止训练

停止训练的条件:

训练过程中如果 avg出现nan,训练可能出错,需要停止

如果nan出现在其他行,训练正常

如果迭代很多次后avg补再下降,需要停止

avg越低越好—,也要防止过拟合

对小的模型、简单的数据集,avg一般为0.05

对大的模型、复杂的数据集,avg一般为3
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210626103746201.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NodWFpamllZXI=,size_16,color_FFFFFF,t_70)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值