YOLO v3 中的darknet.c主程序的个人笔记

一.main函数

int main(int argc, char **argv)
{
    //test_resize("data/bad.jpg");
    //test_box();
    //test_convolutional_layer();
    if(argc < 2){
        fprintf(stderr, "usage: %s \n", argv[0]);
        return 0;
    }
    gpu_index = find_int_arg(argc, argv, "-i", 0);
    if(find_arg(argc, argv, "-nogpu")) {
        gpu_index = -1;
    }

#ifndef GPU
    gpu_index = -1;
#else
    if(gpu_index >= 0){
        cuda_set_device(gpu_index);
    }
#endif

    if (0 == strcmp(argv[1], "average")){
        average(argc, argv);
    } else if (0 == strcmp(argv[1], "detector")){
        run_detector(argc, argv);
    } else if (0 == strcmp(argv[1], "detect")){
        float thresh = find_float_arg(argc, argv, "-thresh", .5);
        char *filename = (argc > 4) ? argv[4]: 0;
        char *outfile = find_char_arg(argc, argv, "-out", 0);
        int fullscreen = find_arg(argc, argv, "-fullscreen");
        test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);
    }
    return 0;
}

暂时的程序笔记.

关于主函数

1.如果程序运行时发送给main函数的命令行参数小于2,显示标准错误.

2.调用cudaSetDevice函数设置当前活跃的GPU卡号

3.若argv[1] = "detector",则转向run_detector( ),并将输入参数传递给run_detector( ),run_detector( )根据argv[2]的值,转向test或train等detector函数.

关于detector.c

1.图像检测网络训练函数(针对图像检测的网络训练)

输入:

datacfg:训练数据描述信息文件的名称和路径

cfgfile:神经网络结构配置文件的名称和路径

weightfile:预训练参数文件的名称和路径

ngpus:使用GPUS块数,使用一块或者不使用时,ngpus都等于1.

gpus:GPU卡号集合(比如使用1块gpu,那么里面只含0元素,默认使用0卡号gpu;如果使用4块gpu,那么含有0,1,2,3四个元素.若是不使用gpu,那么为空.)

 

train_detector( )

argv[2] = train,进人函数.

list *options = read_data_cfg(datacfg);
char *train_images = option_find_str(options, "train", "data/train.list");
char *backup_directory = option_find_str(options, "backup", "/backup/");

 

  • 从options找出训练图片路径信息,如果没找到,默认使用"data/train.list"路径下的图片信息(train.list含有标准的信息格式: )(就是标签存储地么?
  • 该文件可以由darknet提供的scripts/voc_label.py根据自行在网上下载的voc数据集生成,所以说是默认路径,其实也需要使用者自行调整,也可以任意命名,不一定要为train.list
  • 甚至可以不用voc_label.py生成,可以自己不厌其烦的制作一个(当然规模应该是很小的,不然太累了。。。)
  • 读入后,train_images将含有训练图片中所有图片的标签以及定位信息 (标签,类,坐标和高宽?

 

 char *base = basecfg(cfgfile);
 printf("%s\n", base);
 float avg_loss = -1;
 network **nets = calloc(ngpus, sizeof(network));

 

  • 提取配置文件名称中的主要信息用于输出打印,如:cfg/yolo.cfg中的yolo
  • 构建网络,用多少块GPU,就会构建多少个相同的网络

 

 

 

 

#ifdef GPU
        cuda_set_device(gpus[i]);
#endif
        nets[i] = load_network(cfgfile, weightfile, clear);
        nets[i]->learning_rate *= ngpus;

 

设置当前活跃GPU卡号(即设置gpu_index=n,同时调用cudaSetDevice函数设置当前活跃的GPU卡号)

 

imgs是一次加载到内存的图像数量

如果占内存太大的话,可以把subdivision调大或者调小一点

这样一来,一次加载imgs张图片到内存,while循环每次count,就出处理完这些图片,完成一次迭代

 

非均衡数据集处理:利用抖动(jittering)生成额外数据.

    args.n = imgs;//n就是一次加载到内存中的图片数量
    args.m = plist->size;//m是待训练图片的总数量

 

while(get_current_batch(net) < net.max_batches){

        /*进行10次迭代后,调整一次网络大小
        resize网络是yolo v2版本新加的功能。
        即每进行10次迭代就会resize一次网络输入图片的宽和高,
        这样保证了网络可以试音各种不同尺度的目标,
        这样以来,即使没有dropout层,
        训练出来的网络也不会过拟合*/
        if(l.random && count++%10 == 0){
            printf("Resizing\n");
            int dim = (rand() % 10 + 10) * 32;
            if (get_current_batch(net)+200 > net.max_batches) dim = 608;
            //int dim = (rand() % 4 + 16) * 32;
            printf("%d\n", dim);

            //网络输入图片的宽高可调节,dim最小为320,
            // 最大为618,这样可以更好使用多尺度的目标

            args.w = dim;
            args.h = dim;
#ifdef GPU
        if(ngpus == 1){
            loss = train_network(net, train);//开始训练
        } else {
            loss = train_networks(nets, ngpus, train, 4);
        }
#else
        loss = train_network(net, train);
#endif

 

 

1.Main函数中参数argc,argv说明

2.C语言中的fprintf函数

  • stderr和stdout详细解说

 

yolo v3论文

你可能感兴趣的:(open,cv,yolo)