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:
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 sampledict to self.transform so use self.transform(sample['image']) instead.
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