使用cocoapi遇到的坑及爬坑记录
问题一:模型评估阶段,数据类型不匹配
问题二:模型评估阶段,读取预测结果时传的列表为空
近期在做基于coco数据集的实验,这两天又幸运地薅到了实验室一台服务器,搬运一波代码配好环境之后发现在服务器上使用coco自带的api做evaluation的时候报错了,卡了好久才把问题都解决。以下是遇到的两个问题以及爬坑的记录。
问题一:模型评估阶段,数据类型不匹配
错误信息
TypeError: object of type <class ‘numpy.float64’> cannot be safely interpreted as an integer
原因
问题出在 cocoapi 库的 cocoval.py 中的 Params类,代码如下:
self.iouThrs = np.linspace(.5, 0.95, np.round((0.95 - .5) / .05) + 1, endpoint=True)
self.recThrs = np.linspace(.0, 1.00, np.round((1.00 - .0) / .01) + 1, endpoint=True)
.......
self.iouThrs = np.linspace(.5, 0.95, np.round((0.95 - .5) / .05) + 1, endpoint=True)
self.recThrs = np.linspace(.0, 1.00, np.round((1.00 - .0) / .01) + 1, endpoint=True)
np.round()会返回float类型,但是numpy1.11以上的版本中,np.linspace不支持float类型参数,所以需要类型转换。
解决方法
如果不想修改代码,可以把numpy降级为1.11,但是不推荐这么做,还是推荐修改源码,对np.round()前面加一个int型转换就好了,源码位置在 lib/python3.6/site-packages/pycocotools/cocoeval.py
具体如下:
self.iouThrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True)
self.recThrs = np.linspace(.0, 1.00, int(np.round((1.00 - .0) / .01)) + 1, endpoint=True)
......
self.iouThrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True)
self.recThrs = np.linspace(.0, 1.00, int(np.round((1.00 - .0) / .01)) + 1, endpoint=True)
问题二:模型评估阶段,读取预测结果时传的列表为空
Traceback (most recent call last):
File "train.py", line 174, in <module>
args.checkpoint_after, args.val_after)
File "train.py", line 133, in train
evaluate(val_labels, val_output_name, val_images_folder, net)
File "/media/lab349/dbdb0721-5114-4f63-982f-3cfbad742077/JamesChen/lightweight-human-pose-estimation.pytorch-master/val.py", line 160, in evaluate
run_coco_eval(labels, output_name)
File "/media/lab349/dbdb0721-5114-4f63-982f-3cfbad742077/JamesChen/lightweight-human-pose-estimation.pytorch-master/val.py", line 22, in run_coco_eval
coco_dt = coco_gt.loadRes(dt_file_path)
File "/home/lab349/.conda/envs/zzcPose/lib/python3.6/site-packages/pycocotools/coco.py", line 325, in loadRes
if 'caption' in anns[0]:
IndexError: list index out of range
报错信息是 list index out of range,访问第0个元素超出了范围,说明列表 anns 为空。然后看anno这个东西,它是在val的阶段对coco的val数据集预测的结果,此时anns是空的,有一个可能是模型此时啥也没预测出来,然后发现还真是,因为使用了一个自己新改的网络,骨干和后面的refine模块全变了,所有没有加载预训练模型,模型从零开始训练,在刚开始的val阶段未检测出信息,导致空参数resFile传递给了loadRes,致使取anns访问元素报错。
解决方法
知道了问题在哪,解决起来就容易了,我这里直接设置模型刚开始训练时不进行模型评估的操作。
再插一嘴
排这个坑耽误了好久,一开始以为是环境问题,换了cocoapi的版本还是不行,然后以为是代码哪里改错了,又仔细跟之前的代码对照了一波发现一毛一样,然后网上各种乱找资料都没能解决,最后是在这里 https://github.com/RangiLyu/nanodet/issues/120 看到了一个老哥说:“It’s weird. Maybe because the model detected nothing in the Val dataset.” 突然意识到了可能是模型未预测出结果。
网上很多问这个的但是都没能解决我这个坑,我这里记录一下吧,以便大家如果遇到这个问题的话能多一个解决思路~