Hi there!!
I am struggling on using CNN with BCELoss to classify with 0 or 1 images. Basically the loss struggles with the type of the labels but I really don’t understand how I should do it. Basically I have a class Dataset that opens an image and depending on having or not a feature I define a variable label as int 1 or int 0. Then, I convert it to tensor using torch.Tensor() and this class returns a sample with the image and the label. But then, when I try to train it, it always gives errors in the loss function and I really don’t understand why it doesn’t work.
RuntimeError: Caught RuntimeError 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 47, in fetch
return self.collate_fn(data)
File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/collate.py", line 74, in default_collate
return {key: default_collate([d[key] for d in batch]) for key in elem}
File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/collate.py", line 74, in <dictcomp>
return {key: default_collate([d[key] for d in batch]) for key in elem}
File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/collate.py", line 55, in default_collate
return torch.stack(batch, 0, out=out)
RuntimeError: stack expects each tensor to be equal size, but got [0] at entry 0 and [1] at entry 1
Based on the error message it seems your data loading is creating an empty tensor and tries to concatenate it into a batch with other tensors.
Could you use batch_size=1, iterate the DataLoader in isolation without any training and check the shapes for the data and target tensors?
You could try to drop the last (smaller) batch via drop_last=True in the DataLoader.
However, I’m not sure, if this would solve the issue. Let me know, if you are still running into the error.
Basically now I am getting all types of errors regarding the data and target types, maybe it has something to do with a way I convert to tensor, could something check it out?
if self.train == True:
try:
masks = Image.open(self.masks_dir + os.path.splitext(self.train_names[idx])[0]+'beard.jpg') ## change the end of the filename name depending of we want "beard" or "hair" or "_eyelid"
target = 1
#-----------------------------------------------------------------------
except:
target = 0
else:
target = 0
image=np.array(image)
if image.shape[2] == 4:
#convert the image from RGBA2R
image = cv2.cvtColor(image, cv2.COLOR_BGR2BGR)
image=resize(image, (self.im_size , self.im_size),anti_aliasing=True)
image = transforms.ToTensor()(image)
image=image.float()
#target = torch.Tensor(target)
target = transforms.ToTensor()(target).float()
sample = {'image': image, 'target': target}
When I try to iterate the dataloader, this happens:
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 <listcomp>
data = [self.dataset[idx] for idx in possibly_batched_index]
File "<ipython-input-83-577e6d24b257>", line 50, in __getitem__
target = transforms.ToTensor()(target).float()
File "/usr/local/lib/python3.6/dist-packages/torchvision/transforms/transforms.py", line 92, in __call__
return F.to_tensor(pic)
File "/usr/local/lib/python3.6/dist-packages/torchvision/transforms/functional.py", line 46, in to_tensor
raise TypeError('pic should be PIL Image or ndarray. Got {}'.format(type(pic)))
TypeError: pic should be PIL Image or ndarray. Got <class 'int'>
Assuming you are using nn.BCELoss, the model output and target should have the same shape ([batch_size, 1] for a binary classification use case) and both should be FloatTensors.
Note that removing the last sigmoid and using nn.BCEWithLogitsLoss would give you a better numerical stability.