We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Mobilenet v2 width multiplier incorrect
There seems to be a small issue with the width multiplier in mobilenet v2.  The official implementation rounds filter channels to a multiple of 8.  

For example, mobilenet v2 width 1.4.  The first conv layer has 44 channels as opposed to 48 in the official implementation:
model = torchvision.models.mobilenet_v2(width_mult=1.4)

for module in model.modules():
    if isinstance(module, nn.Conv2d):
        print(module.weight.shape)

torch.Size([44, 3, 3, 3])
torch.Size([44, 1, 3, 3])
torch.Size([22, 44, 1, 1])
torch.Size([132, 22, 1, 1])
torch.Size([132, 1, 3, 3])
torch.Size([33, 132, 1, 1])


Corresponding tensorflow 2.0 keras code:
model = tf.keras.applications.MobileNetV2(
    weights="imagenet", input_shape=(224, 224, 3), alpha=1.4)
model.summary()

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 224, 224, 3) 0                                            
__________________________________________________________________________________________________
Conv1_pad (ZeroPadding2D)       (None, 225, 225, 3)  0           input_1[0][0]                    
__________________________________________________________________________________________________
Conv1 (Conv2D)                  (None, 112, 112, 48) 1296        Conv1_pad[0][0]                  
__________________________________________________________________________________________________
bn_Conv1 (BatchNormalization)   (None, 112, 112, 48) 192         Conv1[0][0]                      
__________________________________________________________________________________________________
Conv1_relu (ReLU)               (None, 112, 112, 48) 0           bn_Conv1[0][0]                   
__________________________________________________________________________________________________
expanded_conv_depthwise (Depthw (None, 112, 112, 48) 432         Conv1_relu[0][0]                 
__________________________________________________________________________________________________
expanded_conv_depthwise_BN (Bat (None, 112, 112, 48) 192         expanded_conv_depthwise[0][0]    
__________________________________________________________________________________________________
expanded_conv_depthwise_relu (R (None, 112, 112, 48) 0           expanded_conv_depthwise_BN[0][0] 
__________________________________________________________________________________________________
expanded_conv_project (Conv2D)  (None, 112, 112, 24) 1152        expanded_conv_depthwise_relu[0][0
__________________________________________________________________________________________________
expanded_conv_project_BN (Batch (None, 112, 112, 24) 96          expanded_conv_project[0][0]      
__________________________________________________________________________________________________
block_1_expand (Conv2D)         (None, 112, 112, 144 3456        expanded_conv_project_BN[0][0]   
__________________________________________________________________________________________________
block_1_expand_BN (BatchNormali (None, 112, 112, 144 576         block_1_expand[0][0]             
__________________________________________________________________________________________________
block_1_expand_relu (ReLU)      (None, 112, 112, 144 0           block_1_expand_BN[0][0]          
__________________________________________________________________________________________________
block_1_pad (ZeroPadding2D)     (None, 113, 113, 144 0           block_1_expand_relu[0][0]        
__________________________________________________________________________________________________
block_1_depthwise (DepthwiseCon (None, 56, 56, 144)  1296        block_1_pad[0][0]                
__________________________________________________________________________________________________
block_1_depthwise_BN (BatchNorm (None, 56, 56, 144)  576         block_1_depthwise[0][0]          
__________________________________________________________________________________________________
block_1_depthwise_relu (ReLU)   (None, 56, 56, 144)  0           block_1_depthwise_BN[0][0]       
__________________________________________________________________________________________________
block_1_project (Conv2D)        (None, 56, 56, 32)   4608        block_1_depthwise_relu[0][0]     
__________________________________________________________________________________________________


I've implemented a fix here:
https://github.com/yaysummeriscoming/vision/blob/master/torchvision/models/mobilenet.py

Can I merge it in?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torchvision/models/mobilenet.py`
Content:
```
1 from torch import nn
2 from .utils import load_state_dict_from_url
3 
4 
5 __all__ = ['MobileNetV2', 'mobilenet_v2']
6 
7 
8 model_urls = {
9     'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth',
10 }
11 
12 
13 class ConvBNReLU(nn.Sequential):
14     def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
15         padding = (kernel_size - 1) // 2
16         super(ConvBNReLU, self).__init__(
17             nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False),
18             nn.BatchNorm2d(out_planes),
19             nn.ReLU6(inplace=True)
20         )
21 
22 
23 class InvertedResidual(nn.Module):
24     def __init__(self, inp, oup, stride, expand_ratio):
25         super(InvertedResidual, self).__init__()
26         self.stride = stride
27         assert stride in [1, 2]
28 
29         hidden_dim = int(round(inp * expand_ratio))
30         self.use_res_connect = self.stride == 1 and inp == oup
31 
32         layers = []
33         if expand_ratio != 1:
34             # pw
35             layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))
36         layers.extend([
37             # dw
38             ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim),
39             # pw-linear
40             nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
41             nn.BatchNorm2d(oup),
42         ])
43         self.conv = nn.Sequential(*layers)
44 
45     def forward(self, x):
46         if self.use_res_connect:
47             return x + self.conv(x)
48         else:
49             return self.conv(x)
50 
51 
52 class MobileNetV2(nn.Module):
53     def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None):
54         super(MobileNetV2, self).__init__()
55         block = InvertedResidual
56         input_channel = 32
57         last_channel = 1280
58 
59         if inverted_residual_setting is None:
60             inverted_residual_setting = [
61                 # t, c, n, s
62                 [1, 16, 1, 1],
63                 [6, 24, 2, 2],
64                 [6, 32, 3, 2],
65                 [6, 64, 4, 2],
66                 [6, 96, 3, 1],
67                 [6, 160, 3, 2],
68                 [6, 320, 1, 1],
69             ]
70 
71         # only check the first element, assuming user knows t,c,n,s are required
72         if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4:
73             raise ValueError("inverted_residual_setting should be non-empty "
74                              "or a 4-element list, got {}".format(inverted_residual_setting))
75 
76         # building first layer
77         input_channel = int(input_channel * width_mult)
78         self.last_channel = int(last_channel * max(1.0, width_mult))
79         features = [ConvBNReLU(3, input_channel, stride=2)]
80         # building inverted residual blocks
81         for t, c, n, s in inverted_residual_setting:
82             output_channel = int(c * width_mult)
83             for i in range(n):
84                 stride = s if i == 0 else 1
85                 features.append(block(input_channel, output_channel, stride, expand_ratio=t))
86                 input_channel = output_channel
87         # building last several layers
88         features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1))
89         # make it nn.Sequential
90         self.features = nn.Sequential(*features)
91 
92         # building classifier
93         self.classifier = nn.Sequential(
94             nn.Dropout(0.2),
95             nn.Linear(self.last_channel, num_classes),
96         )
97 
98         # weight initialization
99         for m in self.modules():
100             if isinstance(m, nn.Conv2d):
101                 nn.init.kaiming_normal_(m.weight, mode='fan_out')
102                 if m.bias is not None:
103                     nn.init.zeros_(m.bias)
104             elif isinstance(m, nn.BatchNorm2d):
105                 nn.init.ones_(m.weight)
106                 nn.init.zeros_(m.bias)
107             elif isinstance(m, nn.Linear):
108                 nn.init.normal_(m.weight, 0, 0.01)
109                 nn.init.zeros_(m.bias)
110 
111     def forward(self, x):
112         x = self.features(x)
113         x = x.mean([2, 3])
114         x = self.classifier(x)
115         return x
116 
117 
118 def mobilenet_v2(pretrained=False, progress=True, **kwargs):
119     """
120     Constructs a MobileNetV2 architecture from
121     `"MobileNetV2: Inverted Residuals and Linear Bottlenecks" <https://arxiv.org/abs/1801.04381>`_.
122 
123     Args:
124         pretrained (bool): If True, returns a model pre-trained on ImageNet
125         progress (bool): If True, displays a progress bar of the download to stderr
126     """
127     model = MobileNetV2(**kwargs)
128     if pretrained:
129         state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'],
130                                               progress=progress)
131         model.load_state_dict(state_dict)
132     return model
133
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/torchvision/models/mobilenet.py b/torchvision/models/mobilenet.py
--- a/torchvision/models/mobilenet.py
+++ b/torchvision/models/mobilenet.py
@@ -10,6 +10,26 @@
 }
 
 
+def _make_divisible(v, divisor, min_value=None):
+    """
+    This function is taken from the original tf repo.
+    It ensures that all layers have a channel number that is divisible by 8
+    It can be seen here:
+    https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py
+    :param v:
+    :param divisor:
+    :param min_value:
+    :return:
+    """
+    if min_value is None:
+        min_value = divisor
+    new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
+    # Make sure that round down does not go down by more than 10%.
+    if new_v < 0.9 * v:
+        new_v += divisor
+    return new_v
+
+
 class ConvBNReLU(nn.Sequential):
     def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
         padding = (kernel_size - 1) // 2
@@ -50,7 +70,17 @@
 
 
 class MobileNetV2(nn.Module):
-    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None):
+    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8):
+        """
+        MobileNet V2 main class
+
+        Args:
+            num_classes (int): Number of classes
+            width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount
+            inverted_residual_setting: Network structure
+            round_nearest (int): Round the number of channels in each layer to be a multiple of this number
+            Set to 1 to turn off rounding
+        """
         super(MobileNetV2, self).__init__()
         block = InvertedResidual
         input_channel = 32
@@ -74,12 +104,12 @@
                              "or a 4-element list, got {}".format(inverted_residual_setting))
 
         # building first layer
-        input_channel = int(input_channel * width_mult)
-        self.last_channel = int(last_channel * max(1.0, width_mult))
+        input_channel = _make_divisible(input_channel * width_mult, round_nearest)
+        self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)
         features = [ConvBNReLU(3, input_channel, stride=2)]
         # building inverted residual blocks
         for t, c, n, s in inverted_residual_setting:
-            output_channel = int(c * width_mult)
+            output_channel = _make_divisible(c * width_mult, round_nearest)
             for i in range(n):
                 stride = s if i == 0 else 1
                 features.append(block(input_channel, output_channel, stride, expand_ratio=t))

{"golden_diff": "diff --git a/torchvision/models/mobilenet.py b/torchvision/models/mobilenet.py\n--- a/torchvision/models/mobilenet.py\n+++ b/torchvision/models/mobilenet.py\n@@ -10,6 +10,26 @@\n }\n \n \n+def _make_divisible(v, divisor, min_value=None):\n+    \"\"\"\n+    This function is taken from the original tf repo.\n+    It ensures that all layers have a channel number that is divisible by 8\n+    It can be seen here:\n+    https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py\n+    :param v:\n+    :param divisor:\n+    :param min_value:\n+    :return:\n+    \"\"\"\n+    if min_value is None:\n+        min_value = divisor\n+    new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)\n+    # Make sure that round down does not go down by more than 10%.\n+    if new_v < 0.9 * v:\n+        new_v += divisor\n+    return new_v\n+\n+\n class ConvBNReLU(nn.Sequential):\n     def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):\n         padding = (kernel_size - 1) // 2\n@@ -50,7 +70,17 @@\n \n \n class MobileNetV2(nn.Module):\n-    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None):\n+    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8):\n+        \"\"\"\n+        MobileNet V2 main class\n+\n+        Args:\n+            num_classes (int): Number of classes\n+            width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount\n+            inverted_residual_setting: Network structure\n+            round_nearest (int): Round the number of channels in each layer to be a multiple of this number\n+            Set to 1 to turn off rounding\n+        \"\"\"\n         super(MobileNetV2, self).__init__()\n         block = InvertedResidual\n         input_channel = 32\n@@ -74,12 +104,12 @@\n                              \"or a 4-element list, got {}\".format(inverted_residual_setting))\n \n         # building first layer\n-        input_channel = int(input_channel * width_mult)\n-        self.last_channel = int(last_channel * max(1.0, width_mult))\n+        input_channel = _make_divisible(input_channel * width_mult, round_nearest)\n+        self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)\n         features = [ConvBNReLU(3, input_channel, stride=2)]\n         # building inverted residual blocks\n         for t, c, n, s in inverted_residual_setting:\n-            output_channel = int(c * width_mult)\n+            output_channel = _make_divisible(c * width_mult, round_nearest)\n             for i in range(n):\n                 stride = s if i == 0 else 1\n                 features.append(block(input_channel, output_channel, stride, expand_ratio=t))\n", "issue": "Mobilenet v2 width multiplier incorrect\nThere seems to be a small issue with the width multiplier in mobilenet v2.  The official implementation rounds filter channels to a multiple of 8.  \r\n\r\nFor example, mobilenet v2 width 1.4.  The first conv layer has 44 channels as opposed to 48 in the official implementation:\r\nmodel = torchvision.models.mobilenet_v2(width_mult=1.4)\r\n\r\nfor module in model.modules():\r\n    if isinstance(module, nn.Conv2d):\r\n        print(module.weight.shape)\r\n\r\ntorch.Size([44, 3, 3, 3])\r\ntorch.Size([44, 1, 3, 3])\r\ntorch.Size([22, 44, 1, 1])\r\ntorch.Size([132, 22, 1, 1])\r\ntorch.Size([132, 1, 3, 3])\r\ntorch.Size([33, 132, 1, 1])\r\n\r\n\r\nCorresponding tensorflow 2.0 keras code:\r\nmodel = tf.keras.applications.MobileNetV2(\r\n    weights=\"imagenet\", input_shape=(224, 224, 3), alpha=1.4)\r\nmodel.summary()\r\n\r\n__________________________________________________________________________________________________\r\nLayer (type)                    Output Shape         Param #     Connected to                     \r\n==================================================================================================\r\ninput_1 (InputLayer)            [(None, 224, 224, 3) 0                                            \r\n__________________________________________________________________________________________________\r\nConv1_pad (ZeroPadding2D)       (None, 225, 225, 3)  0           input_1[0][0]                    \r\n__________________________________________________________________________________________________\r\nConv1 (Conv2D)                  (None, 112, 112, 48) 1296        Conv1_pad[0][0]                  \r\n__________________________________________________________________________________________________\r\nbn_Conv1 (BatchNormalization)   (None, 112, 112, 48) 192         Conv1[0][0]                      \r\n__________________________________________________________________________________________________\r\nConv1_relu (ReLU)               (None, 112, 112, 48) 0           bn_Conv1[0][0]                   \r\n__________________________________________________________________________________________________\r\nexpanded_conv_depthwise (Depthw (None, 112, 112, 48) 432         Conv1_relu[0][0]                 \r\n__________________________________________________________________________________________________\r\nexpanded_conv_depthwise_BN (Bat (None, 112, 112, 48) 192         expanded_conv_depthwise[0][0]    \r\n__________________________________________________________________________________________________\r\nexpanded_conv_depthwise_relu (R (None, 112, 112, 48) 0           expanded_conv_depthwise_BN[0][0] \r\n__________________________________________________________________________________________________\r\nexpanded_conv_project (Conv2D)  (None, 112, 112, 24) 1152        expanded_conv_depthwise_relu[0][0\r\n__________________________________________________________________________________________________\r\nexpanded_conv_project_BN (Batch (None, 112, 112, 24) 96          expanded_conv_project[0][0]      \r\n__________________________________________________________________________________________________\r\nblock_1_expand (Conv2D)         (None, 112, 112, 144 3456        expanded_conv_project_BN[0][0]   \r\n__________________________________________________________________________________________________\r\nblock_1_expand_BN (BatchNormali (None, 112, 112, 144 576         block_1_expand[0][0]             \r\n__________________________________________________________________________________________________\r\nblock_1_expand_relu (ReLU)      (None, 112, 112, 144 0           block_1_expand_BN[0][0]          \r\n__________________________________________________________________________________________________\r\nblock_1_pad (ZeroPadding2D)     (None, 113, 113, 144 0           block_1_expand_relu[0][0]        \r\n__________________________________________________________________________________________________\r\nblock_1_depthwise (DepthwiseCon (None, 56, 56, 144)  1296        block_1_pad[0][0]                \r\n__________________________________________________________________________________________________\r\nblock_1_depthwise_BN (BatchNorm (None, 56, 56, 144)  576         block_1_depthwise[0][0]          \r\n__________________________________________________________________________________________________\r\nblock_1_depthwise_relu (ReLU)   (None, 56, 56, 144)  0           block_1_depthwise_BN[0][0]       \r\n__________________________________________________________________________________________________\r\nblock_1_project (Conv2D)        (None, 56, 56, 32)   4608        block_1_depthwise_relu[0][0]     \r\n__________________________________________________________________________________________________\r\n\r\n\r\nI've implemented a fix here:\r\nhttps://github.com/yaysummeriscoming/vision/blob/master/torchvision/models/mobilenet.py\r\n\r\nCan I merge it in?\n", "before_files": [{"content": "from torch import nn\nfrom .utils import load_state_dict_from_url\n\n\n__all__ = ['MobileNetV2', 'mobilenet_v2']\n\n\nmodel_urls = {\n    'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth',\n}\n\n\nclass ConvBNReLU(nn.Sequential):\n    def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):\n        padding = (kernel_size - 1) // 2\n        super(ConvBNReLU, self).__init__(\n            nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False),\n            nn.BatchNorm2d(out_planes),\n            nn.ReLU6(inplace=True)\n        )\n\n\nclass InvertedResidual(nn.Module):\n    def __init__(self, inp, oup, stride, expand_ratio):\n        super(InvertedResidual, self).__init__()\n        self.stride = stride\n        assert stride in [1, 2]\n\n        hidden_dim = int(round(inp * expand_ratio))\n        self.use_res_connect = self.stride == 1 and inp == oup\n\n        layers = []\n        if expand_ratio != 1:\n            # pw\n            layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))\n        layers.extend([\n            # dw\n            ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim),\n            # pw-linear\n            nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),\n            nn.BatchNorm2d(oup),\n        ])\n        self.conv = nn.Sequential(*layers)\n\n    def forward(self, x):\n        if self.use_res_connect:\n            return x + self.conv(x)\n        else:\n            return self.conv(x)\n\n\nclass MobileNetV2(nn.Module):\n    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None):\n        super(MobileNetV2, self).__init__()\n        block = InvertedResidual\n        input_channel = 32\n        last_channel = 1280\n\n        if inverted_residual_setting is None:\n            inverted_residual_setting = [\n                # t, c, n, s\n                [1, 16, 1, 1],\n                [6, 24, 2, 2],\n                [6, 32, 3, 2],\n                [6, 64, 4, 2],\n                [6, 96, 3, 1],\n                [6, 160, 3, 2],\n                [6, 320, 1, 1],\n            ]\n\n        # only check the first element, assuming user knows t,c,n,s are required\n        if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4:\n            raise ValueError(\"inverted_residual_setting should be non-empty \"\n                             \"or a 4-element list, got {}\".format(inverted_residual_setting))\n\n        # building first layer\n        input_channel = int(input_channel * width_mult)\n        self.last_channel = int(last_channel * max(1.0, width_mult))\n        features = [ConvBNReLU(3, input_channel, stride=2)]\n        # building inverted residual blocks\n        for t, c, n, s in inverted_residual_setting:\n            output_channel = int(c * width_mult)\n            for i in range(n):\n                stride = s if i == 0 else 1\n                features.append(block(input_channel, output_channel, stride, expand_ratio=t))\n                input_channel = output_channel\n        # building last several layers\n        features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1))\n        # make it nn.Sequential\n        self.features = nn.Sequential(*features)\n\n        # building classifier\n        self.classifier = nn.Sequential(\n            nn.Dropout(0.2),\n            nn.Linear(self.last_channel, num_classes),\n        )\n\n        # weight initialization\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out')\n                if m.bias is not None:\n                    nn.init.zeros_(m.bias)\n            elif isinstance(m, nn.BatchNorm2d):\n                nn.init.ones_(m.weight)\n                nn.init.zeros_(m.bias)\n            elif isinstance(m, nn.Linear):\n                nn.init.normal_(m.weight, 0, 0.01)\n                nn.init.zeros_(m.bias)\n\n    def forward(self, x):\n        x = self.features(x)\n        x = x.mean([2, 3])\n        x = self.classifier(x)\n        return x\n\n\ndef mobilenet_v2(pretrained=False, progress=True, **kwargs):\n    \"\"\"\n    Constructs a MobileNetV2 architecture from\n    `\"MobileNetV2: Inverted Residuals and Linear Bottlenecks\" <https://arxiv.org/abs/1801.04381>`_.\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    model = MobileNetV2(**kwargs)\n    if pretrained:\n        state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'],\n                                              progress=progress)\n        model.load_state_dict(state_dict)\n    return model\n", "path": "torchvision/models/mobilenet.py"}], "after_files": [{"content": "from torch import nn\nfrom .utils import load_state_dict_from_url\n\n\n__all__ = ['MobileNetV2', 'mobilenet_v2']\n\n\nmodel_urls = {\n    'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth',\n}\n\n\ndef _make_divisible(v, divisor, min_value=None):\n    \"\"\"\n    This function is taken from the original tf repo.\n    It ensures that all layers have a channel number that is divisible by 8\n    It can be seen here:\n    https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py\n    :param v:\n    :param divisor:\n    :param min_value:\n    :return:\n    \"\"\"\n    if min_value is None:\n        min_value = divisor\n    new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)\n    # Make sure that round down does not go down by more than 10%.\n    if new_v < 0.9 * v:\n        new_v += divisor\n    return new_v\n\n\nclass ConvBNReLU(nn.Sequential):\n    def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):\n        padding = (kernel_size - 1) // 2\n        super(ConvBNReLU, self).__init__(\n            nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False),\n            nn.BatchNorm2d(out_planes),\n            nn.ReLU6(inplace=True)\n        )\n\n\nclass InvertedResidual(nn.Module):\n    def __init__(self, inp, oup, stride, expand_ratio):\n        super(InvertedResidual, self).__init__()\n        self.stride = stride\n        assert stride in [1, 2]\n\n        hidden_dim = int(round(inp * expand_ratio))\n        self.use_res_connect = self.stride == 1 and inp == oup\n\n        layers = []\n        if expand_ratio != 1:\n            # pw\n            layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))\n        layers.extend([\n            # dw\n            ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim),\n            # pw-linear\n            nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),\n            nn.BatchNorm2d(oup),\n        ])\n        self.conv = nn.Sequential(*layers)\n\n    def forward(self, x):\n        if self.use_res_connect:\n            return x + self.conv(x)\n        else:\n            return self.conv(x)\n\n\nclass MobileNetV2(nn.Module):\n    def __init__(self, num_classes=1000, width_mult=1.0, inverted_residual_setting=None, round_nearest=8):\n        \"\"\"\n        MobileNet V2 main class\n\n        Args:\n            num_classes (int): Number of classes\n            width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount\n            inverted_residual_setting: Network structure\n            round_nearest (int): Round the number of channels in each layer to be a multiple of this number\n            Set to 1 to turn off rounding\n        \"\"\"\n        super(MobileNetV2, self).__init__()\n        block = InvertedResidual\n        input_channel = 32\n        last_channel = 1280\n\n        if inverted_residual_setting is None:\n            inverted_residual_setting = [\n                # t, c, n, s\n                [1, 16, 1, 1],\n                [6, 24, 2, 2],\n                [6, 32, 3, 2],\n                [6, 64, 4, 2],\n                [6, 96, 3, 1],\n                [6, 160, 3, 2],\n                [6, 320, 1, 1],\n            ]\n\n        # only check the first element, assuming user knows t,c,n,s are required\n        if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4:\n            raise ValueError(\"inverted_residual_setting should be non-empty \"\n                             \"or a 4-element list, got {}\".format(inverted_residual_setting))\n\n        # building first layer\n        input_channel = _make_divisible(input_channel * width_mult, round_nearest)\n        self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)\n        features = [ConvBNReLU(3, input_channel, stride=2)]\n        # building inverted residual blocks\n        for t, c, n, s in inverted_residual_setting:\n            output_channel = _make_divisible(c * width_mult, round_nearest)\n            for i in range(n):\n                stride = s if i == 0 else 1\n                features.append(block(input_channel, output_channel, stride, expand_ratio=t))\n                input_channel = output_channel\n        # building last several layers\n        features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1))\n        # make it nn.Sequential\n        self.features = nn.Sequential(*features)\n\n        # building classifier\n        self.classifier = nn.Sequential(\n            nn.Dropout(0.2),\n            nn.Linear(self.last_channel, num_classes),\n        )\n\n        # weight initialization\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out')\n                if m.bias is not None:\n                    nn.init.zeros_(m.bias)\n            elif isinstance(m, nn.BatchNorm2d):\n                nn.init.ones_(m.weight)\n                nn.init.zeros_(m.bias)\n            elif isinstance(m, nn.Linear):\n                nn.init.normal_(m.weight, 0, 0.01)\n                nn.init.zeros_(m.bias)\n\n    def forward(self, x):\n        x = self.features(x)\n        x = x.mean([2, 3])\n        x = self.classifier(x)\n        return x\n\n\ndef mobilenet_v2(pretrained=False, progress=True, **kwargs):\n    \"\"\"\n    Constructs a MobileNetV2 architecture from\n    `\"MobileNetV2: Inverted Residuals and Linear Bottlenecks\" <https://arxiv.org/abs/1801.04381>`_.\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    model = MobileNetV2(**kwargs)\n    if pretrained:\n        state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'],\n                                              progress=progress)\n        model.load_state_dict(state_dict)\n    return model\n", "path": "torchvision/models/mobilenet.py"}]}