How can I know the exact dimensions for a layer that I am adding (to an already existing architecture)

I am adding the following code in resnet18 custom code

self.layer1 = self._make_layer(block, 64, layers[0]) ## code existed before
self.layer2 = self._make_layer(block, 128, layers[1], stride=2) ## code existed before
self.layer_attend1 =  nn.Sequential(nn.Conv2d(layers[0], layers[0], stride=2, padding=1, kernel_size=3),
                                     nn.AdaptiveAvgPool2d(1),
                                     nn.Softmax(1)) ## code added by me

and also the following in its forward pass (def forward(self, x)) in the same resnet18 custom code:

x = self.layer1(x) ## the code existed before
x = self.layer_attend1(x)*x ## I added this code
x = self.layer2(x) ## the code existed before

and I get the following error. I had no error before adding this attention layer. Any idea how I could fix it?

=> loading checkpoint 'runs/nondisjoint_l2norm/model_best.pth.tar'
=> loaded checkpoint 'runs/nondisjoint_l2norm/model_best.pth.tar' (epoch 5)
/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at  /pytorch/c10/core/TensorImpl.h:1156.)
  return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)
Traceback (most recent call last):
  File "main.py", line 352, in <module>
    main()    
  File "main.py", line 153, in main
    test_acc = test(test_loader, tnet)
  File "main.py", line 248, in test
    embeddings.append(tnet.embeddingnet(images).data)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/scratch3/research/code/fashion/fashion-compatibility/type_specific_network.py", line 101, in forward
    embedded_x = self.embeddingnet(x)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/scratch3/research/code/fashion/fashion-compatibility/Resnet_18.py", line 110, in forward
    x = self.layer_attend1(x)*x #so we don;t use name x1
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/container.py", line 139, in forward
    input = module(input)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 443, in forward
    return self._conv_forward(input, self.weight, self.bias)
  File "/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 439, in _conv_forward
    return F.conv2d(input, weight, bias, self.stride,
RuntimeError: Given groups=1, weight of size [2, 2, 3, 3], expected input[256, 64, 28, 28] to have 2 channels, but got 64 channels instead

Additionally, could you please suggest how to get information without print? (print doesn’t work). For example, I want to print layers[0] information but nothing gets printed.

I am also not sure how to debug this in VSCode. I added a breakpoint on the line before the problematic one (new layer), and it didn’t even go or stop there.

What do you mean by “nothing gets printed”? If you add the line

print("Hi")

at the place where you were trying to print layers[0], does it print anything? (It should …)

To know the dimensions that go into the layer you added, you can try something like this:

x = self.layer1(x) ## the code existed before
print("The input shape is: " + str(x.shape))
x = self.layer_attend1(x)*x ## I added this code
x = self.layer2(x) ## the code existed before
1 Like

actually I just now put the breakpoint in the

class ResNet(nn.Module):

    def __init__(self, block, layers, embedding_size=64):

and was able to print value of layers[0] which is 2. Previously put the breakpoint in forward pass and it just jumped to the error.

Anyhow, still not sure how to fix this error I am getting.

the input shape is The input shape is: torch.Size([256, 64, 28, 28])

knowing that the input shape is: torch.Size([256, 64, 28, 28])

how should I change the following?

self.layer_attend1 =  nn.Sequential(nn.Conv2d(layers[0], layers[0], stride=2, padding=1, kernel_size=3),
                                     nn.AdaptiveAvgPool2d(1),
                                     nn.Softmax(1))

The error is
RuntimeError: Given groups=1, weight of size [2, 2, 3, 3], expected input[256, 64, 28, 28] to have 2 channels, but got 64 channels instead

and the layers[0] is 2

@gphilip

Thank you

In [256, 64, 28, 28] the 256 is the batch size. So each input tensor to the first layer in self.layer_attend1 has the shape [64, 28, 28]. Of this, the 64 is the number of channels in the input. The first argument to nn.Conv2d should therefore be 64.

1 Like

Thanks for your response. So I changed it to

self.layer_attend1 =  nn.Sequential(nn.Conv2d(64, 64, stride=2, padding=1, kernel_size=3),
                                                         nn.AdaptiveAvgPool2d(1),
                                                         nn.Softmax(1))

Do you think if it is wrong or could you please show how to fill the args of nn.Conv2d(64, 64, stride=2, padding=1, kernel_size=3) otherwise?

Here is the documentation for nn.Conv2d. Only the first argument depends on the input. You have to choose the remaining arguments based on what you want out of the convolution layer. See the section on “Shape” in that link for the details on how the output height and width are calculated from the arguments.

1 Like

so maybe i ask my question this way:

how do I know what’s the value or best value for out_channel? currently I have set it to 64.

This is a design decision that you have to make, depending on what you want this layer to do.

1 Like

I have a question for you, if self.layer_attend1 is nn.sequential of three other layers, how would you be able to print the output size of the middle layer?

Here, is the layer_attend1:

self.layer_attend1 =  nn.Sequential(nn.Conv2d(64, 64, stride=2, padding=1, kernel_size=3),
                                    nn.AdaptiveAvgPool2d(1),
                                    nn.Softmax(1))

and i want to know the shape of output of nn.AdaptiveAvgPool2d(1)

is there a way to do so?

Assuming that the shape of the inptu to self.layer.attend1 is torch.Size([256, 64, 28, 28]) like you said above, this can be done using the following code:

X = torch.randn([256, 64, 28, 28])
Y = nn.Conv2d(64, 64, stride=2, padding=1, kernel_size=3)(X)
Z = nn.AdaptiveAvgPool2d(1)(Y)

print(Z.shape)
1 Like

Thanks a lot, so is it wrong to pass
torch.Size([256, 64, 1, 1])
to a softmax(1)?

i am not getting any error but my accuracy has dropped significantly and it seems softmax is not working as expected hence thought maybe i should change the arg inside softmax from 1 to something else that I am not sure what it is.

a bit explanation here How to stack adaptiveavgpool2D and softmax?

Since the code is not throwing an error, it is clearly not a wrong-shaped input to pass to this function.

1 Like