RuntimeError: Given groups=1, weight of size [64, 3, 7, 7], expected input[3, 1, 224, 224] to have 3 channels, but got 1 channels instead

test_data.unsqueeze_(0)

1 Like

Your input images had only one channel, which is not consistent with three channels RGB image in ResNet50 network. You should change Input dim in ResNet50 or convert your images to three channels.

because I had only one or two of my images like so I manually fixed them:

import cv2
import numpy as np
img = cv2.imread('110249.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray
cv2.imwrite('110249.jpg', img2)
2 Likes

i tried the above but am still getting a “Given groups=1, weight of size [64, 3, 7, 7], expected input[4, 1, 224, 224] to have 3 channels, but got 1 channels instead” error.
Did you find any other way to go about it
This is my model arch.

1 Like

What are the dimensions in your [4, 1, 224, 224] input? They should be NCHW (batch size, number of channels, height, width).

If that’s the case, then it means you have 4 examples in your batch, 1 channel (grayscale image) and 224x224 images. If you want the code to work, you need to change either your input to have 3 channels (duplicate the gray channel for RGB) or change the model to accept 1 channel images. For the second solution you need to modify the model code (e.g. by copying the source in your own codebase and changing what you need).

As seen in the Densenet source code, the first convolution expects 3 channels as input.

2 Likes

I faced the same problem and alex has explained it properly.

Use this, to convert a [H,W,C] into [C,H,W]
For including batch_size(N) use DataLoader, it will automatically include
image = image.transpose((2, 0, 1))

3 Likes

this one worked for me

Given groups=1, weight of size 64 1 7 7, expected input[64, 3, 160, 160] to have 1 channels, but got 3 channels instead

I am getting the above error even whilst giving 3 input channels.
This is my architecture code.

class Dnet_1ch(nn.Module):
def __init__(self, arch=arch, n=nunique, pre=True, ps=0.5):
    super().__init__()
    m = arch(True) if pre else arch()
    
    conv = nn.Conv2d(3, 64, kernel_size=5, stride=2, padding=3, bias=False)
    w = (m.features.conv0.weight.sum(1)).unsqueeze(1)
    conv.weight = nn.Parameter(w)
    
    self.layer0 = nn.Sequential(conv, m.features.norm0, nn.ReLU(inplace=True))
    self.layer1 = nn.Sequential(
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False),
        m.features.denseblock1)
    self.layer2 = nn.Sequential(m.features.transition1,m.features.denseblock2)
    self.layer3 = nn.Sequential(m.features.transition2,m.features.denseblock3)
    self.layer4 = nn.Sequential(m.features.transition3,m.features.denseblock4,
                                m.features.norm5)
    
    nc = self.layer4[-1].weight.shape[0]
    self.head1 = Head(nc,n)
    #to_Mish(self.layer0), to_Mish(self.layer1), to_Mish(self.layer2)
    #to_Mish(self.layer3), to_Mish(self.layer4)
    
def forward(self, x):    
    x = self.layer0(x)
    x = self.layer1(x)
    x = self.layer2(x)
    x = self.layer3(x)
    x = self.layer4(x)
    
    x1 = self.head1(x)
    
    return x1

Can you figure out what the problem is?

You are setting the input channels of the first convolution to a single channel in these lines of code:

conv = nn.Conv2d(3, 64, kernel_size=5, stride=2, padding=3, bias=False)
w = (m.features.conv0.weight.sum(1)).unsqueeze(1)
conv.weight = nn.Parameter(w)

while you are passing an input with 3 channels.
Either leave the convolution as it is with in_channels=3 or change the number of channels in your input tensor to a single channel, e.g. by slicing.

1 Like

Thanks for the response. I corrected it.

When does “CUDA error: device-side assert triggered” generally occur?

Generally whenever an assert statement is violated.
E.g. if you are using nn.NLLLoss as the criterion and pass a target with out of bounds values, this line of code will raise this issue.

Note that CUDA operations are asynchronous, so whenever you encounter an error running with CUDA, I would suggest to make sure the code works fine using the CPU (as this might give you a better error message), and if that’s the case run the code with CUDA_LAUNCH_BLOCKING=1 python script.py args.

Thanks for the help. I rectified it.

data_preprocess = transforms.Compose([
        #transforms.RandomResizedCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
def preprocess_input(img):
  x = data_preprocess(img)
  return x.unsqueeze_(0).to(device)
def display_img_pred_and_heatmap(path,model,label=None):
  original_img = cv.imread(path)
  original_img = cv.resize(original_img, (224,224))
  #print("original_img: " , original_img.shape)
  row_size = original_img.shape[0]
  col_size = original_img.shape[1]
  plt.imshow(cv.cvtColor(original_img, cv.COLOR_BGR2RGB))
  plt.show()
  preprocessed_img = preprocess_input(original_img)
  sub_model = nn.Sequential(*list(model.children())[:-1])
  print("sub_model: ",sub_model)
  print("sub_model(preprocessed_img).shape: ",sub_model(preprocessed_img).shape)

I am getting a similar error when I try to get output from an intermediate layer. I don’t get any errors when I try to get output from the complete model. How should I fix it?

RuntimeError: Given groups=1, weight of size [1024, 512, 3, 3], expected input[1, 200, 14, 14] to have 512 channels, but got 200 channels instead

Update: I don’t get any error when I change sub_model = nn.Sequential(*list(model.children())[:-1]) to sub_model = nn.Sequential(*list(model.children())[:-6])

This is my model:

class myModel5(nn.Module):

    def __init__(self, features, num_classes=200, **kwargs):
        super(myModel5, self).__init__()
        self.features = features
        self.conv6 = nn.Conv2d(512,  1024, kernel_size=3, padding=1) 
        self.conv7 = nn.Conv2d(1024, num_classes, kernel_size=1)
        self.conv8 = nn.Conv2d(512,  1024, kernel_size=3, padding=1) 
        self.conv9 = nn.Conv2d(1024, num_classes, kernel_size=1)
        self.relu = nn.ReLU(inplace=False)
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        #self.fc = nn.Linear(1024, num_classes)
        initialize_weights(self.modules(), init_mode='he')
    def forward(self, x, labels=None, return_cam=False):
        batch_size = x.shape[0]
        x1 = self.features(x)
        x1 = self.conv6(x1)
        x1 = self.relu(x1)
        x1 = self.conv7(x1)
        x1 = self.relu(x1)
        x2 = self.features(x)
        x2 = self.conv8(x2)
        x2 = self.relu(x2)
        x2 = self.conv9(x2)
        x2 = self.relu(x2)
        x = x1 + x2

Well, you are asking it to feed the output of conv7 into conv8, which is clearly unintended. So think about what you actually want to do.

How do I get outputs of conv7 and conv9 then?

There are many ways to accomplish that, one way would be

submodel = nn.Sequential(
    model.features,
    model.conv6,
    model.relu,
    model.conv7,
    model.relu
)

To get the output of relu(conv7). Children will return registered submodules, which means as they are added in __init__. Since relu is applied multiple times in forward, you can’t just take children.

Another way would be to just return the intermediate values along with final value in the forward.

1 Like

Hello, Am also facing a related challenge, Here is the error i get when i try to load an image into a CNN,

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

Below is my code
class Network(nn.Module):
def init(self, in_channels=3):
print("\ninitalizing “Network”")
super(Network,self).init()
#create 4 input Conv. layers
self.Conv1 = nn.Sequential(
nn.Conv2d(in_channels, 16, 3),
nn.MaxPool2d(2,2),
nn.Conv2d(16,16, 3, stride=1, padding=1), nn.ReLU(),
nn.Conv2d(16, 16, 3), nn.ReLU(),
nn.Conv2d(16, 16, 3))

     self.Conv2 = nn.Sequential(
	        nn.Conv2d(in_channels, 16, 3),
            nn.MaxPool2d(2,2),
			nn.Conv2d(16, 8, 3, stride=1, padding=1), nn.ReLU(),
            nn.Conv2d(8, 16, 3, padding=1), nn.ReLU(),
            nn.Conv2d(16, 16, 3))

     self.Conv3 =  nn.Sequential(
	        nn.Conv2d(in_channels, 16,3),
            nn.MaxPool2d(2,2),
		    nn.Conv2d(16, 4, 3,stride=1, padding=1), nn.ReLU(),
            nn.Conv2d(4, 16, 3, padding=1), nn.ReLU(),
            nn.Conv2d(16, 16, 3))

     self.Conv4 =nn.Sequential(
	        nn.Conv2d(in_channels, 16, 3),
            nn.MaxPool2d(2,2),
			nn.Conv2d(16, 2, 3, stride=1, padding=1), nn.ReLU(),
            nn.Conv2d(2, 16,  3, padding=1),nn.ReLU(),
            nn.Conv2d(16, 16,  3))

     self.Upsample1 = nn.Sequential(
              nn.Upsample(size=(16, 16), scale_factor=None,align_corners=True, mode="bilinear"),
              nn.Conv2d(16, 64, 3, stride=1, padding=1) ,nn.ReLU(),
              nn.MaxPool2d(3,2),
              nn.Conv2d(64, 32, 3, stride=1),nn.ReLU(),
              
              nn.Upsample(size=(32, 32), scale_factor=None,align_corners=True, mode='bilinear'),
              nn.Conv2d(32, 16, 3, stride=1, padding=1),nn.ReLU(),
              nn.MaxPool2d(2,2),
              nn.Conv2d(16, 8, 3, stride=1),nn.ReLU(),
              
              nn.Upsample(size=(8, 8), scale_factor=None,align_corners=True, mode='bilinear'),
              nn.Conv2d(8, 4, 3, stride=1, padding=1),nn.ReLU(),
              nn.MaxPool2d(2,2),
              nn.Conv2d(4, 2, 3),nn.ReLU())
              

     self.Upsample2 = nn.Sequential(
              nn.Upsample(size=(16, 16), scale_factor=None,align_corners=True, mode='bilinear'),
              nn.Conv2d(16, 64, 3, stride=2, padding=1),nn.ReLU(),
              nn.MaxPool2d(2,2),
              nn.Conv2d(64, 16, 3, stride=2),nn.ReLU(),
              
              nn.Upsample(size=(16, 16), scale_factor=None,align_corners=True, mode='bilinear'),
              nn.Conv2d(16, 4, 3, stride=2, padding=1),nn.ReLU(),
              nn.MaxPool2d(2,2),
              nn.Conv2d(4, 4, 3),nn.ReLU())              
                
     self.Upsample3 = nn.Sequential(
              nn.Upsample(size=(16, 16), scale_factor=None,align_corners=True, mode='bilinear'),
              nn.Conv2d(16, 64, 3, stride=2, padding=1),nn.ReLU(),
              nn.MaxPool2d(2,2),
              nn.Conv2d(64, 8, 3),nn.ReLU())
     
     self.Conv1a = nn.Conv2d(3, 16, 3, padding=1)
     self.Conv2a = nn.Conv2d(4, 16, 3, padding=1)                   
     self.Conv3a = nn.Conv2d(8, 16, 3, padding=1)
     self.Conv4a = nn.Conv2d(16,16, 3) 
     self.Conv5 =  nn.Conv2d(64 ,3, 3 )
  
def forward(self,image):
   
    w = self.Conv1(image)
    w = self.Upsample1(w)
    w=  F.relu(self.Conv1a(w))

    k = self.Conv2(image)
    k = self.Upsample2(k)
    k=  F.relu(self.Conv2a(k))

    y = self.Conv3(image)
    y = self.Upsample3(y)
    y=  F.relu(self.Conv3a(y))

    z = self.Conv4(image)
    z=  F.relu(self.Conv4a(z))
    
    p = torch.cat([w, k, y, z], dim=1)
    p = F.relu(self.fc1(p))
    p = self.fc2(p)

    q = self.Conv5(p)


    q = self.out(q)
    return q

I guess the first conv layer is using in_channels=3 and is raising this error, since you are passing an input with two channels in the shape [2, 2, 2, 2].
Note that even if you use 3 channels ([2, 3, 2, 2]), the spatial size would still be too small for the model, since the first conv layer uses a kernel size of 3, which is bigger than the input.

Thank you for the observation @ptrblck, its true the the first conv. is raising the error, how should i go about it?

1 Like