TypeError: Compose.__call__() takes 2 positional arguments but 3 were given

my code is which is generating error is:

class ToTensor(object):
def call(self, sample):
image, mask = sample
image = torch.from_numpy(image).permute(2, 0, 1).float().unsqueeze(0)
mask = torch.from_numpy(mask).long()
return image, mask

transform = transforms.Compose([ToTensor()])
train_dataset = CustomDataset(image_paths, mask_paths, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=2, shuffle=True)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
num_epochs = 10

for epoch in range(num_epochs):
for images, masks in train_loader:
optimizer.zero_grad()

    outputs = model(images)
    loss = criterion(outputs['out'], masks)

    loss.backward()
    optimizer.step()

print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')

and the error is:


TypeError Traceback (most recent call last)
in <cell line: 2>()
1 num_epochs = 10
2 for epoch in range(num_epochs):
----> 3 for images, masks in train_loader:
4 optimizer.zero_grad()
5

4 frames
in getitem(self, idx)
15 # Apply transformations
16 if self.transform:
—> 17 image, mask = self.transform(image, mask)
18
19 return image, mask

TypeError: Compose.call() takes 2 positional arguments but 3 were given
can anyone help me with that

You would have to pass each tensor separately to your transformation as the error message explains.

1 Like

thanks in advance for your help. sorry if am asking a really silly question am new to the frame work. i tried using

class CustomDataset(Dataset):
def init(self, image_paths, mask_paths, transform=None):
self.image_paths = image_paths
self.mask_paths = mask_paths
self.transform = transform

def __len__(self):
    return len(self.image_paths)

def __getitem__(self, idx):
    image = load_tiff_image(self.image_paths[idx])
    mask = load_tiff_masks(self.mask_paths[idx])

    if self.transform:
          image, mask = self.transform(image, mask)

    return image, mask

class ToTensor(object):
def call(self, image, mask):
image = torch.from_numpy(image).permute(2, 0, 1).float()
mask = torch.from_numpy(mask).long()
return image, mask

class Resize(object):
def init(self, size):
self.size = size

def __call__(self, image, mask):
    image = tifffile.resize(image, self.size)
    mask = tifffile.resize(mask, self.size)

    return image, mask

def load_tiff_image(file_path):
image = tifffile.imread(file_path)
image = (image - image.min()) / (image.max() - image.min())

return image

def load_tiff_masks(file_path):
mask = tifffile.imread(file_path)
mask = (mask > 0).astype(np.uint8)

return mask

image_folder = “/content/drive/MyDrive/solafun_detectsolarpanels/data/train/s2_image”
mask_folder = “/content/drive/MyDrive/solafun_detectsolarpanels/data/train/mask”

image_file_names = os.listdir(image_folder)
mask_file_names = os.listdir(mask_folder)

image_paths = sorted([os.path.join(image_folder, name) for name in image_file_names])
mask_paths = sorted([os.path.join(mask_folder, name) for name in mask_file_names])

assert len(image_paths) == len(mask_paths), “Number of images and masks do not match”

transform = transforms.Compose([Resize((256, 256)), ToTensor()])
train_dataset = CustomDataset(image_paths, mask_paths, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=2, shuffle=True, collate_fn=lambda x: tuple(zip(*x)))
for images, masks in train_loader:
print(“Batch Size:”, images.shape[1])
print(“Image Shape:”, images.shape[1:])
print(“Mask Shape:”, masks.shape[1:])
break

but still am getting the same error


TypeError Traceback (most recent call last)
in <cell line: 1>()
----> 1 for images, masks in train_loader:
2 print(“Batch Size:”, images.shape[1])
3 print(“Image Shape:”, images.shape[1:])
4 print(“Mask Shape:”, masks.shape[1:])
5 break

4 frames
/usr/local/lib/python3.10/dist-packages/torch/utils/data/dataloader.py in next(self)
628 # TODO(Bug in dataloader iterator found by mypy · Issue #76750 · pytorch/pytorch · GitHub)
629 self._reset() # type: ignore[call-arg]
→ 630 data = self._next_data()
631 self._num_yielded += 1
632 if self._dataset_kind == _DatasetKind.Iterable and \

/usr/local/lib/python3.10/dist-packages/torch/utils/data/dataloader.py in _next_data(self)
672 def _next_data(self):
673 index = self._next_index() # may raise StopIteration
→ 674 data = self._dataset_fetcher.fetch(index) # may raise StopIteration
675 if self._pin_memory:
676 data = _utils.pin_memory.pin_memory(data, self._pin_memory_device)

/usr/local/lib/python3.10/dist-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)
49 data = self.dataset.getitems(possibly_batched_index)
50 else:
—> 51 data = [self.dataset[idx] for idx in possibly_batched_index]
52 else:
53 data = self.dataset[possibly_batched_index]

/usr/local/lib/python3.10/dist-packages/torch/utils/data/_utils/fetch.py in (.0)
49 data = self.dataset.getitems(possibly_batched_index)
50 else:
—> 51 data = [self.dataset[idx] for idx in possibly_batched_index]
52 else:
53 data = self.dataset[possibly_batched_index]

in getitem(self, idx)
13
14 if self.transform:
—> 15 image, mask = self.transform(image, mask)
16
17 return image, mask

TypeError: Compose.call() takes 2 positional arguments but 3 were given

can u suggest to me where i should put your suggustions?

Your custom ToTensor transformation would accept two inputs, but transforms.Compose does not. Since you are using a single transformation only, just use transform = ToTensor() or also provide a custom Compose transformation accepting multiple inputs.

1 Like