Pic should be Tensor or ndarray. Got <class 'dict'>

im facing the problem ‘pic should be tensor or ndarray’ . i check both img and to pil image on transforms. how to fix this problem ?

Blockquote
TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/worker.py”, line 185, in _worker_loop
data = fetcher.fetch(index)
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py”, line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py”, line 44, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File “”, line 40, in getitem
self.sample = self.transform(self.sample)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/transforms.py”, line 61, in call
img = t(img)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/transforms.py”, line 172, in call
return F.to_pil_image(pic, self.mode)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/functional.py”, line 190, in to_pil_image
raise TypeError(‘pic should be Tensor or ndarray. Got {}.’.format(type(pic)))
TypeError: pic should be Tensor or ndarray. Got <class ‘dict’>.

train_transform = transforms.Compose([transforms.ToPILImage(),                                  
  transforms.Resize(226),
  transforms.RandomVerticalFlip(p=0.5),
transforms.ToTensor(), 
  
])


class DatasetLoader_Custom(Dataset):
    def __init__(self,root_dir, transform=None):
        """
        Args:
            root_dir (string): Directory with all the images.
            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.images = []
        self.label = []
        for filename in os.listdir(root_dir):
          for folder in os.listdir(os.path.join(root_dir,filename)):
            img = Image.open(os.path.join(os.path.join(root_dir,filename),folder))
            text = filename
            if img is not None:
              #zeros = np.zeros(3,960,720)
              img = np.array(img)
              img = img.transpose(2,1,0)
              if text.find("_") > 0:
                self.images.append(img)
              else:
                self.label.append(img)
            else:
              print('Errorrr')

        self.transform = transform
        
        print("Images: ",self.images[1])
        print(self.images[1].shape)
        print("************************")
        print("Label: ",self.label[1])
        print(self.label[1].shape)
    def __len__(self):
        return len(self.images)

    def __getitem__(self, x):
        self.sample = {'image': self.images, 'landmarks': self.label}

        if self.transform:
            self.sample = self.transform(self.sample)
        self.images = self.sample['image']
        self.labels = self.sample['landmarks']

        return self.images[x],self.labels[x]

Why do you want to perform the self.transform() operation on all images every time when the __getitem__() of the dataloader is called? You’re required to do the transform operation only on self.images[x] and self.labels[x]. It’s not wrong, but it’s not a good programming practice as you’re doing a redundant operation. Try to change your __getitem__() to the following definition:

def __getitem__(self, x):
        img, label = self.images[x], self.labels[x]
        sample = {'image': img, 'landmarks': label}

        if self.transform:
            sample = self.transform(sample)
        img = sample['image']
        label = sample['landmarks']

        return img, label
2 Likes

Actually, i only tried this operation because its would cause a problem. the problem still continues

Blockquote
Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/worker.py”, line 185, in _worker_loop
data = fetcher.fetch(index)
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py”, line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File “/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py”, line 44, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File “”, line 41, in getitem
sample = self.transform(sample)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/transforms.py”, line 61, in call
img = t(img)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/transforms.py”, line 172, in call
return F.to_pil_image(pic, self.mode)
File “/usr/local/lib/python3.6/dist-packages/torchvision/transforms/functional.py”, line 190, in to_pil_image
raise TypeError(‘pic should be Tensor or ndarray. Got {}.’.format(type(pic)))
TypeError: pic should be Tensor or ndarray. Got <class ‘dict’>.

Assuming you are passing train_transform to the transform argument in DatasetLoader_Custom, you would have to apply this transformation for each image separately as noted by @planet_pluto.

Currently you are passing the sample dict to self.transform so use self.transform(sample['image']) instead.

1 Like

I think we solved the problem, but now I encounter an error in the iterator. Can you explain what is the source of these problems?

 len(valid_data_loader)
 iterator = iter(valid_data_loader)
 x,y = next(iterator)

TypeError Traceback (most recent call last)
in ()
1 len(valid_data_loader)
2 iterator = iter(valid_data_loader)
----> 3 x,y = next(iterator)

7 frames
/usr/local/lib/python3.6/dist-packages/torchvision/transforms/functional.py in resize(img, size, interpolation)
317 “”"
318 if not _is_pil_image(img):
→ 319 raise TypeError(‘img should be PIL Image. Got {}’.format(type(img)))
320 if not (isinstance(size, int) or (isinstance(size, Iterable) and len(size) == 2)):
321 raise TypeError(‘Got inappropriate size arg: {}’.format(size))

TypeError: img should be PIL Image. Got <class ‘torch.Tensor’>

Resize expects a PIL.Image, while you are passing a tensor.
The most recent torchvision version added transformations, which also accept tensors so you could install the nightly or build from source.
If you don’t want to update torchvision, pass a PIL.Image to the transformation.

i dont understand where to use this information because i feed to the dataloader by opening PIL.Image.Open and converting numpy array for operation .Morever, i used ToPILImage by pytorch.Frankly, im really confusing