Given groups=1, weight of size [32, 1, 3, 3], expected input[100, 3, 112, 112] to have 1 channels, but got 3 channels instead

I am trying to train a CNN classifier with PyTorch for traffic sign recognition GTSRB.

I downloaded GTSRB_Final_Training_Images.zip and GTSRB_Final_Test_Images.zip and putted them under GTSRB/Train and GTSRB/Test respectively.

My code:


import torch
import torch.nn as nn
import torch.optim as optim

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class Flatten(nn.Module):
    def forward(self, x):
        return x.view(x.shape[0], -1)    

model_cnn = nn.Sequential(nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(),
                          nn.Conv2d(32, 32, 3, padding=1, stride=2), nn.ReLU(),
                          nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(),
                          nn.Conv2d(64, 64, 3, padding=1, stride=2), nn.ReLU(),
                          nn.Flatten(),
                          nn.Linear(7*7*64, 100), nn.ReLU(),
                          nn.Linear(100, 10)).to(device)

data_transforms = transforms.Compose([
    transforms.Resize([112, 112]),
    transforms.ToTensor()
    ])

from torchvision import datasets, transforms
from torch.utils.data import DataLoader

train_data_path = "GTSRB/Train"
test_data_path = "GTSRB/Test"

train_data = datasets.ImageFolder(root = train_data_path, transform = data_transforms)
test_data = datasets.ImageFolder(root = test_data_path, transform = data_transforms)

train_loader = DataLoader(train_data, batch_size = 100, shuffle=True)
test_loader = DataLoader(test_data, batch_size = 100, shuffle=False)

def epoch(loader, model, opt=None):
    total_loss, total_err = 0.,0.
    for X,y in loader:
        X,y = X.to(device), y.to(device)
        yp = model(X)
        loss = nn.CrossEntropyLoss()(yp,y)
        if opt:
            opt.zero_grad()
            loss.backward()
            opt.step()
        
        total_err += (yp.max(dim=1)[1] != y).sum().item()
        total_loss += loss.item() * X.shape[0]
    return total_err / len(loader.dataset), total_loss / len(loader.dataset)

opt = optim.SGD(model_cnn.parameters(), lr=1e-1)
for _ in range(10):
    train_err, train_loss = epoch(train_loader, model_cnn, opt)
    test_err, test_loss = epoch(test_loader, model_cnn)
    print(*("{:.6f}".format(i) for i in (train_err, train_loss, test_err, test_loss)), sep="\t")

The error message:

~\anaconda3\envs\lab01\lib\site-packages\torch\nn\modules\conv.py in _conv_forward(self, input, weight, bias)
    394                             _pair(0), self.dilation, self.groups)
    395         return F.conv2d(input, weight, bias, self.stride,
--> 396                         self.padding, self.dilation, self.groups)
    397 
    398     def forward(self, input: Tensor) -> Tensor:

RuntimeError: Given groups=1, weight of size [32, 1, 3, 3], expected input[100, 3, 112, 112] to have 1 channels, but got 3 channels instead

What is wrong?

The first conv layer expects input tensors with a single channel, while your inputs contain 3 channels.
You would thus either have to change the first layer to:

nn.Conv2d(3, 32, 3, padding=1)

or use grayscale images.

1 Like

That makes sense!
Thank you.

I also changed some other parameters in the model to get it work:

     nn.Linear(4096, 100), nn.ReLU(),
     nn.Linear(100, 44)).to(device)