YOLOv3计算自己数据集训练模型的mAP

YOLOv3计算自己数据集训练模型的mAP

  • 使用valid计算结果数据
    • 类型配置
    • 结果存储文件名
    • 类型个数
  • voc_eval参数设置
  • Python2转Python3

关于使用YOLOv3计算mAP的帖子已经很多了。这里不再过多啰嗦,可以参考https://blog.csdn.net/amusi1994/article/details/81564504的介绍。
但是如果自己训练了模型,直接照搬常常会遇到各种问题,这里就几个比较迷惑的点进行记录:

使用valid计算结果数据

类型配置

计算mAP的第一步就是使用detector.c中的validate_detector,利用验证集图片计算一堆的结果,然后存在result文件夹中的txt文件中。
如果你使用的不是coco或者voc数据集,根据源码,将会使用你自定义的type:

char *type = option_find_str(options, "eval", "voc");

所以建议在data文件中增加一行配置:

eval = YOUR_TYPE

如果type为coco,将会保存成json文件;如果type为imagenet,将会将所有的结果保存到imagenet-detection.txt文件中。如果不配置,也不会产生什么影响,依然会就会默认使用comp4_det_test_[classname].txt。只是为了保证工程的完整性建议修改。

结果存储文件名

另外,建议将源码中的outfile初始值修改一下,将validate_detector函数中的

if(!outfile) outfile = "comp4_det_test_";

改为:

if(!outfile) outfile = "";

再编译。这样的结果是result中的文件保存的文件名就为[classname].txt,使用Python函数voc_eval.py在计算的时候,
通过

R = [obj for obj in recs[imagename] if obj['name'] == classname]

过获取每个类型的文件中匹配到目标的信息,否则obj[‘name’],即recs[imagename][i][‘name’]=comp4_det_test_[classname],这个if等式永远无法相等,就算的AP和mAP都将是nan.
当然,不想该detector.c,也可以使用Python语句

obj['name'].replace(‘comp4_det_test_’,’’)

将comp4_det_test_去掉。

类型个数

如果你的数据集类型个数不是80个,建议在validate_detector函数源码

int classes = l.classes;

后面增加

char *classesnum = option_find_str(options, "classes", "80");
classes = atoi(classesnum);

否者,在生成结果文件的过程中会出现“段错误”,这是因为根据源码:

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");
}

实际类型个数少,而class仍然按80计算,就会导致多出来的类型没有办法生成对应的文件。

voc_eval参数设置

def voc_eval(detpath,
             annopath,
             imagesetfile,
             classname,
             cachedir,
             ovthresh=0.5,
             use_07_metric=False):

中有多个参数,其中detpath是结果文件路径,在Python中设置问xxx/results/{}.txt。这个{}啥意思呢?因为在voc_eval中通过:

detfile = detpath.format(classname)

获得路径名,format(classname)用于根据classname这个字符串,对路径名进行填充。
annopath是标签文件路径,即Annotations文件夹中的xml文件,采用xxx/images_data/Annotations/{}.xml,和detpath设置是一个道理。
classname中存储的是存储验证集的文件名的文件路径,一般放在xxx/images_data/ImageSets/Main/文件夹下,这里的文件名就是将YOLO配置文件valia_data.txt中的路径和文件名后缀都去掉,如valia_data.txt中存储的是

app/cptest/images_data/JPEGImages/174_15890312979608698.jpg

在此文件中存储的就是

174_15890312979608698

注意,一定要一个文件名放一行。
classname是通过

class_name = sub_files[i].split(".txt")[0]

获得的,就是存储结果的文件名。这个class_name如果和文件名不一致,处理方法前面已经说过了。
cachedir就是缓存标签的路径,一般设置为‘.’,表示不设置
ovthresh为确定认为命中目标,针对class的置信度所使用的阈值,一般默认设置为0.5,可以根据实际情况进行设置。
use_07_metric表示是否使用VOC07的11点计算法,默认为Flase.

Python2转Python3

由于voc_eval是使用Python2编写的,当你使用Python3调用时候
(1)print ‘’的语法改为print()
(2)import cPickle改为import pickle
代码中cPickle.dump和cPickle.load进行相应修改

以上就是计算mAP会遇到的问题和解决办法。

你可能感兴趣的:(YOLOv3计算自己数据集训练模型的mAP)