# VGG with 1x1 convolution

**URL:** <https://discuss.pytorch.org/t/vgg-with-1x1-convolution/57980>\
**Category:** vision\
**Created:** [October 11, 2019, 7:14pm UTC](https://discuss.pytorch.org/t/vgg-with-1x1-convolution/57980 "2019-10-11T19:14:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ricardborras](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/r/9dc877/32.png) [@ricardborras](https://discuss.pytorch.org/u/ricardborras)\
**Post date:** [October 11, 2019, 7:14pm UTC](https://discuss.pytorch.org/t/vgg-with-1x1-convolution/57980/1 "2019-10-11T19:14:53Z")

</div>

Hi,

given the first 5 layers of a VGG network:

Sequential(  
(0): Conv2d(3, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(1): ReLU(inplace=True)  
(2): Conv2d(64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(3): ReLU(inplace=True)  
(4): MaxPool2d(kernel\_size=2, stride=2, padding=0, dilation=1, ceil\_mode=False)  
(5): Conv2d(64, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(6): ReLU(inplace=True)  
(7): Conv2d(128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(8): ReLU(inplace=True)  
(9): MaxPool2d(kernel\_size=2, stride=2, padding=0, dilation=1, ceil\_mode=False)  
(10): Conv2d(128, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(11): ReLU(inplace=True)  
(12): Conv2d(256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(13): ReLU(inplace=True)  
(14): Conv2d(256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(15): ReLU(inplace=True)  
(16): MaxPool2d(kernel\_size=2, stride=2, padding=0, dilation=1, ceil\_mode=False)  
(17): Conv2d(256, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(18): ReLU(inplace=True)  
(19): Conv2d(512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(20): ReLU(inplace=True)  
(21): Conv2d(512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(22): ReLU(inplace=True)  
(23): MaxPool2d(kernel\_size=2, stride=2, padding=0, dilation=1, ceil\_mode=False)  
(24): Conv2d(512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(25): ReLU(inplace=True)  
(26): Conv2d(512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(27): ReLU(inplace=True)  
(28): Conv2d(512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1))  
(29): ReLU(inplace=True)  
(30): MaxPool2d(kernel\_size=2, stride=2, padding=0, dilation=1, ceil\_mode=False)  
)

How to add a layer to classify each activation into n\_classes? I am trying with a 1x1 convolution from 512 (number of filters in last layer) to n\_classes, something like this:

nn.Sequential(  
nn.Conv2d(in\_channels=512, out\_channels=n\_classes, kernel\_size=1),  
nn.Softmax(dim=1)  
)  
This network gives (batch\_size, n\_classes H // 32, W // 32) outputs. However, all outputs for each class are equal for a given image, I mean that, for a given batch, B and class C, all values are the same.

I have tried training with CrossEntropyLoss and even converting to logits and applying BCELoss, but without success. I also have tried other networks in my train loop and this do not happens.

Any clue?

Thanks

---

<div class="post-metadata">

**Author:** ![mailcorahul](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mailcorahul/32/15919_2.png) [@mailcorahul](https://discuss.pytorch.org/u/mailcorahul)\
**Post date:** [October 12, 2019, 12:16pm UTC](https://discuss.pytorch.org/t/vgg-with-1x1-convolution/57980/2 "2019-10-12T12:16:30Z")

</div>

You can use `nn.AdaptiveAvgPool2d` to reduce the spatial dimensions to 1x1(HxW) and then use 1x1 convolution to bring num\_filters = num\_classes. Use this after the last conv output from vgg.

```auto
self.classifier = nn.Sequential(
          nn.AdaptiveAvgPool2d((1, 1)), 
          nn.Conv2d(in_channels=512, out_channels=n_classes, kernel_size=1),
          nn.ReLU(inplace=True)
         )

```

Given what you have done above, I am not sure how you were able to calculate loss since the output will be num\_classes, H//32, W//32. However one important thing to note is, do not use `nn.Softmax` at the end of the network when using `nn.CrossEntropy`(it combines softmax and nll loss). That can cause problems.

---

<div class="post-metadata">

**Author:** ![ricardborras](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/r/9dc877/32.png) [@ricardborras](https://discuss.pytorch.org/u/ricardborras)\
**Post date:** [October 12, 2019, 7:33pm UTC](https://discuss.pytorch.org/t/vgg-with-1x1-convolution/57980/3 "2019-10-12T19:33:33Z")

</div>

Hi,

thanks for the tip, I have removed Softmax from classification layer. Also, I found my mistake: it was a problem of weight initialization of last 1x1 convolution layer. Now the network is learning properly.

many thanks
