# 比较与torch.nn.Conv2d的功能差异

## torch.nn.Conv2d

class torch.nn.Conv2d(
in_channels,
out_channels,
kernel_size,
stride=1,
dilation=1,
groups=1,
bias=True,
)(input) -> Tensor


## mindspore.nn.Conv2d

class mindspore.nn.Conv2d(
in_channels,
out_channels,
kernel_size,
stride=1,
dilation=1,
group=1,
has_bias=False,
weight_init='normal',
bias_init='zeros',
data_format='NCHW'
)(x) -> Tensor


## 差异对比

PyTorch：对输入Tensor计算二维卷积，通常情况下，输入大小为 $$\left(N, C_{\mathrm{in}}, H, W\right)$$ 、输出大小为 $$\left(N, C_{\text {out }}, H_{\text {out }}, W_{\text {out }}\right)$$ 的输出值可以描述为： $$\operatorname{out}\left(N_{i}, C_{\text {out }_{j}}\right)=\operatorname{bias}\left(C_{\text {out }_{j}}\right)+\sum_{k=0}^{C_{i n}-1} \text { weight }\left(C_{\text {out }_{j}}, k\right) \star \operatorname{input}\left(N_{i}, k\right)$$ 其中，$$\star$$ 为2D cross-correlation 算子，$$N$$ 是batch size，$$C$$ 是通道数量，$$H$$$$W$$ 分别是特征层的高度和宽度。

zero：常量填充（默认零填充）。

reflect：反射填充。

replicate：复制填充。

circular：循环填充。

valid：不填充。

PyTorch

MindSpore

in_channels

in_channels

-

out_channels

out_channels

-

kernel_size

kernel_size

-

stride

stride

-

-

dilation

dilation

-

groups

group

bias

has_bias

-

weight_init

-

bias_init

-

data_format

input

x

### 代码示例1

PyTorch的参数bias默认值为True，即默认添加偏置参数，而MindSpore的参数has_bias默认值为False，即默认不添加偏置函数，如果需要添加偏置参数，需要将has_bias的值设置为True。

# PyTorch
import torch
from torch import tensor
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = tensor(x_, dtype=torch.float32)
net = torch.nn.Conv2d(120, 240, 4)
output = net(x).detach().numpy().shape
print(output)
# (1, 240, 1021, 637)

# MindSpore
import mindspore
from mindspore import Tensor
import mindspore.nn as nn
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = Tensor(x_, mindspore.float32)
net = nn.Conv2d(120, 240, 4, has_bias=True, pad_mode='valid')
output = net(x).shape
print(output)
# (1, 240, 1021, 637)


### 代码示例2

# PyTorch
import torch
from torch import tensor
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = tensor(x_, dtype=torch.float32)
output = net(x).detach().numpy().shape
print(output)
# (1, 240, 1023, 639)

# MindSpore
import mindspore
from mindspore import Tensor
import mindspore.nn as nn
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = Tensor(x_, mindspore.float32)
output = net(x).shape
print(output)
# (1, 240, 1023, 639)


### 代码示例3

# PyTorch
import torch
from torch import tensor
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = tensor(x_, dtype=torch.float32)
output = net(x).detach().numpy().shape
print(output)
# (1, 240, 1023, 639)

# MindSpore
import mindspore
from mindspore import Tensor
import mindspore.nn as nn
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = Tensor(x_, mindspore.float32)
print(output)
# (1, 240, 1023, 639)


### 代码示例4

# PyTorch
import torch
from torch import tensor
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = tensor(x_, dtype=torch.float32)
net = torch.nn.Conv2d(120, 240, 4)
output = net(x).detach().numpy().shape
print(output)
# (1, 240, 1021, 637)

# MindSpore
import mindspore
from mindspore import Tensor
import mindspore.nn as nn
import numpy as np

x_ = np.ones((1, 120, 1024, 640))
x = Tensor(x_, mindspore.float32)
net = nn.Conv2d(120, 240, 4, pad_mode='valid')
output = net(x).shape
print(output)
# (1, 240, 1021, 637)