yolov3源码阅读(一)从main开始到加载解析模型相关参数
yolov3源码阅读(一) 从main开始到加载解析模型相关参数
主函数main() 在examples下面的Darknet.c文件下
打开该文件,开启源码阅读之路
以训练模型输入为例
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23
- 1
在终端输入上述指令时,运行main()
./darknet 是执行当前文件下面已经编译好的darknet文件
int main(int argc, char **argv)
- 1
Linux操作系统中C/C++的main函数标准写法。
argc和argv参数在用命令行编译程序时有用。
第一个参数,int型的argc,为整型,用来统计程序运行时发送给main函数的命令行参数的个数
第二个参数,char*型的argv[],为字符串数组,用来存放指向的字符串参数的指针数组
即
argv[0]=darknet
argv[1]=detector
argv[2]=train
argv[3]=cfg/voc.data
argv[4]=cfg/yolo-voc.cfg
argv[5]=darknet19_448.conv.23
- 1
- 2
- 3
- 4
- 5
- 6
继续看
if(argc < 2){//如果参数小于2
fprintf(stderr, "usage: %s <function>\n", argv[0]);//在屏幕打印
return 0;
}
- 1
- 2
- 3
- 4
参数不对时打印相关信息
gpu_index = find_int_arg(argc, argv, "-i", 0);//多GPU时指定参与训练的GPU编号
if(find_arg(argc, argv, "-nogpu")) {//设置无gpu格式
gpu_index = -1;
}
- 1
- 2
- 3
- 4
根据指令 决定gpu_index的值是多少。当没有相关设置时gpu_index=0。
#ifndef GPU //makefile中的配置
gpu_index = -1; //不用GPU 值为 -1 不配置cuda
#else
if(gpu_index >= 0){
cuda_set_device(gpu_index);//配置cuda
}
#endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
根据makefile中的GPU配置 与指令gpu_index的值 配置cuda
然后就是根据指令进入不同的函数
if (0 == strcmp(argv[1], "average")){
average(argc, argv);
} else if (0 == strcmp(argv[1], "yolo")){
run_yolo(argc, argv);
} else if (0 == strcmp(argv[1], "super")){
run_super(argc, argv);
} else if (0 == strcmp(argv[1], "lsd")){
run_lsd(argc, argv);
} else if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
后面的部分内容。argv[1]=detector,直接进入 run_detector(argc, argv)函数分析。
该函数在darknet\examples文件夹下的detector.c中
这个函数中前面的参数在训练指令中都没有,主要完成从参数中取到该值赋值,没有附默认值
可以直接看后半部分
argv[2]=train
所以关心这条语句即可
else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
- 1
执行train_detector函数,其中参数从上面代码得到
char *datacfg = argv[3];//cfg/voc.data
char *cfg = argv[4];//cfg/yolo-voc.cfg
char *weights = (argc > 5) ? argv[5] : 0;//darknet19_448.conv.23
- 1
- 2
- 3
int clear = find_arg(argc, argv, "-clear");//clear=0
- 1
gpu = gpu_index;//0
gpus = &gpu;
ngpus = 1;
- 1
- 2
- 3
接下来看train_detector函数,该函数是训练目标检测器的入口函数
void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear)
- 1
list *options = read_data_cfg(datacfg);//解析datacfg文件
- 1
datacfg = argv[3];//cfg/voc.data
就是加载voc.data并解析该文件将各变量赋值到options下
voc.data文件实例及解释
怎么解析的有时间再细看,很多list的操作。
char *train_images = option_find_str(options, "train", "data/train.list");//判断options里是否含有train信息,没有默认为为"data/train.list"
- 1
*train_images 就是训练图片的名字(不带后缀)
char *backup_directory = option_find_str(options, "backup", "/backup/");//判断options里是否含有backup信息,没有默认为为""/backup/""
- 1
*backup_directory就是模型存放的路径
char *base = basecfg(cfgfile);//解析cfgfile文件
- 1
char *cfg = argv[4];//cfg/yolo-voc.cfg
cfg/yolo-voc.cfg文件实例,就是模型的配置参数
加载解析了相关文件,下一步就要用这些参数构建网络了。
主要函数
nets[i] = load_network(cfgfile, weightfile, clear);
- 1
放到下部分内容里吧。
文章来源: blog.csdn.net,作者:月照银海似蛟龙,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_32761549/article/details/92615507
- 点赞
- 收藏
- 关注作者
评论(0)