问题描述:
【功能模块】
mindspore 1.3.0
python 3.7.5
【操作步骤&问题现象】
mindspore池化操作pad到底是怎么补零的?跟pytorch池化操作后的结果完全不一样,导致迁移过来的模型推理出来乱七八糟
为什么不能像pytorch那样设定padding值呢,或者有什么办法可以使mindspore的池化层可以像pytorch池化一样padding?
下面是测试mindspore和pytorch最大池化操作的样例截图,同样都是k=3,s=2,输出的尺寸大小也一样,但内容却南辕北辙。
看了半天都没搞懂mindspore这个池化是按什么规则的,补零是怎么个补零法?
【截图信息】
【日志信息】(可选,上传日志内容或者附件)
import numpy as np
from mindspore import Tensor
import mindspore.nn as nn2
import mindspore.common.dtype as mstype
import torch
import torch.nn as nn
a = np.random.randn(1,2,3,4)
m1 = nn.MaxPool2d(3, stride=2, padding=1)
m2 = nn2.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')
input1 = torch.Tensor(a)
input2 = Tensor(a, mstype.float32)
output1 = m1(input1)
output2 = m2(input2)
print("input\n", a)
print("output_pytorch\n", output1)
print("output_mindspore\n", output2)
解答:
mindspore的计算方式是和TensorFlow保持一致的,请检查一下torch的属性是否有差异
import mindspore as ms
import numpy as np
from mindspore import Tensor
import mindspore.nn as nn
import tensorflow as tf
np.random.seed(10)
a = np.random.randn(1, 2, 3, 4)
tf_input = tf.constant(a)
nn_input = Tensor(a).astype(ms.float32)
net1 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same")
tf_out = tf.nn.max_pool2d(tf_input, ksize=(3, 3), strides=(2, 2), padding="SAME")
nn_out = net1(nn_input)
print("tf_out: ", tf_out)
print("nn_out: ", nn_out)
"""
ms_out
Tensor(shape=[1, 1, 2, 4], dtype=Float32, value=
[[[[ 1.33158648e+00, 1.02827406e+00, 1.48453701e+00, 4.45137620e-01],
[ 6.21335983e-01, 1.35136873e-01, 1.48453701e+00, 2.38496733e+00]]]])
ms_out.shape
(1, 1, 2, 4)
tf_out: tf.Tensor(
[[[[1.3315865 1.02827408 1.484537 0.44513761]
[0.62133597 0.13513688 1.484537 2.38496733]]]], shape=(1, 1, 2, 4), dtype=float64)
"""
看下这里的实现: https://github.com/lvyufeng/easy_mindspore/blob/main/easy_mindspore/nn/pooling_layers.py#L23
这个算子是对标TensorFlow同名算子的,跟torch的并不能完全对等。如果要达到torch算子相同的效果,需要在调用torch.nn.MaxPool2d算子之前,先使用torch.nn.ConstantPad2d算子打Pad到合适的形式。