项目背景
在yolo-v2生成D:\dahuangfeng\darknet-master\build\darknet\x64\backup
路径下的权重文件
后,我们先需要先修改D:\dahuangfeng\darknet-master\build\darknet\x64
路径下的test_obj.cmd
文件,将操作对象修改成我们需要测试的权重文件,
然后运行test_obj.cmd
程序,程序加载权重文件并开始运行,
运行完毕后,取输出最后一行作为我们测试需要的结果,将其取样并写入指定txt文件并保存。
然后按照上述步骤循环测试后面的权重文件。太多太累太麻烦,于是便想写一个批处理程序。预设步骤
1、建立列表,将权重文件序号填写进去。
2、读取列表,打开test_obj.cmd
文件,运用正则化参数修改保存序号。
3、运行test_obj.cmd
文件,取最后行输出,用正则化参数提取数据并写入输出文件。
在visual studio中,打开detector.c文件,直接在validate_detector_recall()函数中加入“创建Test_Weight_Files.txt文件并将输出结果写入”的代码:
void validate_detector_recall(char *datacfg, char *cfgfile, char *weightfile){network net = parse_network_cfg_custom(cfgfile, 1);if(weightfile){load_weights(&net, weightfile);}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 *options = read_data_cfg(datacfg);char *valid_images = option_find_str(options, "valid", "data/train.txt");list *plist = get_paths(valid_images);char **paths = (char **)list_to_array(plist);layer l = net.layers[net.n-1];int classes = l.classes;int j, k;box *boxes = calloc(l.w*l.h*l.n, sizeof(box));float **probs = calloc(l.w*l.h*l.n, sizeof(float *));for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = calloc(classes, sizeof(float *));int m = plist->size;int i=0;float thresh = .2;// .001;float iou_thresh = .5;float nms = .4;int total = 0;int correct = 0;int proposals = 0;float avg_iou = 0;for(i = 0; i < m; ++i){char *path = paths[i];image orig = load_image_color(path, 0, 0);image sized = resize_image(orig, net.w, net.h);char *id = basecfg(path);network_predict(net, sized.data);get_region_boxes(l, 1, 1, thresh, probs, boxes, 1, 0);if (nms) do_nms(boxes, probs, l.w*l.h*l.n, 1, nms);char labelpath[4096];find_replace(path, "images", "labels", labelpath);find_replace(labelpath, "JPEGImages", "labels", labelpath);find_replace(labelpath, ".jpg", ".txt", labelpath);find_replace(labelpath, ".JPEG", ".txt", labelpath);find_replace(labelpath, ".png", ".txt", labelpath);int num_labels = 0;box_label *truth = read_boxes(labelpath, &num_labels);for(k = 0; k < l.w*l.h*l.n; ++k){if(probs[k][0] > thresh){++proposals;}}for (j = 0; j < num_labels; ++j) {++total;box t = { truth[j].x, truth[j].y, truth[j].w, truth[j].h };float best_iou = 0;for (k = 0; k < l.w*l.h*l.n; ++k) {float iou = box_iou(boxes[k], t);if (probs[k][0] > thresh && iou > best_iou) {best_iou = iou;}}avg_iou += best_iou;if(best_iou > iou_thresh){++correct;}}fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total);free(id);free_image(orig);free_image(sized);}//创建Test_Weight_Files.txt文件并将输出结果写入FILE *fp = fopen("./Test_Weight_Files.txt", "a");char* token = strtok(weightfile, "/");token = strtok(NULL, "/");fprintf(fp, "%s\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", token, (float)proposals / (i + 1), avg_iou * 100 / total, 100.*correct / total);fclose(fp);}
然后修改我们的test_obj.cmd
文件的信息:
:生成可用以下python代码(其实可用代码提取生成的权重文件中数字,没做,莎哔了。。。)
# -*- coding: utf-8 -*-"""@File : _dontla_auto_evaluate.py@Time : /3/8 23:43@Author : Dontla@Email : sxana@@Software: PyCharm"""import osepoch = ['100', '200', '300', '400', '500', '600', '700', '800', '900','1000', '2000', '3000', '4000', '5000', '6000', '7000', '8000', '9000','10000', '11000', '12000', '13000', '14000', '15000', '16000', '17000', '18000', '19000','20000', '21000', '22000', '23000', '24000', '25000', '26000', '27000', '28000', '29000','30000', '31000', '32000', '33000', '34000', '35000', '36000', '37000', '38000', '39000','40000', '41000', '42000', '43000', '44000', '45000', 'final']file = open('./dontla_result.txt', 'w', encoding='utf-8')for i in epoch:command = '.\darknet.exe detector recall data/obj.data yolo-obj.cfg backup/yolo-obj_{}.weights'.format(i)print(command)# print(command)# ..\darknet.exe detector recall data/obj.data yolo-obj.cfg backup/yolo-obj_100.weights# ..\darknet.exe detector recall data/obj.data yolo-obj.cfg backup/yolo-obj_200.weights# ...# result = os.popen(command)# res = result.read()# for line in res.splitlines():#print(line)# file.write(''.join([i, '\t', result_list]))file.close()
运行test_obj.cmd
便可批量生成测试结果到Test_Weight_Files.txt
文件中,全部输出完毕后,会自行停止,
结果:虽然不如设想那样运用python去直接执行我们的操作,而是直接在c语言程序的函数中去增加处理代码,但还是顺利地实现了我们需要的功能。
参考文章1:c语言中的制表符\t与空格
参考文章2:用c语言创建一个txt文件,并且写入数据
参考文章3:C语言字符串处理的一些函数strok,strstr, strchr,strsub
参考文章4:C\C++编程中:相对路径+绝对路径
python yolo-v2 设计批处理程序对训练生成的权重文件进行自动化批量测试 并输出结果到指定txt文件