比较与tf.nn.conv2d的功能差异

tf.nn.conv2d

tf.nn.conv2d(
    input,
    filters,
    strides,
    padding,
    data_format='NHWC',
    dilations=None,
    name=None
) -> Tensor

更多内容详见tf.nn.conv2d

mindspore.nn.Conv2d

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

更多内容详见mindspore.nn.Conv2d

差异对比

TensorFlow:对输入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\) 分别是特征层的高度和宽度。

MindSpore:与TensorFlow实现的功能基本一致,但部分参数结构、支持维度、默认值不同。MindSpore和TensorFlow的填充模式都包含了’same’、’valid’,但MindSpore相较于TensorFlow多了’pad’(零填充)。

分类

子类

TensorFlow

MindSpore

差异

参数

参数1

input

x

功能一致,参数名不同

参数2

filters

kernel_size

功能一致,参数名不同,数据结构不同

参数3

strides

stride

功能一致,参数名不同,支持维度不同,默认值不同

参数4

padding

pad_mode

功能一致,参数名不同,可选项不同,默认值不同

参数5

data_format

data_format

功能一致,默认值不同

参数6

dilations

dilation

功能一致,参数名不同,支持维度不同,默认值不同

参数7

name

-

不涉及

参数8

-

in_channels

输入Tensor的空间维度

参数9

-

out_channels

输出Tensor的空间维度

参数10

-

padding

输入的高度和宽度方向上填充的数量

参数11

-

group

将过滤器拆分为组

参数12

-

has_bias

是否添加偏置参数

参数13

-

weight_init

权重参数的初始化方法

参数14

-

bias_init

偏置参数的初始化方法

代码示例1

TensorFlow的参数data_format默认值为’NHWC’,表示输入和输出的Tensor格式为[batchsize,in_height,in_width,in_channels]。MindSpore的参数data_format默认值为’NCHW’,表示输入和输出的Tensor格式为[batchsize,in_channels,in_height,in_width]。MindSpore的’NHWC’数据格式只能在GPU上使用,其它平台上,当输入数据格式为’NHWC’时,可以使用ops.transpose将数据格式修改为’NCHW’再进行卷积操作,最后将结果再通过ops.transpose转化为’NHWC’。

# TensorFlow
import tensorflow as tf
import numpy as np

x_ = tf.ones((1, 3, 3, 5))
x = tf.convert_to_tensor(x_, dtype=tf.float32)
filters_ = tf.ones((2, 2, 5, 1))
filters = tf.convert_to_tensor(filters_, dtype=tf.float32)
output = tf.nn.conv2d(x, filters, strides=1, padding='SAME').shape
print(output)
# (1, 3, 3, 1)

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

x_ = np.ones((1, 3, 3, 5))
x_NHWC = Tensor(x_, mindspore.float32)
x = ops.transpose(x_NHWC, (0, 3, 1, 2))
net = nn.Conv2d(5, 1, 2, stride=1, pad_mode='same')
output = ops.transpose(net(x), (0, 2, 3, 1)).shape
print(output)
# (1, 3, 3, 1)

代码示例2

TensorFlow的参数filters是一个四维Tensor,包括[filter_height,filter_width,in_channels,out_channels],即[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]。MindSpore的参数kernel_size为整型或两个整型的tuple,一个整数表示卷积核的高度和宽度均为该值。两个整数的tuple分别表示卷积核的高度和宽度。

# TensorFlow
import tensorflow as tf
import numpy as np

x_ = tf.ones((1, 4, 4, 5))
x = tf.convert_to_tensor(x_, dtype=tf.float32)
filters_ = tf.ones((2, 3, 5, 1))
filters = tf.convert_to_tensor(filters_, dtype=tf.float32)
output = tf.nn.conv2d(x, filters, strides=1, padding='VALID').shape
print(output)
# (1, 3, 2, 1)

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

x_ = np.ones((1, 4, 4, 5))
x_NHWC = Tensor(x_, mindspore.float32)
x = ops.transpose(x_NHWC, (0, 3, 1, 2))
net = nn.Conv2d(5, 1, (2, 3), stride=1, pad_mode='valid')
output = ops.transpose(net(x), (0, 2, 3, 1)).shape
print(output)
# (1, 3, 2, 1)

代码示例3

TensorFlow的参数strides是一个一维向量,长度可以为1、2、4,表示卷积时每一维的步长。一个整数表示在高度和宽度方向的移动步长均为该值,两个整数分别表示在高度和宽度方向的移动步长,剩下两维移动步长默认为1,此参数无默认值。MindSpore的参数stride为整型或两个整型的tuple。一个整数表示在高度和宽度方向的移动步长均为该值。两个整数的tuple分别表示在高度和宽度方向的移动步长,参数默认值为1。

# TensorFlow
import tensorflow as tf
import numpy as np

x_ = tf.ones((1, 4, 4, 5))
x = tf.convert_to_tensor(x_, dtype=tf.float32)
filters_ = tf.ones((2, 3, 5, 1))
filters = tf.convert_to_tensor(filters_, dtype=tf.float32)
output = tf.nn.conv2d(x, filters, strides=[1,1,1,1], padding='VALID').shape
print(output)
# (1, 3, 2, 1)

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

x_ = np.ones((1, 4, 4, 5))
x_NHWC = Tensor(x_, mindspore.float32)
x = ops.transpose(x_NHWC, (0, 3, 1, 2))
net = nn.Conv2d(5, 1, (2, 3), pad_mode='valid')
output = ops.transpose(net(x), (0, 2, 3, 1)).shape
print(output)
# (1, 3, 2, 1)

代码示例4

TensorFlow的参数dilations是一个一维向量,长度可以为1、2、4,表示卷积核膨胀尺寸,在H和C维度上的值必须为1。MindSpore的参数dilation为整型或两个整型的tuple。

# TensorFlow
import tensorflow as tf
import numpy as np

x_ = tf.ones((1, 6, 6, 5))
x = tf.convert_to_tensor(x_, dtype=tf.float32)
filters_ = tf.ones((2, 3, 5, 1))
filters = tf.convert_to_tensor(filters_, dtype=tf.float32)
output = tf.nn.conv2d(x, filters, strides=1, dilations=[1,2,2,1], padding='VALID').shape
print(output)
# (1, 4, 2, 1)

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

x_ = np.ones((1, 6, 6, 5))
x_NHWC = Tensor(x_, mindspore.float32)
x = ops.transpose(x_NHWC, (0, 3, 1, 2))
net = nn.Conv2d(5, 1, (2, 3), dilation=(2,2), pad_mode='valid')
output = ops.transpose(net(x), (0, 2, 3, 1)).shape
print(output)
# (1, 4, 2, 1)

代码示例5

TensorFlow的参数padding表示填充模式,没有默认值。MindSpore的参数pad_mode默认值为’same’。

# TensorFlow
import tensorflow as tf
import numpy as np

x_ = tf.ones((1, 4, 4, 5))
x = tf.convert_to_tensor(x_, dtype=tf.float32)
filters_ = tf.ones((2, 3, 5, 1))
filters = tf.convert_to_tensor(filters_, dtype=tf.float32)
output = tf.nn.conv2d(x, filters, strides=1, padding='SAME').shape
print(output)
# (1, 4, 4, 1)

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

x_ = np.ones((1, 4, 4, 5))
x_NHWC = Tensor(x_, mindspore.float32)
x = ops.transpose(x_NHWC, (0, 3, 1, 2))
net = nn.Conv2d(5, 1, (2, 3), stride=1)
output = ops.transpose(net(x), (0, 2, 3, 1)).shape
print(output)
# (1, 4, 4, 1)