PacktPublishing/Modern-Computer-Vision-with-PyTorch

Issue with Data_augmentation_with_CNN: 'Tensor' object has no attribute 'deepcopy'

Fernando961226 opened this issue · 2 comments

The problems seems to lie with this line:
if self.aug: ims=self.aug.augment_images(images=ims)
The issue is that we are passing a tuple with tensors they must be NumPy arrays to work from my understanding.

Here is the error that I get:

in
3 for epoch in range(5):
4 print(epoch)
----> 5 for ix, batch in enumerate(iter(trn_dl)):
6 x, y = batch
7 batch_loss = train_batch(x, y, model, optimizer, loss_fn)

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\torch\utils\data\dataloader.py in next(self)
519 if self._sampler_iter is None:
520 self._reset()
--> 521 data = self._next_data()
522 self._num_yielded += 1
523 if self._dataset_kind == _DatasetKind.Iterable and \

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\torch\utils\data\dataloader.py in _next_data(self)
559 def _next_data(self):
560 index = self._next_index() # may raise StopIteration
--> 561 data = self._dataset_fetcher.fetch(index) # may raise StopIteration
562 if self._pin_memory:
563 data = _utils.pin_memory.pin_memory(data)

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\torch\utils\data_utils\fetch.py in fetch(self, possibly_batched_index)
50 else:
51 data = self.dataset[possibly_batched_index]
---> 52 return self.collate_fn(data)

in collate_fn(self, batch)
14
15
---> 16 if self.aug: ims=self.aug.augment_images(images=ims)
17 ims = torch.tensor(ims)[:,None,:,:].to(device)/255.
18 classes = torch.tensor(classes).to(device)

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\imgaug\augmenters\meta.py in augment_images(self, images, parents, hooks)
823 UnnormalizedBatch(images=images),
824 parents=parents,
--> 825 hooks=hooks
826 ).images_aug
827

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\imgaug\augmenters\meta.py in augment_batch_(self, batch, parents, hooks)
595 batch_unnorm = batch
596 batch_norm = batch.to_normalized_batch()
--> 597 batch_inaug = batch_norm.to_batch_in_augmentation()
598 elif isinstance(batch, Batch):
599 batch_norm = batch

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\imgaug\augmentables\batches.py in to_batch_in_augmentation(self)
449
450 return _BatchInAugmentation(
--> 451 images=_copy(self.images_unaug),
452 heatmaps=_copy(self.heatmaps_unaug),
453 segmentation_maps=_copy(self.segmentation_maps_unaug),

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\imgaug\augmentables\batches.py in _copy(var)
445 # TODO first check here if _aug is set and if it is then use that?
446 if var is not None:
--> 447 return utils.copy_augmentables(var)
448 return var
449

E:\Programs\anaconda3\envs\deep-learning\lib\site-packages\imgaug\augmentables\utils.py in copy_augmentables(augmentables)
17 result.append(np.copy(augmentable))
18 else:
---> 19 result.append(augmentable.deepcopy())
20 return result
21

AttributeError: 'Tensor' object has no attribute 'deepcopy'

I had the same issue when running the notebook on VSCode on a Mac...
It worked fine on Google Colab though.

I used this turnaround:

  1. Define a to_numpy function:
    import numpy as np
    def to_numpy(tensor):
    return tensor.cpu().detach().numpy()
  2. apply the function to each tensor element of the ims tuple in the collate_fn method:
    def collate_fn(self, batch):
    'logic to modify a batch of images'
    ims, classes = list(zip(*batch))
    ims=tuple(map(to_numpy, ims))
    # transform a batch of images at once
    if self.aug: ims=self.aug.augment_images(images=ims)
    ims = torch.tensor(ims)[:,None,:,:].to(device)/255.
    classes = torch.tensor(classes).to(device)
    return ims, classes

and it should work...

Thank you for the resolution @TiStef
@Fernando961226 - Feel free to reopen the issue with more details if it still doesn't work