-1

I have a neural network for image processing. All images are greyscaled,resized and labeled. I made a neural network model in PyTorch.

class CarBrand(nn.Module):
    def __init__(self, num_classes):
        super(CarBrand, self).__init__()

        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1)

        self.fc1 = nn.Linear(128*300*300*1, 512) # fully connected layers
        self.fc2_class = nn.Linear(512, num_classes)           
        self.relu = nn.ReLU()
        self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
        
    def forward(self, x):
        x = self.relu(self.conv1(x))
        x = self.maxpool(x)        
        x = self.relu(self.conv2(x))
        x = self.maxpool(x)       
        x = self.relu(self.conv3(x))
        x = self.maxpool(x)
        x = x.view(x.size(0), -1)
        x = self.relu(self.fc1(x))
        brand_pred = self.fc2_class(x)      
        return brand_pred

class CarBrandDataset(Dataset):
    def __init__(self, data_dir, transform=None):
        self.data_dir = data_dir
        self.transform = transform
        self.image_paths = [filename for filename in os.listdir(data_dir) if filename.endswith('.jpg')]

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

    def __getitem__(self, index):
        image_path = os.path.join(self.data_dir, self.image_paths[index])
        xml_path = os.path.splitext(image_path)[0] + '.xml'

        image = Image.open(image_path).convert('L') # convert to greyscale
        if self.transform:
            image.transform(image.size, Image.AFFINE, image) 
            
        # parse XML
        tree = ET.parse(xml_path)
        root = tree.getroot()
        # extract label information from XML 
        brand_label_mapping = {
            'bmw': 0,
            'citroen': 1,
            'mercedes': 2,
            'maserati': 3,
            'audi': 4,
            'honda': 5
        }
        brand_label_str = root.text
        brand_label =  brand_label_mapping.get(brand_label_str, -1)
        return image, brand_label
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5], std=[0.5]),
    transforms.Resize(300)
])

data_dir = "split_data/train" 
dataset = CarBrandDataset(data_dir, transform=transform) 
batch_size = 32 
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

When I start train it ,

    running_loss = 0.0
    for images, brand_labels in dataloader:
        optimizer.zero_grad()

        brand_pred = model(images)

        loss_brand = criterion_class(brand_pred, brand_labels)
 
        loss_brand.backward()
        optimizer.step()

        running_loss += loss_brand.item()

I get this error, I tried to fix it but I couldn't manage to do that.

C:\Users\Cihan\AppData\Local\Temp\ipykernel_17820\2575177316.py:23: DeprecationWarning: AFFINE is deprecated and will be removed in Pillow 10 (2023-07-01). Use Transform.AFFINE instead.
  image.transform(image.size, Image.AFFINE, image)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 9
      7 for epoch in range(num_epochs):
      8     running_loss = 0.0
----> 9     for images, brand_labels in dataloader:
     10         optimizer.zero_grad()
     12         brand_pred = model(images)

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\torch\utils\data\dataloader.py:633, in _BaseDataLoaderIter.__next__(self)
    630 if self._sampler_iter is None:
    631     # TODO(https://github.com/pytorch/pytorch/issues/76750)
    632     self._reset()  # type: ignore[call-arg]
--> 633 data = self._next_data()
    634 self._num_yielded += 1
    635 if self._dataset_kind == _DatasetKind.Iterable and \
    636         self._IterableDataset_len_called is not None and \
    637         self._num_yielded > self._IterableDataset_len_called:

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\torch\utils\data\dataloader.py:677, in _SingleProcessDataLoaderIter._next_data(self)
    675 def _next_data(self):
    676     index = self._next_index()  # may raise StopIteration
--> 677     data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
    678     if self._pin_memory:
    679         data = _utils.pin_memory.pin_memory(data, self._pin_memory_device)

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\torch\utils\data\_utils\fetch.py:51, in _MapDatasetFetcher.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]

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\torch\utils\data\_utils\fetch.py:51, in <listcomp>(.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]

Cell In[16], line 23, in CarBrandDataset.__getitem__(self, index)
     21 image = Image.open(image_path).convert('L') # convert to greyscale
     22 if self.transform:
---> 23     image.transform(image.size, Image.AFFINE, image) 
     24 # if self.transform:
     25 #     image = self.transform(image)
     26     
     27 # parse XML
     28 tree = ET.parse(xml_path)

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\PIL\Image.py:2631, in Image.transform(self, size, method, data, resample, fill, fillcolor)
   2627         im.__transformer(
   2628             box, self, Transform.QUAD, quad, resample, fillcolor is None
   2629         )
   2630 else:
-> 2631     im.__transformer(
   2632         (0, 0) + size, self, method, data, resample, fillcolor is None
   2633     )
   2635 return im

File ~\OneDrive\Masaüstü\plate\pytorchNN\Lib\site-packages\PIL\Image.py:2644, in Image.__transformer(self, box, image, method, data, resample, fill)
   2641 h = box[3] - box[1]
   2643 if method == Transform.AFFINE:
-> 2644     data = data[:6]
   2646 elif method == Transform.EXTENT:
   2647     # convert extent to an affine transform
   2648     x0, y0, x1, y1 = data

TypeError: 'Image' object is not subscriptable*

I have tried converting image object to a numpy array but it did not work, I have no idea what should I do in order to solve that problem. Edit:I added 'dataloader', sorry I forgot to add it.

  • Where do you assign `dataloader`? You apparently expect it to be a list, but it's just a single item. – Barmar Aug 10 '23 at 16:36
  • I assign it in here from torch.utils.data import DataLoader data_dir = "split_data/train" dataset = CarBrandDataset(data_dir, transform=transform) batch_size = 32 dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) – Cihan Yalçın Aug 10 '23 at 17:02
  • Don't put code in comments, add that to the question. – Barmar Aug 10 '23 at 17:02
  • Is this the error verbatim? I get the feeling you edited the error to make it shorter. – Dr. Snoopy Aug 10 '23 at 17:46
  • I added full error message, it was too long,because of that I did not added at first – Cihan Yalçın Aug 10 '23 at 18:23
  • I think you now see why shortening was a bad idea, as people were misinterpreting the error message. The problem is that you have to convert your Image to a numpy array before passing it to PyTorch. – Dr. Snoopy Aug 10 '23 at 18:27

1 Answers1

0

You are calling the PIL.Image.transform method incorrectly. The data argument is not supposed to be the image data, but extra data that is required for some of the transforms (e.g. the xmin, ymin, xmax, ymax for an EXTENT transform). And the transformed image is returned by the method, not applied to the existing image, so as is your transformation would be thrown away.

Instead of

image.transform(image.size, Image.AFFINE, image)

you want

image = image.transform(image.size, Image.AFFINE, data)

where data are the parameters for your affine transformation.

See, for example, Python/PIL affine transformation for details on the data parameters.

Malcolm
  • 461
  • 2
  • 10