# MobileNet-V2 PyTorch implementation

**URL:** <https://discuss.pytorch.org/t/mobilenet-v2-pytorch-implementation/112612>\
**Category:** vision\
**Created:** [February 22, 2021, 2:03pm UTC](https://discuss.pytorch.org/t/mobilenet-v2-pytorch-implementation/112612 "2021-02-22T14:03:17Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aryan\_Asadian](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/aryan_asadian/32/27084_2.png) [@Aryan\_Asadian](https://discuss.pytorch.org/u/Aryan_Asadian)\
**Post date:** [February 22, 2021, 2:03pm UTC](https://discuss.pytorch.org/t/mobilenet-v2-pytorch-implementation/112612/1 "2021-02-22T14:03:17Z")

</div>

I was trying to re-implement MobileNet-V2 according to the [paper](https://openaccess.thecvf.com/content_cvpr_2018/papers/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.pdf). Based on Table 2(Page 5) of the paper, after the sequence of Inverted residual blocks, there should be 2 other regular convolutional layers. But in [Pytorch’s implementation](https://github.com/pytorch/vision/blob/62e185c7ee6df9938809bc0aec353bbcad1f1223/torchvision/models/mobilenetv2.py#L31), the second regular convolutional layer(last row in table 2) has been removed. What is the reason for this modification?

---

<div class="post-metadata">

**Author:** ![ksz](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@ksz](https://discuss.pytorch.org/u/ksz)\
**Post date:** [February 22, 2021, 8:36pm UTC](https://discuss.pytorch.org/t/mobilenet-v2-pytorch-implementation/112612/2 "2021-02-22T20:36:19Z")

</div>

I am not sure, but it seems that everything is correct. Last row: `conv2d 1x1` is just a classifier. You can use the convolution layer with filter 1x1 instead of the Linear layer. The output will be the same - for a mathematical point of view, they are the same operations. I suppose that authors use that kind of format in the table to keep the same conventions - without introducing a new type of layer.

See example:

```auto

number_of_classes = 1000
batch_size = 512
i = torch.rand(batch_size, 1280, 7, 7)

class NetworkA(torch.nn.Module):
    def __init__ (self):
        super(NetworkA, self). __init__ ()
        self.linear = torch.nn.Linear(1280, number_of_classes)
        
    def forward(self, x):
        x = torch.nn.functional.adaptive_avg_pool2d(x, (1, 1)).reshape(x.shape[0], -1)
        return self.linear(x)
    
class NetworkB(torch.nn.Module):
    def __init__ (self):
        super(NetworkB, self). __init__ ()
        self.conv = torch.nn.Conv2d(1280, number_of_classes, kernel_size=1)
        
    def forward(self, x):
        x = torch.nn.functional.adaptive_avg_pool2d(x, (1, 1))
        return self.conv(x).reshape(x.shape[0], -1)    
    
netA = NetworkA()
print(netA(i).shape)

netB = NetworkB()
print(netB(i).shape)

```

The result:

```auto
torch.Size([512, 1000])
torch.Size([512, 1000])

```
