1.src/darknet.c/main()
通过解析train.sh中的批处理指令,遇到detector进入run_detector函数。
else if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
2.src/detector.c/run_detector()
通过解析train.sh的批处理指令,遇到train进入train_detector函数。
else if(0==strcmp(argv[2], "train"))
train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
run_detector函数代码
void run_detector(int argc, char **argv)
{
char *prefix = find_char_arg(argc, argv, "-prefix", 0);
float thresh = find_float_arg(argc, argv, "-thresh", .24);
float hier_thresh = find_float_arg(argc, argv, "-hier", .5);
int cam_index = find_int_arg(argc, argv, "-c", 0);
int frame_skip = find_int_arg(argc, argv, "-s", 0);
int avg = find_int_arg(argc, argv, "-avg", 3);
if(argc < 4){
fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]);
return;
}
// 解析输入参数,获取GPU使用情况,如果使用单个GPU,那么调用时不需要指明GPU卡号,默认使用卡号0上的GPU;
// 如果使用多块GPU,那么在调用时,其中有两个参数必须为:-gpus 0,1,2...(以逗号隔开)
// 前者指明是GPU卡号参数,后者为多块GPU的卡号,find_char_arg就是将0,1,2...读入gpu_list
char *gpu_list = find_char_arg(argc, argv, "-gpus", 0);
char *outfile = find_char_arg(argc, argv, "-out", 0);
// 整型数组,为所有使用GPU的卡号集合(如果使用多个GPU,那么会有0,1,2..多个值,
// 如果只使用一块GPU,那么只有一个元素值0,这是默认卡号;如果不使用GPU,那么以下3个参数最终其实没有用到,
// 只是为了统一接口,这三个参数不能删)
int *gpus = 0;
int gpu = 0;
int ngpus = 0;
// 如果不用GPU进行训练,会执行else语句,此时ngpus=1,这不是说还是会使用GPU,因为在真正调用使用GPU的函数之前,
// 还是会判断#ifdef GPU,如果没有定义,即使ngpus=1也不会使用GPU进行训练;此外,ngpus是最终网络划分的个数,
// 这个参数不管使不使用GPU都会用到:使用多个GPU时,需要将网络划分成多个,分到各个GPU上进行训练;而使用一块GPU或者不使用GPU时,显然ngpus都得等于1
if(gpu_list){
printf("%s\n", gpu_list);
int len = strlen(gpu_list);
ngpus = 1;
int i;
for(i = 0; i < len; ++i){
if (gpu_list[i] == ',') ++ngpus;
}
gpus = calloc(ngpus, sizeof(int));
for(i = 0; i < ngpus; ++i){
gpus[i] = atoi(gpu_list);
gpu_list = strc