Darknet 最新教程 批量测试

Darknet 最新教程 批量测试 Ubuntu

  • 环境配置
  • 训练模型
  • 批量测试图片

由于Darknet官方代码不断更新,但是CSDN上教程和批量测试代码没有及时更新,导致各种编译错误,本文针对2021年8月18日的Darknet官方代码作教程!

环境配置

从Darknet官方下载代码,找到里面的Makefile文件,用记事本打开。默认大家都有GPU、CUDA和CUDNN,将其中的GPUCUDNN设置为1。如果电脑安装了OPENCV,就将OPENCV设置为1
Darknet 最新教程 批量测试_第1张图片
如果你不确定你的电脑是否有OPENCV,就先设置成1编译,如果编译报错,就把OPENCV再改回0就是了。直接在darknet文件夹内打开终端,输入make开始编译。

(base) user@name: ~/darknet-master$: make

编译没有出错,并且daknet文件夹里面多了个darknet,命令行输入./darknet,它有反应,并且回复你usage: ./darknet ,那么恭喜你,darknet环境配置好了。

(base) user@name: ~/darknet-master$: ./darknet
usage: ./darknet 

训练模型

在自己的数据集上训练模型,先给自己创个文件夹吧,命名my_project行吧。然后把你所有的图片数据、标注文件放在这个my_project文件夹里面。请把图片数据img和标注文件xml分开放,像下面这样

my_project
	|———— xml
	|      |————picture0.xml
	|      |————picture1.xml
	|       ……
	|———— img
	       |————picture0.jpg
	       |————picture1.jpg
	        ……

图片数据img就是你想要训练的图片,标注文件xml就是通过labelimg画框后保存的.xml文件,一张图img一个标注xml文件,一一对应!
下一步,把这个process.py脚本文件给我复制保存到my_project文件夹里面!

import os
import random

train_percent = 0.85  # 按比例划分训练集
val_percent = 0.15    # 按比例划分验证集
xmlfilepath = './xml/'
txtsavepath = './img/'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)     
list = range(num)
train = random.sample(list, int(num * train_percent))
val = random.sample(list, int(num * val_percent))

ftest = open('./test.txt', 'w')   # 会生成一个test.txt文件用于当测试集
ftrain = open('./train.txt', 'w') # 会生成一个train.txt文件用于当训练集
fval = open('./val.txt', 'w')     # 会生成一个val.txt文件用于当验证集

for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in train:
        ftrain.write(name)
    else:
        ftest.write(name)
    if i in val:
        fval.write(name)

ftrain.close()
fval.close()
ftest.close()

这个process.py脚本运行一下,process.py文件夹里会多3个文件,test.txttrain.txtval.txt,里面的内容只不过是把你的数据集分成三个类而已。
再下一步,把这个convert.py脚本文件给我复制保存到my_project文件夹里面!

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
 
sets=[('my_project', 'train')]  
sets2=[('my_project', 'test')]
 
classes = ["class1", "class2"]   # 你的数据集类别
 
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('./xml/%s.xml'%(image_id))  
    out_file = open('./img/%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')

 
for year, image_set in sets:
    image_ids = open('./%s.txt'%(image_set)).read().strip().split()
    list_file = open('./%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('./my_project/img/%s.jpg\n'%(image_id))
        convert_annotation(year, image_id)
    list_file.close()

for year2, image_set2 in sets2:    
    image_ids2 = open('./%s.txt'%(image_set2)).read().strip().split()
    test_file = open('./%s_%s.txt'%(year2, image_set2), 'w')
    for image_id2 in image_ids2:
        test_file.write('./my_project/img/%s.jpg\n'%(image_id2))
        convert_annotation(year2, image_id2)
    test_file.close()

这个convert.py文件运行后,会生成my_project_train.txtmy_project_test.txt。这个脚本的功能就是通过test.txttrain.txtval.txt的内容,整理训练图片路径,到时候训练的时候就需要用到这个my_project_train.txt
再下一步,你需要一个.names文件,也把他放在my_project文件夹里,你可以命名为my_project.names,里面的内容是你数据集的类别名:
Darknet 最新教程 批量测试_第2张图片
再下一步,你需要创建一个weights文件夹存放你训练保存的模型文件。你还需要一个.data文件,也把他放在my_project文件夹里,你可以命名为my_project.data,里面的内容是下面这样,最好请使用绝对路径:
Darknet 最新教程 批量测试_第3张图片
到此为止,你的my_project文件夹里面应该长这样:

my_project
	|———— xml
	|      |————picture0.xml
	|      |————picture1.xml
	|       ……
	|———— img
	|      |————picture0.jpg
	|      |————picture1.jpg
	|       ……
	|———— weights
	|———— process.py
	|———— convert.py
	|———— train.txt
	|———— test.txt
    |———— val.txt
    |———— my_project_train.txt
    |———— my_project_test.txt
    |———— my_project.names
    |———— my_project.data

接下来就到修改cfg文件啦!找到darknet-master/cfg文件夹里面,这里面有非常多的cfg可以使用,选择一个你喜欢的模型,跟着我修改里面的数据!例如我选的yolov3-tiny.cfg
把里面Testing的注释掉,Training的取消注释
Darknet 最新教程 批量测试_第4张图片
里面的一些参数到底是干什么的,表示什么,请去搜一搜别的CSDN博客吧~这里只介绍一下max_batches是你训练迭代的epoch,step的话有两个数组成,前一个数可以改为max_batches×0.8,后一个数可以改为max_batches×0.9。如果CUDA报错out of memory就把subdivisions值调大,但是得是2的幂,一般8就行。
然后修改网络参数,找到[yolo]classes和你的数据集对应,把上面的filters改成(classes+5)×3
Darknet 最新教程 批量测试_第5张图片
比如你是两个类的,那就classes=2filters=21
然后就是最后一步了!在命令行输入下面的代码开始训练!

(base) user@name: ~/darknet-master$: ./darknet detector train my_project/my_project.data cfg/yolov3-tiny.cfg -gpus 0

等着被训练数据刷屏就是了。模型最后会保存在weights文件夹里面。

批量测试图片

这是最简单的批量测试图片代码,直接将darknet-master/src/detecor.c里面的test_detecot函数全部替换成下面这样,再改个保存路径,重新make就好了!

void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, int dont_show, int ext_output, int save_labels, char *outfile, int letter_box,int benchmark_layers)
{
    list *options = read_data_cfg(datacfg);
    char *name_list = option_find_str(options, "names", "data/names.list");
    int names_size = 0;
    char **names = get_labels_custom(name_list, &names_size); //get_labels(name_list);
 
    image **alphabet = load_alphabet();
    network net = parse_network_cfg_custom(cfgfile, 1, 1); // set batch=1
    if (weightfile) {
        load_weights(&net, weightfile);
    }
    net.benchmark_layers = benchmark_layers;
    fuse_conv_batchnorm(net);
    calculate_binary_weights(net);
    if (net.layers[net.n - 1].classes != names_size) {
        printf(" Error: in the file %s number of names %d that isn't equal to classes=%d in the file %s \n",
            name_list, names_size, net.layers[net.n - 1].classes, cfgfile);
        if (net.layers[net.n - 1].classes > names_size) getchar();
    }
    srand(2222222);
    double time;
    char buff[256];
    char *input = buff;
    char *json_buf = NULL;
    int json_image_id = 0;
    FILE* json_file = NULL;
    if (outfile) {
        json_file = fopen(outfile, "wb");
        char *tmp = "[\n";
        fwrite(tmp, sizeof(char), strlen(tmp), json_file);
    }
    int j,i;
    float nms = .45;    // 0.4F
    if (filename) {
        strncpy(input, filename, 256);
        list *plist = get_paths(input);
	char **paths = (char **)list_to_array(plist);
	printf("Start Testing!\n");
	int m = plist->size;
 
	for(i=0;i thresh && dets[i].prob[j] > prob) {
                            prob = dets[i].prob[j];
                            class_id = j;
                        }
                    }
                    if (class_id >= 0) {
                        sprintf(buff, "%d %2.4f %2.4f %2.4f %2.4f\n", class_id, dets[i].bbox.x, dets[i].bbox.y, dets[i].bbox.w, dets[i].bbox.h);
                        fwrite(buff, sizeof(char), strlen(buff), fw);
                    }
                  }
                fclose(fw);
            }
 
            free_detections(dets, nboxes);
            free_image(im);
            free_image(sized);
	}
    }
    printf("All Done!\n");
    pause();
    exit(0);
    free_ptrs(names, net.layers[net.n - 1].classes);
    free_list_contents_kvp(options);
    free_list(options);
 
    const int nsize = 8;
    for (j = 0; j < nsize; ++j) {
	for (i = 32; i < 127; ++i) {
            free_image(alphabet[j][i]);
	}
	free(alphabet[j]);
    }
 
    free(alphabet);
    free_network(net);
    printf("All Done!\n");
    pause();
}

记得重新make不然改了没用

(base) user@name: ~/darknet-master$: make

然后测试图片的指令是

(base) user@name: ~/darknet-master$: ./darknet detector test my_project/my_project.data cfg/yolov3-tiny.cfg my_project/weights/你的模型.weights my_project/my_project_test.txt

你可能感兴趣的:(深度学习)