下载模型及权重文件

模型下载地址:https://github.com/pjreddie/darknet 权重下载地址:https://pjreddie.com/darknet/yolo/

安装

参考https://blog.csdn.net/uncle_ll/article/details/80830112
CPU版本

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

这里如果自己的电脑支持Openmp的话,也可以更改Makefile文件将其中的OPENMP的值更改为1,会加快训练和测试速度

GPU=0
CUDNN=0  
OPENCV=0
OPENMP=0 # 若电脑支持Openmp时,可以将其设置为1
DEBUG=0
ARCH= -gencode arch=compute_30,code=sm_30 
 -gencode arch=compute_35,code=sm_35 
 -gencode arch=compute_50,code=[sm_50,compute_50] 
 -gencode arch=compute_52,code=[sm_52,compute_52] \
 -gencode arch=compute_60,code=[sm_60,compute_60]
 # 这个地方是根据自己的GPU架构进行设置,不同架构的GPU的运算能力不一样,本文使用的是帕斯卡结构,查阅英伟达官网查看对应的计算能力为6.0
 # -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated? # This is what I use, uncomment if you know your arch and want to specify

ARCH= -gencode arch=compute_52,code=compute_52

VPATH=./src/:./examples
 SLIB=libdarknet.so
 ALIB=libdarknet.a
 EXEC=darknet
 OBJDIR=./obj/
 CC=gcc
 NVCC=nvcc # 这个地方若没有定义为环境变量,最好是使用绝对路径,大概位于/usr/local/cuda/bin/nvcc


数据形式介绍

1、数据分为图片和标注。二者为一一对应关系
2、标注可用LabelImg等标注软件生成

官方yolov4权重文件 yolov3权重文件_Image

数据导入及配套文件生成

1.在darknet目录下创建一个新文件夹

2.在该文件夹下创建两个文件夹分别存放图片和xml标注文件

3.生成train.txt、val.txt、test.txt以及将标注文件转成txt格式

我的脚本:https://github.com/yuace/yolo_python 4.记录类别名称的.names文件

官方yolov4权重文件 yolov3权重文件_官方yolov4权重文件_02

修改配置文件

1.修改cfg文件夹中的.data文件

官方yolov4权重文件 yolov3权重文件_Image_03


2.修改cfg文件夹中的.cfg文件

在[net]层修改batch大小及调整迭代步长;

官方yolov4权重文件 yolov3权重文件_权重_04


修改[yolo]层的classes,并将[yolo]层上一层的[convolutional]层的filters值按照如下公式修改:

filters = (classes + 5)*3

修改anchors,改为我们聚类的9个中心点

我的聚类脚本:https://github.com/yuace/yolo_python/blob/master/kmeans.py

官方yolov4权重文件 yolov3权重文件_权重_05


注意:如果classes = 20,则filters = 75。注意网络中一共有3个yolo层,因此上述步骤一共要修改3次

训练、验证、测试

1.训练:

./darknet  detector  train  cfg/xxx.data  cfg/yolov3.cfg  pretrained.weights

我们通常使用预训练权重来训练:

wget https://pjreddie.com/media/files/darknet53.conv.74//下载预训练
./darknet detector train cfg/xxx.data cfg/yolov3.cfg darknet53.conv.74

多gpu训练:

./darknet detector train cfg/xxx.data cfg/yolov3.cfg darknet53.conv.74 -gpus 0,1,2,3

如果中断,想继续训练,只需将预训练权重换成我们保存的权重即可。
2.验证:

./darknet  detector  recall  cfg/xxx.data  cfg/yolov3.cfg  trained.weights

3.测试:

./darknet  detector  test  cfg/xxx.data  cfg/yolov3.cfg  trained.weights  xxx.jpg

(注意:验证和测试时,将.cfg文件中的batch和subdivisions均改为1)

批量测试图片并保存在自定义文件夹下

参考:
1.用下面代码替换detector.c文件(example文件夹下)的void test_detector函数(注意有3处要改成自己的路径)

void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
    list *options = read_data_cfg(datacfg);
    char *name_list = option_find_str(options, "names", "data/names.list");
    char **names = get_labels(name_list);

image **alphabet = load_alphabet();
network *net = load_network(cfgfile, weightfile, 0);
set_batch_network(net, 1);
srand(2222222);
double time;
char buff[256];
char *input = buff;
float nms=.45;
int i=0;
while(1){
    if(filename){
        strncpy(input, filename, 256);
        image im = load_image_color(input,0,0);
        image sized = letterbox_image(im, net->w, net->h);
    //image sized = resize_image(im, net->w, net->h);
    //image sized2 = resize_max(im, net->w);
    //image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
    //resize_network(net, sized.w, sized.h);
        layer l = net->layers[net->n-1];


        float *X = sized.data;
        time=what_time_is_it_now();
        network_predict(net, X);
        printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);
        int nboxes = 0;
        detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
        //printf("%d\n", nboxes);
        //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
        if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
            draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
            free_detections(dets, nboxes);
        if(outfile)
         {
            save_image(im, outfile);
         }
        else{
            save_image(im, "predictions");
#ifdef OPENCV
 cvNamedWindow(“predictions”, CV_WINDOW_NORMAL);
 if(fullscreen){
 cvSetWindowProperty(“predictions”, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
 }
 show_image(im, “predictions”);
 cvWaitKey(0);
 cvDestroyAllWindows();
 #endif
 }
 free_image(im);
 free_image(sized);
 if (filename) break;
 }
 else {
 printf("Enter Image Path: ");
 fflush(stdout);
 input = fgets(input, 256, stdin);
 if(!input) return;
 strtok(input, “\n”);list *plist = get_paths(input);
        char **paths = (char **)list_to_array(plist);
         printf("Start Testing!\n");
        int m = plist->size;
        if(access("/home/xxxl/darknet/data/out",0)==-1)//"/home/xxx/darknet/data"修改成自己的路径
        {
          if (mkdir("/home/xxx/darknet/data/out",0777))//"/home/xxx/darknet/data"修改成自己的路径
           {
             printf("creat file bag failed!!!");
           }
        }
        for(i = 0; i < m; ++i){
         char *path = paths[i];
         image im = load_image_color(path,0,0);
         image sized = letterbox_image(im, net->w, net->h);
    //image sized = resize_image(im, net->w, net->h);
    //image sized2 = resize_max(im, net->w);
    //image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
    //resize_network(net, sized.w, sized.h);
    layer l = net->layers[net->n-1];


    float *X = sized.data;
    time=what_time_is_it_now();
    network_predict(net, X);
    printf("Try Very Hard:");
    printf("%s: Predicted in %f seconds.\n", path, what_time_is_it_now()-time);
    int nboxes = 0;
    detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
    //printf("%d\n", nboxes);
    //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
    if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
    draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
    free_detections(dets, nboxes);
    if(outfile){
        save_image(im, outfile);
    }
    else{
         
         char b[2048];
        sprintf(b,"/home/xxx/darknet/data/out/%s",GetFilename(path));//"/home/xxx/darknet/data"修改成自己的路径
        
        save_image(im, b);
        printf("save %s successfully!\n",GetFilename(path));
list *plist = get_paths(input);
        char **paths = (char **)list_to_array(plist);
         printf("Start Testing!\n");
        int m = plist->size;
        if(access("/home/xxxl/darknet/data/out",0)==-1)//"/home/xxx/darknet/data"修改成自己的路径
        {
          if (mkdir("/home/xxx/darknet/data/out",0777))//"/home/xxx/darknet/data"修改成自己的路径
           {
             printf("creat file bag failed!!!");
           }
        }
        for(i = 0; i < m; ++i){
         char *path = paths[i];
         image im = load_image_color(path,0,0);
         image sized = letterbox_image(im, net->w, net->h);
    //image sized = resize_image(im, net->w, net->h);
    //image sized2 = resize_max(im, net->w);
    //image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
    //resize_network(net, sized.w, sized.h);
    layer l = net->layers[net->n-1];


    float *X = sized.data;
    time=what_time_is_it_now();
    network_predict(net, X);
    printf("Try Very Hard:");
    printf("%s: Predicted in %f seconds.\n", path, what_time_is_it_now()-time);
    int nboxes = 0;
    detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
    //printf("%d\n", nboxes);
    //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
    if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
    draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
    free_detections(dets, nboxes);
    if(outfile){
        save_image(im, outfile);
    }
    else{
         
         char b[2048];
        sprintf(b,"/home/xxx/darknet/data/out/%s",GetFilename(path));//"/home/xxx/darknet/data"修改成自己的路径
        
        save_image(im, b);
        printf("save %s successfully!\n",GetFilename(path));
#ifdef OPENCV
 cvNamedWindow(“predictions”, CV_WINDOW_NORMAL);
 if(fullscreen){
 cvSetWindowProperty(“predictions”, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
 }
 show_image(im, “predictions”);
 cvWaitKey(0);
 cvDestroyAllWindows();
 #endif
 }
free_image(im);
    free_image(sized);
    if (filename) break;
    }
  }
}
char *GetFilename(char *p)
 {
 static char name[20]={""};
 char *q = strrchr(p,’/’) + 1;
 strncpy(name,q,6);//注意后面的6,如果你的测试集的图片的名字字符(不包括后缀)是其他长度,请改为你需要的长度(官方的默认的长度是6)
 return name;
 }


3.在darknet下重新make

make clean
make

4.执行批量测试命令会出现如下

Loading weights from yolov3.weights...Done!
Enter Image Path:

Enter Image Path:后面输入你的txt文件路径(你准备好的所有测试图片的路径全部存放在一个txt文件里),如下

/home/xxx/darknet/data/test.txt

之后就可以去自己的定义的out文件夹看结果了。