Loading

mmdetection测试报错,data['category_id'] = self.cat_ids[label] IndexError: list index out of range

解决方案

测试自己的数据集之前,是否做了以下操作:

  1. 修改模型配置文件中的类别数num_classes为自己数据集中的类别数,我这里设置为1:num_classes=1
  2. mmdet/evaluation/functional/class_names.py中找到函数coco_classes()注释掉原来的类名,替换为自己的类名,如下所示:
def coco_classes() -> list:
    """Class names of COCO."""
    return ['pedestrian']
    # return [
    #     'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train',
    #     'truck', 'boat', 'traffic_light', 'fire_hydrant', 'stop_sign',
    #     'parking_meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep',
    #     'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella',
    #     'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard',
    #     'sports_ball', 'kite', 'baseball_bat', 'baseball_glove', 'skateboard',
    #     'surfboard', 'tennis_racket', 'bottle', 'wine_glass', 'cup', 'fork',
    #     'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange',
    #     'broccoli', 'carrot', 'hot_dog', 'pizza', 'donut', 'cake', 'chair',
    #     'couch', 'potted_plant', 'bed', 'dining_table', 'toilet', 'tv',
    #     'laptop', 'mouse', 'remote', 'keyboard', 'cell_phone', 'microwave',
    #     'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',
    #     'scissors', 'teddy_bear', 'hair_drier', 'toothbrush'
    # ]
  1. 找到文件mmdet/datasets/coco.py,注释掉原来的类名,如下所示:
class CocoDataset(BaseDetDataset):
    """Dataset for COCO."""

    METAINFO = {
        'classes': 'pedestrain'
        # ('person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train',
        #  'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign',
        #  'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep',
        #  'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella',
        #  'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard',
        #  'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard',
        #  'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork',
        #  'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange',
        #  'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair',
        #  'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv',
        #  'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave',
        #  'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',
        #  'scissors', 'teddy bear', 'hair drier', 'toothbrush'),
        # palette is a list of color tuples, which is used for visualization.
        'palette': [(220, 20, 60), ]
        # [(220, 20, 60), (119, 11, 32), (0, 0, 142), (0, 0, 230), (106, 0, 228),
        #  (0, 60, 100), (0, 80, 100), (0, 0, 70), (0, 0, 192), (250, 170, 30),

一般来说执行了以上操作,再测试就不会出错了。但是,我做了以上操作,依旧报错:

Traceback (most recent call last):
  File "tools/test.py", line 149, in <module>
    main()
  File "tools/test.py", line 145, in main
    runner.test()
  File "/root/anaconda3/envs/py38/lib/python3.8/site-packages/mmengine/runner/runner.py", line 1823, in test
    metrics = self.test_loop.run()  # type: ignore
  File "/root/anaconda3/envs/py38/lib/python3.8/site-packages/mmengine/runner/loops.py", line 466, in run
    metrics = self.evaluator.evaluate(len(self.dataloader.dataset))
  File "/root/anaconda3/envs/py38/lib/python3.8/site-packages/mmengine/evaluator/evaluator.py", line 79, in evaluate
    _results = metric.evaluate(size)
  File "/root/anaconda3/envs/py38/lib/python3.8/site-packages/mmengine/evaluator/metric.py", line 133, in evaluate
    _metrics = self.compute_metrics(results)  # type: ignore
  File "/tmp/mmdetProject/mmdet/evaluation/metrics/coco_metric.py", line 424, in compute_metrics
    result_files = self.results2json(preds, outfile_prefix)
  File "/tmp/mmdetProject/mmdet/evaluation/metrics/coco_metric.py", line 244, in results2json
    data['category_id'] = self.cat_ids[label]
IndexError: list index out of range

可以看到,报错信息是这行代码:data['category_id'] = self.cat_ids[label],找到报错的文件coco_metric.py,定位到244行,Ctrl+F,找到有self.cat_ids[label]的地方,可以找到下面的代码:

	# handle lazy init
	if self.cat_ids is None:
		self.cat_ids = self._coco_api.get_cat_ids(
		cat_names=self.dataset_meta['classes'])
	if self.img_ids is None:
		self.img_ids = self._coco_api.get_img_ids()

可以看到cat_ids是调用函数self._coco_api.get_cat_ids(),并使用类别名作为参数之后的返回结果。问题就出在这里!!!。因为使用官方的数据集格式转换文件tools/dataset_converters/crowdhuman2coco.py,默认的类别名是pedestrian,我在修改上述包含classes的类别名是person,class name不一致,因此返回的id是空列表,也就出现数组越界的错误!!!!最后就正常了,不会报错了

总结

  1. 修改模型配置文件中的num_classes
  2. 修改mmdet/evaluation/functional/class_names.py中的coco_classes()
  3. 修改文件mmdet/datasets/coco.py中的METAINFO
  4. 检查标注文件的类名是否和上述文件中的类别名一致!!!

参考

MMDetection训练自己的数据集 coco格式

posted @ 2025-03-07 16:54  记录学习的Lyx  阅读(363)  评论(0)    收藏  举报