Brummi / MonoRec

Official implementation of the paper: MonoRec: Semi-Supervised Dense Reconstruction in Dynamic Environments from a Single Moving Camera (CVPR 2021)
MIT License
587 stars 85 forks source link

TypeError: 'tuple' object is not callable #30

Closed huangbinz closed 2 years ago

huangbinz commented 2 years ago

when train the model with command python train.py --config configs/train/monorec/monorec_depth.json --options stereo, get an error:

Traceback (most recent call last):
  File "/home/hyel/python_work/MonoRec/train.py", line 70, in <module>
    main(config, config.args.options)
  File "/home/hyel/python_work/MonoRec/train.py", line 49, in main
    trainer.train()
  File "/home/hyel/python_work/MonoRec/base/base_trainer.py", line 73, in train
    result = self._train_epoch(epoch)
  File "/home/hyel/python_work/MonoRec/trainer/trainer.py", line 84, in _train_epoch
    for batch_idx, (data, target) in enumerate(self.data_loader):
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 517, in __next__
    data = self._next_data()
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 1199, in _next_data
    return self._process_data(data)
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 1225, in _process_data
    data.reraise()
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/_utils.py", line 429, in reraise
    raise self.exc_type(msg)
TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/_utils/worker.py", line 202, in _worker_loop
    data = fetcher.fetch(index)
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/home/hyel/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in <listcomp>
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/home/hyel/python_work/MonoRec/data_loader/kitti_odometry_dataset.py", line 250, in __getitem__
    self._crop_boxes[dataset_index])
  File "/home/hyel/python_work/MonoRec/data_loader/kitti_odometry_dataset.py", line 126, in preprocess_image
    img = self.color_transform(img)
  File "/home/hyel/python_work/MonoRec/data_loader/kitti_odometry_dataset.py", line 383, in __call__
    return map_fn(x, self.transform)
  File "/home/hyel/python_work/MonoRec/utils/util.py", line 22, in map_fn
    return fn(batch)
TypeError: 'tuple' object is not callable

modify function in kitti_odometry_dataset.py from:

class ColorJitterMulti(torchvision.transforms.ColorJitter):
    def fix_transform(self):
        self.transform = self.get_params(self.brightness, self.contrast,
                                         self.saturation, self.hue)

    def __call__(self, x):
        return map_fn(x, self.transform)

to

class ColorJitterMulti(torchvision.transforms.ColorJitter):
    def fix_transform(self):
        self.transform = self.get_params(self.brightness, self.contrast,
                                         self.saturation, self.hue)

    def __call__(self, x):
        return map_fn(x, self.forward)           # change self.transform to self.forward

can fix this error

this is a bug? is it right to modify the code like this?

Brummi commented 2 years ago

Hi, thank you for your interest in MonoRec. I don't have this bug on my machine. Could you please let me know which version of the torchvision package you are using? If possible, downgrade torchvision to version 0.6.

Brummi commented 2 years ago

I think this should do the trick without downgrading your torchvision.

class ColorJitterMulti(torchvision.transforms.ColorJitter):
    def fix_transform(self):
        self.params = self.get_params(self.brightness, self.contrast, self.saturation, self.hue)

    def __call__(self, img):
        fn_idx, brightness_factor, contrast_factor, saturation_factor, hue_factor = self.params
        for fn_id in fn_idx:
            if fn_id == 0 and brightness_factor is not None:
                img = F.adjust_brightness(img, brightness_factor)
            elif fn_id == 1 and contrast_factor is not None:
                img = F.adjust_contrast(img, contrast_factor)
            elif fn_id == 2 and saturation_factor is not None:
                img = F.adjust_saturation(img, saturation_factor)
            elif fn_id == 3 and hue_factor is not None:
                img = F.adjust_hue(img, hue_factor)

        return img
huangbinz commented 2 years ago

Hi, thank you for your interest in MonoRec. I don't have this bug on my machine. Could you please let me know which version of the torchvision package you are using? If possible, downgrade torchvision to version 0.6.

thank you for your reply, my torchvision is 0.9.0.

huangbinz commented 2 years ago

I think this should do the trick without downgrading your torchvision.

class ColorJitterMulti(torchvision.transforms.ColorJitter):
    def fix_transform(self):
        self.params = self.get_params(self.brightness, self.contrast, self.saturation, self.hue)

    def __call__(self, img):
        fn_idx, brightness_factor, contrast_factor, saturation_factor, hue_factor = self.params
        for fn_id in fn_idx:
            if fn_id == 0 and brightness_factor is not None:
                img = F.adjust_brightness(img, brightness_factor)
            elif fn_id == 1 and contrast_factor is not None:
                img = F.adjust_contrast(img, contrast_factor)
            elif fn_id == 2 and saturation_factor is not None:
                img = F.adjust_saturation(img, saturation_factor)
            elif fn_id == 3 and hue_factor is not None:
                img = F.adjust_hue(img, hue_factor)

        return img

you are right, but i think, this is the implementation in ColorJitter.forward, we can call it directly

Brummi commented 2 years ago

The implementation is very similar. However, ColorJitter.forward obtains new randomized parameters every time it is called. In our case, this is not desired because we need to apply the same augmentation onto all the frames that go into the cost volume.

Therefore, we fix the parameters once (in fix_transform) and then reuse the same parameters for all frames in the respective cost volume. (fix_transform gets called once for every item the dataset returns).

huangbinz commented 2 years ago

I understand, thank you very much for your patience