We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
'ConvModule' object has no attribute 'norm' when using torch.jit.trace
environment: python3.6.6 pytorch1.7.0

code:

```
import torch
from mmcv.cnn.bricks import ConvModule

conv = ConvModule(3, 8, 2, norm_cfg=dict(type='BN'))
input_example = torch.randn((1, 3, 224, 224))

ts = torch.jit.trace(func=conv.eval(), example_inputs=input_example)
torch.jit.save(ts, 'conv_module.ts')
```

It work well, but when set `norm_cfg=None`, failed.

```
torch.nn.modules.module.ModuleAttributeError: 'ConvModule' object has no attribute 'norm'
```

Any help?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmcv/cnn/bricks/conv_module.py`
Content:
```
1 import warnings
2 
3 import torch.nn as nn
4 
5 from ..utils import constant_init, kaiming_init
6 from .activation import build_activation_layer
7 from .conv import build_conv_layer
8 from .norm import build_norm_layer
9 from .padding import build_padding_layer
10 from .registry import PLUGIN_LAYERS
11 
12 
13 @PLUGIN_LAYERS.register_module()
14 class ConvModule(nn.Module):
15     """A conv block that bundles conv/norm/activation layers.
16 
17     This block simplifies the usage of convolution layers, which are commonly
18     used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU).
19     It is based upon three build methods: `build_conv_layer()`,
20     `build_norm_layer()` and `build_activation_layer()`.
21 
22     Besides, we add some additional features in this module.
23     1. Automatically set `bias` of the conv layer.
24     2. Spectral norm is supported.
25     3. More padding modes are supported. Before PyTorch 1.5, nn.Conv2d only
26     supports zero and circular padding, and we add "reflect" padding mode.
27 
28     Args:
29         in_channels (int): Number of channels in the input feature map.
30             Same as that in ``nn._ConvNd``.
31         out_channels (int): Number of channels produced by the convolution.
32             Same as that in ``nn._ConvNd``.
33         kernel_size (int | tuple[int]): Size of the convolving kernel.
34             Same as that in ``nn._ConvNd``.
35         stride (int | tuple[int]): Stride of the convolution.
36             Same as that in ``nn._ConvNd``.
37         padding (int | tuple[int]): Zero-padding added to both sides of
38             the input. Same as that in ``nn._ConvNd``.
39         dilation (int | tuple[int]): Spacing between kernel elements.
40             Same as that in ``nn._ConvNd``.
41         groups (int): Number of blocked connections from input channels to
42             output channels. Same as that in ``nn._ConvNd``.
43         bias (bool | str): If specified as `auto`, it will be decided by the
44             norm_cfg. Bias will be set as True if `norm_cfg` is None, otherwise
45             False. Default: "auto".
46         conv_cfg (dict): Config dict for convolution layer. Default: None,
47             which means using conv2d.
48         norm_cfg (dict): Config dict for normalization layer. Default: None.
49         act_cfg (dict): Config dict for activation layer.
50             Default: dict(type='ReLU').
51         inplace (bool): Whether to use inplace mode for activation.
52             Default: True.
53         with_spectral_norm (bool): Whether use spectral norm in conv module.
54             Default: False.
55         padding_mode (str): If the `padding_mode` has not been supported by
56             current `Conv2d` in PyTorch, we will use our own padding layer
57             instead. Currently, we support ['zeros', 'circular'] with official
58             implementation and ['reflect'] with our own implementation.
59             Default: 'zeros'.
60         order (tuple[str]): The order of conv/norm/activation layers. It is a
61             sequence of "conv", "norm" and "act". Common examples are
62             ("conv", "norm", "act") and ("act", "conv", "norm").
63             Default: ('conv', 'norm', 'act').
64     """
65 
66     _abbr_ = 'conv_block'
67 
68     def __init__(self,
69                  in_channels,
70                  out_channels,
71                  kernel_size,
72                  stride=1,
73                  padding=0,
74                  dilation=1,
75                  groups=1,
76                  bias='auto',
77                  conv_cfg=None,
78                  norm_cfg=None,
79                  act_cfg=dict(type='ReLU'),
80                  inplace=True,
81                  with_spectral_norm=False,
82                  padding_mode='zeros',
83                  order=('conv', 'norm', 'act')):
84         super(ConvModule, self).__init__()
85         assert conv_cfg is None or isinstance(conv_cfg, dict)
86         assert norm_cfg is None or isinstance(norm_cfg, dict)
87         assert act_cfg is None or isinstance(act_cfg, dict)
88         official_padding_mode = ['zeros', 'circular']
89         self.conv_cfg = conv_cfg
90         self.norm_cfg = norm_cfg
91         self.act_cfg = act_cfg
92         self.inplace = inplace
93         self.with_spectral_norm = with_spectral_norm
94         self.with_explicit_padding = padding_mode not in official_padding_mode
95         self.order = order
96         assert isinstance(self.order, tuple) and len(self.order) == 3
97         assert set(order) == set(['conv', 'norm', 'act'])
98 
99         self.with_norm = norm_cfg is not None
100         self.with_activation = act_cfg is not None
101         # if the conv layer is before a norm layer, bias is unnecessary.
102         if bias == 'auto':
103             bias = not self.with_norm
104         self.with_bias = bias
105 
106         if self.with_norm and self.with_bias:
107             warnings.warn('ConvModule has norm and bias at the same time')
108 
109         if self.with_explicit_padding:
110             pad_cfg = dict(type=padding_mode)
111             self.padding_layer = build_padding_layer(pad_cfg, padding)
112 
113         # reset padding to 0 for conv module
114         conv_padding = 0 if self.with_explicit_padding else padding
115         # build convolution layer
116         self.conv = build_conv_layer(
117             conv_cfg,
118             in_channels,
119             out_channels,
120             kernel_size,
121             stride=stride,
122             padding=conv_padding,
123             dilation=dilation,
124             groups=groups,
125             bias=bias)
126         # export the attributes of self.conv to a higher level for convenience
127         self.in_channels = self.conv.in_channels
128         self.out_channels = self.conv.out_channels
129         self.kernel_size = self.conv.kernel_size
130         self.stride = self.conv.stride
131         self.padding = padding
132         self.dilation = self.conv.dilation
133         self.transposed = self.conv.transposed
134         self.output_padding = self.conv.output_padding
135         self.groups = self.conv.groups
136 
137         if self.with_spectral_norm:
138             self.conv = nn.utils.spectral_norm(self.conv)
139 
140         # build normalization layers
141         if self.with_norm:
142             # norm layer is after conv layer
143             if order.index('norm') > order.index('conv'):
144                 norm_channels = out_channels
145             else:
146                 norm_channels = in_channels
147             self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels)
148             self.add_module(self.norm_name, norm)
149 
150         # build activation layer
151         if self.with_activation:
152             act_cfg_ = act_cfg.copy()
153             # nn.Tanh has no 'inplace' argument
154             if act_cfg_['type'] not in [
155                     'Tanh', 'PReLU', 'Sigmoid', 'HSigmoid', 'Swish'
156             ]:
157                 act_cfg_.setdefault('inplace', inplace)
158             self.activate = build_activation_layer(act_cfg_)
159 
160         # Use msra init by default
161         self.init_weights()
162 
163     @property
164     def norm(self):
165         return getattr(self, self.norm_name)
166 
167     def init_weights(self):
168         # 1. It is mainly for customized conv layers with their own
169         #    initialization manners by calling their own ``init_weights()``,
170         #    and we do not want ConvModule to override the initialization.
171         # 2. For customized conv layers without their own initialization
172         #    manners (that is, they don't have their own ``init_weights()``)
173         #    and PyTorch's conv layers, they will be initialized by
174         #    this method with default ``kaiming_init``.
175         # Note: For PyTorch's conv layers, they will be overwritten by our
176         #    initialization implementation using default ``kaiming_init``.
177         if not hasattr(self.conv, 'init_weights'):
178             if self.with_activation and self.act_cfg['type'] == 'LeakyReLU':
179                 nonlinearity = 'leaky_relu'
180                 a = self.act_cfg.get('negative_slope', 0.01)
181             else:
182                 nonlinearity = 'relu'
183                 a = 0
184             kaiming_init(self.conv, a=a, nonlinearity=nonlinearity)
185         if self.with_norm:
186             constant_init(self.norm, 1, bias=0)
187 
188     def forward(self, x, activate=True, norm=True):
189         for layer in self.order:
190             if layer == 'conv':
191                 if self.with_explicit_padding:
192                     x = self.padding_layer(x)
193                 x = self.conv(x)
194             elif layer == 'norm' and norm and self.with_norm:
195                 x = self.norm(x)
196             elif layer == 'act' and activate and self.with_activation:
197                 x = self.activate(x)
198         return x
199
```
--- 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/mmcv/cnn/bricks/conv_module.py b/mmcv/cnn/bricks/conv_module.py
--- a/mmcv/cnn/bricks/conv_module.py
+++ b/mmcv/cnn/bricks/conv_module.py
@@ -146,6 +146,8 @@
                 norm_channels = in_channels
             self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels)
             self.add_module(self.norm_name, norm)
+        else:
+            self.norm_name = None
 
         # build activation layer
         if self.with_activation:
@@ -162,7 +164,10 @@
 
     @property
     def norm(self):
-        return getattr(self, self.norm_name)
+        if self.norm_name:
+            return getattr(self, self.norm_name)
+        else:
+            return None
 
     def init_weights(self):
         # 1. It is mainly for customized conv layers with their own

{"golden_diff": "diff --git a/mmcv/cnn/bricks/conv_module.py b/mmcv/cnn/bricks/conv_module.py\n--- a/mmcv/cnn/bricks/conv_module.py\n+++ b/mmcv/cnn/bricks/conv_module.py\n@@ -146,6 +146,8 @@\n                 norm_channels = in_channels\n             self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels)\n             self.add_module(self.norm_name, norm)\n+        else:\n+            self.norm_name = None\n \n         # build activation layer\n         if self.with_activation:\n@@ -162,7 +164,10 @@\n \n     @property\n     def norm(self):\n-        return getattr(self, self.norm_name)\n+        if self.norm_name:\n+            return getattr(self, self.norm_name)\n+        else:\n+            return None\n \n     def init_weights(self):\n         # 1. It is mainly for customized conv layers with their own\n", "issue": "'ConvModule' object has no attribute 'norm' when using torch.jit.trace\nenvironment: python3.6.6 pytorch1.7.0\r\n\r\ncode:\r\n\r\n```\r\nimport torch\r\nfrom mmcv.cnn.bricks import ConvModule\r\n\r\nconv = ConvModule(3, 8, 2, norm_cfg=dict(type='BN'))\r\ninput_example = torch.randn((1, 3, 224, 224))\r\n\r\nts = torch.jit.trace(func=conv.eval(), example_inputs=input_example)\r\ntorch.jit.save(ts, 'conv_module.ts')\r\n```\r\n\r\nIt work well, but when set `norm_cfg=None`, failed.\r\n\r\n```\r\ntorch.nn.modules.module.ModuleAttributeError: 'ConvModule' object has no attribute 'norm'\r\n```\r\n\r\nAny help?\n", "before_files": [{"content": "import warnings\n\nimport torch.nn as nn\n\nfrom ..utils import constant_init, kaiming_init\nfrom .activation import build_activation_layer\nfrom .conv import build_conv_layer\nfrom .norm import build_norm_layer\nfrom .padding import build_padding_layer\nfrom .registry import PLUGIN_LAYERS\n\n\n@PLUGIN_LAYERS.register_module()\nclass ConvModule(nn.Module):\n    \"\"\"A conv block that bundles conv/norm/activation layers.\n\n    This block simplifies the usage of convolution layers, which are commonly\n    used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU).\n    It is based upon three build methods: `build_conv_layer()`,\n    `build_norm_layer()` and `build_activation_layer()`.\n\n    Besides, we add some additional features in this module.\n    1. Automatically set `bias` of the conv layer.\n    2. Spectral norm is supported.\n    3. More padding modes are supported. Before PyTorch 1.5, nn.Conv2d only\n    supports zero and circular padding, and we add \"reflect\" padding mode.\n\n    Args:\n        in_channels (int): Number of channels in the input feature map.\n            Same as that in ``nn._ConvNd``.\n        out_channels (int): Number of channels produced by the convolution.\n            Same as that in ``nn._ConvNd``.\n        kernel_size (int | tuple[int]): Size of the convolving kernel.\n            Same as that in ``nn._ConvNd``.\n        stride (int | tuple[int]): Stride of the convolution.\n            Same as that in ``nn._ConvNd``.\n        padding (int | tuple[int]): Zero-padding added to both sides of\n            the input. Same as that in ``nn._ConvNd``.\n        dilation (int | tuple[int]): Spacing between kernel elements.\n            Same as that in ``nn._ConvNd``.\n        groups (int): Number of blocked connections from input channels to\n            output channels. Same as that in ``nn._ConvNd``.\n        bias (bool | str): If specified as `auto`, it will be decided by the\n            norm_cfg. Bias will be set as True if `norm_cfg` is None, otherwise\n            False. Default: \"auto\".\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer. Default: None.\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        inplace (bool): Whether to use inplace mode for activation.\n            Default: True.\n        with_spectral_norm (bool): Whether use spectral norm in conv module.\n            Default: False.\n        padding_mode (str): If the `padding_mode` has not been supported by\n            current `Conv2d` in PyTorch, we will use our own padding layer\n            instead. Currently, we support ['zeros', 'circular'] with official\n            implementation and ['reflect'] with our own implementation.\n            Default: 'zeros'.\n        order (tuple[str]): The order of conv/norm/activation layers. It is a\n            sequence of \"conv\", \"norm\" and \"act\". Common examples are\n            (\"conv\", \"norm\", \"act\") and (\"act\", \"conv\", \"norm\").\n            Default: ('conv', 'norm', 'act').\n    \"\"\"\n\n    _abbr_ = 'conv_block'\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size,\n                 stride=1,\n                 padding=0,\n                 dilation=1,\n                 groups=1,\n                 bias='auto',\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=dict(type='ReLU'),\n                 inplace=True,\n                 with_spectral_norm=False,\n                 padding_mode='zeros',\n                 order=('conv', 'norm', 'act')):\n        super(ConvModule, self).__init__()\n        assert conv_cfg is None or isinstance(conv_cfg, dict)\n        assert norm_cfg is None or isinstance(norm_cfg, dict)\n        assert act_cfg is None or isinstance(act_cfg, dict)\n        official_padding_mode = ['zeros', 'circular']\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.inplace = inplace\n        self.with_spectral_norm = with_spectral_norm\n        self.with_explicit_padding = padding_mode not in official_padding_mode\n        self.order = order\n        assert isinstance(self.order, tuple) and len(self.order) == 3\n        assert set(order) == set(['conv', 'norm', 'act'])\n\n        self.with_norm = norm_cfg is not None\n        self.with_activation = act_cfg is not None\n        # if the conv layer is before a norm layer, bias is unnecessary.\n        if bias == 'auto':\n            bias = not self.with_norm\n        self.with_bias = bias\n\n        if self.with_norm and self.with_bias:\n            warnings.warn('ConvModule has norm and bias at the same time')\n\n        if self.with_explicit_padding:\n            pad_cfg = dict(type=padding_mode)\n            self.padding_layer = build_padding_layer(pad_cfg, padding)\n\n        # reset padding to 0 for conv module\n        conv_padding = 0 if self.with_explicit_padding else padding\n        # build convolution layer\n        self.conv = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            out_channels,\n            kernel_size,\n            stride=stride,\n            padding=conv_padding,\n            dilation=dilation,\n            groups=groups,\n            bias=bias)\n        # export the attributes of self.conv to a higher level for convenience\n        self.in_channels = self.conv.in_channels\n        self.out_channels = self.conv.out_channels\n        self.kernel_size = self.conv.kernel_size\n        self.stride = self.conv.stride\n        self.padding = padding\n        self.dilation = self.conv.dilation\n        self.transposed = self.conv.transposed\n        self.output_padding = self.conv.output_padding\n        self.groups = self.conv.groups\n\n        if self.with_spectral_norm:\n            self.conv = nn.utils.spectral_norm(self.conv)\n\n        # build normalization layers\n        if self.with_norm:\n            # norm layer is after conv layer\n            if order.index('norm') > order.index('conv'):\n                norm_channels = out_channels\n            else:\n                norm_channels = in_channels\n            self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels)\n            self.add_module(self.norm_name, norm)\n\n        # build activation layer\n        if self.with_activation:\n            act_cfg_ = act_cfg.copy()\n            # nn.Tanh has no 'inplace' argument\n            if act_cfg_['type'] not in [\n                    'Tanh', 'PReLU', 'Sigmoid', 'HSigmoid', 'Swish'\n            ]:\n                act_cfg_.setdefault('inplace', inplace)\n            self.activate = build_activation_layer(act_cfg_)\n\n        # Use msra init by default\n        self.init_weights()\n\n    @property\n    def norm(self):\n        return getattr(self, self.norm_name)\n\n    def init_weights(self):\n        # 1. It is mainly for customized conv layers with their own\n        #    initialization manners by calling their own ``init_weights()``,\n        #    and we do not want ConvModule to override the initialization.\n        # 2. For customized conv layers without their own initialization\n        #    manners (that is, they don't have their own ``init_weights()``)\n        #    and PyTorch's conv layers, they will be initialized by\n        #    this method with default ``kaiming_init``.\n        # Note: For PyTorch's conv layers, they will be overwritten by our\n        #    initialization implementation using default ``kaiming_init``.\n        if not hasattr(self.conv, 'init_weights'):\n            if self.with_activation and self.act_cfg['type'] == 'LeakyReLU':\n                nonlinearity = 'leaky_relu'\n                a = self.act_cfg.get('negative_slope', 0.01)\n            else:\n                nonlinearity = 'relu'\n                a = 0\n            kaiming_init(self.conv, a=a, nonlinearity=nonlinearity)\n        if self.with_norm:\n            constant_init(self.norm, 1, bias=0)\n\n    def forward(self, x, activate=True, norm=True):\n        for layer in self.order:\n            if layer == 'conv':\n                if self.with_explicit_padding:\n                    x = self.padding_layer(x)\n                x = self.conv(x)\n            elif layer == 'norm' and norm and self.with_norm:\n                x = self.norm(x)\n            elif layer == 'act' and activate and self.with_activation:\n                x = self.activate(x)\n        return x\n", "path": "mmcv/cnn/bricks/conv_module.py"}], "after_files": [{"content": "import warnings\n\nimport torch.nn as nn\n\nfrom ..utils import constant_init, kaiming_init\nfrom .activation import build_activation_layer\nfrom .conv import build_conv_layer\nfrom .norm import build_norm_layer\nfrom .padding import build_padding_layer\nfrom .registry import PLUGIN_LAYERS\n\n\n@PLUGIN_LAYERS.register_module()\nclass ConvModule(nn.Module):\n    \"\"\"A conv block that bundles conv/norm/activation layers.\n\n    This block simplifies the usage of convolution layers, which are commonly\n    used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU).\n    It is based upon three build methods: `build_conv_layer()`,\n    `build_norm_layer()` and `build_activation_layer()`.\n\n    Besides, we add some additional features in this module.\n    1. Automatically set `bias` of the conv layer.\n    2. Spectral norm is supported.\n    3. More padding modes are supported. Before PyTorch 1.5, nn.Conv2d only\n    supports zero and circular padding, and we add \"reflect\" padding mode.\n\n    Args:\n        in_channels (int): Number of channels in the input feature map.\n            Same as that in ``nn._ConvNd``.\n        out_channels (int): Number of channels produced by the convolution.\n            Same as that in ``nn._ConvNd``.\n        kernel_size (int | tuple[int]): Size of the convolving kernel.\n            Same as that in ``nn._ConvNd``.\n        stride (int | tuple[int]): Stride of the convolution.\n            Same as that in ``nn._ConvNd``.\n        padding (int | tuple[int]): Zero-padding added to both sides of\n            the input. Same as that in ``nn._ConvNd``.\n        dilation (int | tuple[int]): Spacing between kernel elements.\n            Same as that in ``nn._ConvNd``.\n        groups (int): Number of blocked connections from input channels to\n            output channels. Same as that in ``nn._ConvNd``.\n        bias (bool | str): If specified as `auto`, it will be decided by the\n            norm_cfg. Bias will be set as True if `norm_cfg` is None, otherwise\n            False. Default: \"auto\".\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer. Default: None.\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        inplace (bool): Whether to use inplace mode for activation.\n            Default: True.\n        with_spectral_norm (bool): Whether use spectral norm in conv module.\n            Default: False.\n        padding_mode (str): If the `padding_mode` has not been supported by\n            current `Conv2d` in PyTorch, we will use our own padding layer\n            instead. Currently, we support ['zeros', 'circular'] with official\n            implementation and ['reflect'] with our own implementation.\n            Default: 'zeros'.\n        order (tuple[str]): The order of conv/norm/activation layers. It is a\n            sequence of \"conv\", \"norm\" and \"act\". Common examples are\n            (\"conv\", \"norm\", \"act\") and (\"act\", \"conv\", \"norm\").\n            Default: ('conv', 'norm', 'act').\n    \"\"\"\n\n    _abbr_ = 'conv_block'\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size,\n                 stride=1,\n                 padding=0,\n                 dilation=1,\n                 groups=1,\n                 bias='auto',\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=dict(type='ReLU'),\n                 inplace=True,\n                 with_spectral_norm=False,\n                 padding_mode='zeros',\n                 order=('conv', 'norm', 'act')):\n        super(ConvModule, self).__init__()\n        assert conv_cfg is None or isinstance(conv_cfg, dict)\n        assert norm_cfg is None or isinstance(norm_cfg, dict)\n        assert act_cfg is None or isinstance(act_cfg, dict)\n        official_padding_mode = ['zeros', 'circular']\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.inplace = inplace\n        self.with_spectral_norm = with_spectral_norm\n        self.with_explicit_padding = padding_mode not in official_padding_mode\n        self.order = order\n        assert isinstance(self.order, tuple) and len(self.order) == 3\n        assert set(order) == set(['conv', 'norm', 'act'])\n\n        self.with_norm = norm_cfg is not None\n        self.with_activation = act_cfg is not None\n        # if the conv layer is before a norm layer, bias is unnecessary.\n        if bias == 'auto':\n            bias = not self.with_norm\n        self.with_bias = bias\n\n        if self.with_norm and self.with_bias:\n            warnings.warn('ConvModule has norm and bias at the same time')\n\n        if self.with_explicit_padding:\n            pad_cfg = dict(type=padding_mode)\n            self.padding_layer = build_padding_layer(pad_cfg, padding)\n\n        # reset padding to 0 for conv module\n        conv_padding = 0 if self.with_explicit_padding else padding\n        # build convolution layer\n        self.conv = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            out_channels,\n            kernel_size,\n            stride=stride,\n            padding=conv_padding,\n            dilation=dilation,\n            groups=groups,\n            bias=bias)\n        # export the attributes of self.conv to a higher level for convenience\n        self.in_channels = self.conv.in_channels\n        self.out_channels = self.conv.out_channels\n        self.kernel_size = self.conv.kernel_size\n        self.stride = self.conv.stride\n        self.padding = padding\n        self.dilation = self.conv.dilation\n        self.transposed = self.conv.transposed\n        self.output_padding = self.conv.output_padding\n        self.groups = self.conv.groups\n\n        if self.with_spectral_norm:\n            self.conv = nn.utils.spectral_norm(self.conv)\n\n        # build normalization layers\n        if self.with_norm:\n            # norm layer is after conv layer\n            if order.index('norm') > order.index('conv'):\n                norm_channels = out_channels\n            else:\n                norm_channels = in_channels\n            self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels)\n            self.add_module(self.norm_name, norm)\n        else:\n            self.norm_name = None\n\n        # build activation layer\n        if self.with_activation:\n            act_cfg_ = act_cfg.copy()\n            # nn.Tanh has no 'inplace' argument\n            if act_cfg_['type'] not in [\n                    'Tanh', 'PReLU', 'Sigmoid', 'HSigmoid', 'Swish'\n            ]:\n                act_cfg_.setdefault('inplace', inplace)\n            self.activate = build_activation_layer(act_cfg_)\n\n        # Use msra init by default\n        self.init_weights()\n\n    @property\n    def norm(self):\n        if self.norm_name:\n            return getattr(self, self.norm_name)\n        else:\n            return None\n\n    def init_weights(self):\n        # 1. It is mainly for customized conv layers with their own\n        #    initialization manners by calling their own ``init_weights()``,\n        #    and we do not want ConvModule to override the initialization.\n        # 2. For customized conv layers without their own initialization\n        #    manners (that is, they don't have their own ``init_weights()``)\n        #    and PyTorch's conv layers, they will be initialized by\n        #    this method with default ``kaiming_init``.\n        # Note: For PyTorch's conv layers, they will be overwritten by our\n        #    initialization implementation using default ``kaiming_init``.\n        if not hasattr(self.conv, 'init_weights'):\n            if self.with_activation and self.act_cfg['type'] == 'LeakyReLU':\n                nonlinearity = 'leaky_relu'\n                a = self.act_cfg.get('negative_slope', 0.01)\n            else:\n                nonlinearity = 'relu'\n                a = 0\n            kaiming_init(self.conv, a=a, nonlinearity=nonlinearity)\n        if self.with_norm:\n            constant_init(self.norm, 1, bias=0)\n\n    def forward(self, x, activate=True, norm=True):\n        for layer in self.order:\n            if layer == 'conv':\n                if self.with_explicit_padding:\n                    x = self.padding_layer(x)\n                x = self.conv(x)\n            elif layer == 'norm' and norm and self.with_norm:\n                x = self.norm(x)\n            elif layer == 'act' and activate and self.with_activation:\n                x = self.activate(x)\n        return x\n", "path": "mmcv/cnn/bricks/conv_module.py"}]}