【深度学习】问题解决:YOLOv3 自动计算各个数据集中每个类别的数量

YOLOv3 自动计算各个数据集中每个类别的数量

虽然功能实现了,方法也很简单,但算不是最上层的方法。

步骤0:

已知:
进行批量测试的时候,使用./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights输出文本检测结果后,会在darknet/results文件夹中生成comp4_det_test_类名.txt(一个类别对应一个txt文件,有多少类别,就产生多少个txt文件)。

随便打开一个txt文件,里面的内容简单示例如下。每行都是一个目标。这样的话,看一下文件总共有多少行,就能得到这个类别对应的目标个数(直接打开每个类别的txt文件,鼠标点到最后一行,看一下右下角的行数)。

008681 0.999982 565.763733 1311.388672 633.671326 1377.522949
008683 0.999982 565.872070 1315.253906 635.104248 1377.797363
008690 0.999984 523.559265 1306.766113 585.476746 1366.243652
008692 0.999964 523.111206 1306.916748 586.848389 1367.439697
008705 0.999984 530.645020 1291.177368 596.593750 1356.693970
008724 0.999983 533.842834 1291.449829 603.227844 1355.802612

以下是darknet/example/detector.c中的validate_detector函数。如下第43行处的“comp4_det_test_“是最终生成的文件的前缀名,是哪个种类,后面就会加上种类名。

void validate_detector(char *datacfg, char *cfgfile, char *weightfile, char *outfile)
{
    int j;
    list *options = read_data_cfg(datacfg);
    char *valid_images = option_find_str(options, "valid", "data/test.list");
    char *name_list = option_find_str(options, "names", "data/names.list");
    char *prefix = option_find_str(options, "results", "results");
    char **names = get_labels(name_list);
    char *mapf = option_find_str(options, "map", 0);
    int *map = 0;
    if (mapf) map = read_map(mapf);

    network *net = load_network(cfgfile, weightfile, 0);
    set_batch_network(net, 1);
    fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay);
    srand(time(0));

    list *plist = get_paths(valid_images);
    char **paths = (char **)list_to_array(plist);

    layer l = net->layers[net->n-1];
    int classes = l.classes;

    char buff[1024];
    char *type = option_find_str(options, "eval", "voc");
    FILE *fp = 0;
    FILE **fps = 0;
    int coco = 0;
    int imagenet = 0;
    if(0==strcmp(type, "coco")){
        if(!outfile) outfile = "coco_results";
        snprintf(buff, 1024, "%s/%s.json", prefix, outfile);
        fp = fopen(buff, "w");
        fprintf(fp, "[\n");
        coco = 1;
    } else if(0==strcmp(type, "imagenet")){
        if(!outfile) outfile = "imagenet-detection";
        snprintf(buff, 1024, "%s/%s.txt", prefix, outfile);
        fp = fopen(buff, "w");
        imagenet = 1;
        classes = 200;
    } else {
        if(!outfile) outfile = "comp4_det_test_";
        fps = calloc(classes, sizeof(FILE *));
        for(j = 0; j < classes; ++j){
            snprintf(buff, 1024, "%s/%s%s.txt", prefix, outfile, names[j]);
            fps[j] = fopen(buff, "w");
        }
    }


    int m = plist->size;
    int i=0;
    int t;

    float thresh = .005;
    float nms = .45;

    int nthreads = 4;
    image *val = calloc(nthreads, sizeof(image));
    image *val_resized = calloc(nthreads, sizeof(image));
    image *buf = calloc(nthreads, sizeof(image));
    image *buf_resized = calloc(nthreads, sizeof(image));
    pthread_t *thr = calloc(nthreads, sizeof(pthread_t));

    load_args args = {0};
    args.w = net->w;
    args.h = net->h;
    //args.type = IMAGE_DATA;
    args.type = LETTERBOX_DATA;

    for(t = 0; t < nthreads; ++t){
        args.path = paths[i+t];
        args.im = &buf[t];
        args.resized = &buf_resized[t];
        thr[t] = load_data_in_thread(args);
    }
    double start = what_time_is_it_now();
    for(i = nthreads; i < m+nthreads; i += nthreads){
        fprintf(stderr, "%d\n", i);
        for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
            pthread_join(thr[t], 0);
            val[t] = buf[t];
            val_resized[t] = buf_resized[t];
        }
        for(t = 0; t < nthreads && i+t < m; ++t){
            args.path = paths[i+t];
            args.im = &buf[t];
            args.resized = &buf_resized[t];
            thr[t] = load_data_in_thread(args);
        }
        for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
            char *path = paths[i+t-nthreads];
            char *id = basecfg(path);
            float *X = val_resized[t].data;
            network_predict(net, X);
            int w = val[t].w;
            int h = val[t].h;
            int nboxes = 0;
            detection *dets = get_network_boxes(net, w, h, thresh, .5, map, 0, &nboxes);
            if (nms) do_nms_sort(dets, nboxes, classes, nms);
            if (coco){
                print_cocos(fp, path, dets, nboxes, classes, w, h);
            } else if (imagenet){
                print_imagenet_detections(fp, i+t-nthreads+1, dets, nboxes, classes, w, h);
            } else {
                print_detector_detections(fps, id, dets, nboxes, classes, w, h);
            }
            free_detections(dets, nboxes);
            free(id);
            free_image(val[t]);
            free_image(val_resized[t]);
        }
    }
    for(j = 0; j < classes; ++j){
        if(fps) fclose(fps[j]);
    }
    if(coco){
        fseek(fp, -2, SEEK_CUR); 
        fprintf(fp, "\n]\n");
        fclose(fp);
    }
    fprintf(stderr, "Total Detection Time: %f Seconds\n", what_time_is_it_now() - start);
}

步骤1:

将上述函数(darknet/example/detector.c中的validate_detector函数)中的comp4_det_test_改成comp4_det_train_,重新编译:

在darknet文件夹下打开一个终端窗口,输入:

make clean //清除已生成的编译文件
make -j8 //重新编译 -j8是为了加速

编译完成后,此时,(接下来这个过程不需要做)再次运行命令./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights,会在results文件夹下产生文件名为“comp4_det_train_+类别名称“的文件。

步骤2:

以将darknet/scripts中的2007_test.txt重命名为2007_test原来的.txt,将2007_train.txt重命名为2007_test.txt
darknet/scripts/VOCdevkit/VOC2007/ImageSets/Main中的test.txt重命名为test原来的.txt,将train.txt重命名为test.txt
完成这两步修改后,就可以运行命令:

./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights

会在results文件夹下产生文件名为“comp4_det_train_+类别名称“的文件。

挨个打开它们,统计行数即可~

你可能感兴趣的:(深度学习目标检测算法,深度学习,ubuntu)