open-mmlab / mmpose

OpenMMLab Pose Estimation Toolbox and Benchmark.
https://mmpose.readthedocs.io/en/latest/
Apache License 2.0
5.91k stars 1.26k forks source link

“ValueError: non-integer arg 1 for randrange()” and its solutions #2197

Closed wukurua closed 1 year ago

wukurua commented 1 year ago

When I transplant config file "configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose-m_8xb64-210e_ap10k-256x256.py" to my dataset, and then run "tools/train.py", it reports errors: Error traceback

Traceback (most recent call last):
  File ".\tools\train.py", line 160, in <module>
    main()
  File ".\tools\train.py", line 156, in main
    runner.train()
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\runner\runner.py", line 1706, in train
    model = self.train_loop.run()  # type: ignore
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\runner\loops.py", line 96, in run
    self.run_epoch()
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\runner\loops.py", line 111, in run_epoch
    for idx, data_batch in enumerate(self.dataloader):
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\dataloader.py", line 521, in __next__
    data = self._next_data()
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\dataloader.py", line 1203, in _next_data
    return self._process_data(data)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\dataloader.py", line 1229, in _process_data
    data.reraise()
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\_utils.py", line 434, in reraise
    raise exception
ValueError: Caught ValueError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\_utils\worker.py", line 287, in _worker_loop
    data = fetcher.fetch(index)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\_utils\fetch.py", line 49, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\torch\utils\data\_utils\fetch.py", line 49, in <listcomp>
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\dataset\base_dataset.py", line 413, in __getitem__
    data = self.prepare_data(idx)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\dataset\base_dataset.py", line 114, in wrapper
    return old_func(obj, *args, **kwargs)
  File "e:\code\mmpose\mmpose\datasets\datasets\base\base_coco_style_dataset.py", line 150, in prepare_data
    return self.pipeline(data_info)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmengine\dataset\base_dataset.py", line 59, in __call__
    data = t(data)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\mmcv\transforms\base.py", line 12, in __call__
    return self.transform(results)
  File "e:\code\mmpose\mmpose\datasets\transforms\common_transforms.py", line 683, in transform
    results_albu = self.aug(**results_albu)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\albumentations\core\composition.py", line 176, in __call__
    data = t(force_apply=force_apply, **data)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\albumentations\core\transforms_interface.py", line 78, in __call__
    params_dependent_on_targets = self.get_params_dependent_on_targets(targets_as_params)
  File "D:\anaconda3\envs\openmmlab\lib\site-packages\albumentations\augmentations\transforms.py", line 1571, in get_params_dependent_on_targets
    hole_height = random.randint(self.min_height, self.max_height)
  File "D:\anaconda3\envs\openmmlab\lib\random.py", line 248, in randint
    return self.randrange(a, b+1)
  File "D:\anaconda3\envs\openmmlab\lib\random.py", line 212, in randrange
    raise ValueError("non-integer arg 1 for randrange()")
ValueError: non-integer arg 1 for randrange()

After checking, I found the reason to be in the following code:

# pipelines
train_pipeline = [
    dict(type='LoadImage', backend_args=backend_args),
    dict(type='GetBBoxCenterScale'),
    dict(type='RandomFlip', direction='horizontal'),
    dict(type='RandomHalfBody'),
    dict(
        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),
    dict(type='TopdownAffine', input_size=codec['input_size']),
    dict(type='mmdet.YOLOXHSVRandomAug'),
    dict(
        type='Albumentation',
        transforms=[
            dict(type='Blur', p=0.1),
            dict(type='MedianBlur', p=0.1),
           dict(
                type='CoarseDropout',
                max_holes=1,
                max_height=0.4,
                max_width=0.4,
                min_holes=1,
                min_height=0.2,
                min_width=0.2,
                p=1.0),),
        ]),
    dict(type='GenerateTarget', encoder=codec),
    dict(type='PackPoseInputs')
]

Change to:

# pipelines
train_pipeline = [
    dict(type='LoadImage', backend_args=backend_args),
    dict(type='GetBBoxCenterScale'),
    dict(type='RandomFlip', direction='horizontal'),
    dict(type='RandomHalfBody'),
    dict(
        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),
    dict(type='TopdownAffine', input_size=codec['input_size']),
    dict(type='mmdet.YOLOXHSVRandomAug'),
    dict(
        type='Albumentation',
        transforms=[
            dict(type='Blur', p=0.1),
            dict(type='MedianBlur', p=0.1),
            # dict(
            #     type='CoarseDropout',
            #     max_holes=1,
            #     max_height=0.4,
            #     max_width=0.4,
            #     min_holes=1,
            #     min_height=0.2,
            #     min_width=0.2,
            #     p=1.0),
            dict(
                type='CoarseDropout',
                max_holes=1,
                max_height=10,
                max_width=10,
                min_holes=1,
                min_height=1,
                min_width=1,
                p=0.5),
        ]),
    dict(type='GenerateTarget', encoder=codec),
    dict(type='PackPoseInputs')
]

The deeper reason is to be "albumentations" lib. My version is 0.4.6, I annotated a section of code and modify it to look like the following, so the train code can also run. D:\anaconda3\envs\openmmlab\Lib\site-packages\albumentations\augmentations\transforms.py

def get_params_dependent_on_targets(self, params):
    img = params["image"]
    height, width = img.shape[:2]

    holes = []
    for _n in range(random.randint(self.min_holes, self.max_holes)):
        # hole_height = random.randint(self.min_height, self.max_height)
        # hole_width = random.randint(self.min_width, self.max_width)
        # 
        # y1 = random.randint(0, height - hole_height)
        # x1 = random.randint(0, width - hole_width)
        # y2 = y1 + hole_height
        # x2 = x1 + hole_width
        hole_height = random.uniform(self.min_height, self.max_height)
        hole_width = random.uniform(self.min_width, self.max_width)

        y1 = math.ceil(random.uniform(0, height - hole_height))
        x1 = math.ceil(random.uniform(0, width - hole_width))
        y2 = math.floor(y1 + hole_height)
        x2 = math.floor(x1 + hole_width)

        holes.append((x1, y1, x2, y2))

    return {"holes": holes}

But I think the first method is closer to the original intention of CoarseDropout, and I'm not sure if it's correct or not. I'm looking forward to hearing back!

Tau-J commented 1 year ago

Thanks for using MMPose. This seems like an issue related to albumentations. We don't have any suggestions, please refer to the official documentation.