TypeError bool is not subscriptable

I’m using code from this tutorial. I have my own data. It is a very small set of images, just seven with seven masks. The masks have a black background and four AOIs each with their own shade.

When I get to these lines:

dataset = sensor_image(root = '/home/nightjar/Documents/images', transforms = get_transform(train=True))
>>> data_loader = torch.utils.data.DataLoader(
...  dataset)#, batch_size=1, num_workers=2,
>>> images,targets = next(iter(data_loader))

… I get the following error

:30: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
Traceback (most recent call last):
File “”, line 1, in
File “/home/nightjar/.local/share/virtualenvs/instance_seg_training-pW2YCmb4/lib64/python3.9/site-packages/torch/utils/data/dataloader.py”, line 530, in next
data = self._next_data()
File “/home/nightjar/.local/share/virtualenvs/instance_seg_training-pW2YCmb4/lib64/python3.9/site-packages/torch/utils/data/dataloader.py”, line 570, in _next_data
data = self._dataset_fetcher.fetch(index) # may raise StopIteration
File “/home/nightjar/.local/share/virtualenvs/instance_seg_training-pW2YCmb4/lib64/python3.9/site-packages/torch/utils/data/_utils/fetch.py”, line 49, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File “/home/nightjar/.local/share/virtualenvs/instance_seg_training-pW2YCmb4/lib64/python3.9/site-packages/torch/utils/data/_utils/fetch.py”, line 49, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File “”, line 36, in getitem
TypeError: ‘bool’ object is not subscriptable

I think the error is caused by the something to do with the masks, but I’m not sure of that, because I don’t understand everything the traceback says. But since it says “bool”, I’m guessing that is with the masks due to this comment in the code:
# split the color-encoded mask into a set
# of binary masks

That comment occurs early in the code where the class for the dataset is declared.

What can I do to resolve this error?

Based on the stacktrace it seems the error is raised in:

data = [self.dataset[idx] for idx in possibly_batched_index]

which seems to be caused by the indexing of self.dataset[idx] which seems to be a bool scalar.
What is print(type(dataset)) returning before wrapping it into the DataLoader?
If this is returning the proper Dataset class, are you able to iterate the object?

Hi, ptrblck.

It looks like I have the right Dataset class (I renamed it).

>> print(type(dataset))
<class '__main__.sensor_image'>

But it seems that I can’t iterate the Dataset.

>> iter(dataset)
<iterator object at 0x7fbc3c5ec220>
>> for i in iter(dataset):
...     print(i)
... 
<stdin>:30: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 36, in __getitem__
TypeError: 'bool' object is not subscriptable

This is the code for building the Dataset class. I think I only edited one line. It’s in the section for obj_ids.

class sensor_image(torch.utils.data.Dataset):
     def __init__(self, root, transforms=None, target_transform=None):
         self.root = root
         self.transforms = transforms
         self.target_transform = target_transform
         # load all image files, sorting them to
         # ensure that they are aligned
         self.imgs = list(sorted(os.listdir(os.path.join(root))))
         self.masks = list(sorted(os.listdir(os.path.join(root))))
         
     def __getitem__(self, idx):
         # load images ad masks
         img_path = os.path.join(self.root, self.imgs[idx])
         mask_path = os.path.join(self.root, self.masks[idx])
         img = Image.open(img_path).convert("RGB")
         # note that we haven't converted the mask to RGB,
         # because each color corresponds to a different instance
         # with 0 being background
         mask = Image.open(mask_path)
         
         # Convert from image object to array
         mask = np.array(mask)
         
         obj_ids = np.unique(mask)
         # I have four classes. 
         obj_ids = obj_ids[-4:]
         # The line in original code is
         # obj_ids =  obj_ids[1:]
         
         # split the color-encoded mask into a set
         # of binary masks
         masks = mask == obj_ids[:, None, None]
         
         # get bounding box coordinates for each mask
         num_objs = len(obj_ids)
         boxes = []
         for i in range(num_objs):
             pos = np.where(masks[i])
             xmin = np.min(pos[1])
             xmax = np.max(pos[1])
             ymin = np.min(pos[0])
             ymax = np.max(pos[0])
             boxes.append([xmin, ymin, xmax, ymax])
         
         boxes = torch.as_tensor(boxes, dtype=torch.float32)
         # there is only one class
         labels = torch.ones((num_objs,), dtype=torch.int64)
         masks = torch.as_tensor(masks, dtype=torch.uint8)
         
         image_id = torch.tensor([idx])
         area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
         # suppose all instances are not crowd
         iscrowd = torch.zeros((num_objs,), dtype=torch.int64)
         
         target = {}
         target["boxes"] = boxes
         target["labels"] = labels
         target["masks"] = masks
         target["image_id"] = image_id
         target["area"] = area
         target["iscrowd"] = iscrowd
         
         if self.transforms is not None:
             img, target = self.transforms(img, target)
         
         return img, target
         
     def __len__(self):
         return len(self.imgs)

This is an example of one of the masks.

Thanks for the follow up as it seems the bool indexing issue is indeed created in the __getitem__.
Could you check the types of all tensors where an indexing operation is used and make sure these are tensors? Your suspicion that the (bool) mask might be the issue could be right and maybe:

pos = np.where(masks[i])

is failing as you might expect mask to be a tensor while it could be a single bool value.

It took me a minute, since I’m as a lousy programmer. I wrote a bunch of loops to match the steps in the class that create the masks. I won’t include that tedious code here, but will add it if you insist on inspecting it. The following is probably tedious enough. :wink:

for i in range(4):             
     pos.append(np.where(mask1[i]))
     pos.append(np.where(mask2[i]))
     pos.append(np.where(mask3[i]))
     pos.append(np.where(mask4[i]))
     pos.append(np.where(mask5[i]))
     pos.append(np.where(mask6[i]))
     pos.append(np.where(mask7[i]))

>>> for i in boxes:
...     print(i)
... 
[470, 2337, 2354, 3238]
[472, 2346, 2339, 3238]
[470, 2340, 2344, 3238]
[470, 2372, 2329, 3237]
[470, 2337, 2354, 3238]
[472, 2346, 2339, 3238]
[470, 2340, 2344, 3238]
[470, 2372, 2329, 3237]

So it looks like the boxes are okay. I’m not sure what to check next…

I would add debug print statements to the __getitem__ and try to isolate which lines exactly fails and what the indexed object contains.

Thanks, ptrblck. I’ve got it now. It looks like I had my paths and files partially crossed. The TypeError is now replaced with another error. I’ll mess around with that some and maybe ask another question later.

I appreciate your help!

Best regards.