Hardware Environment(Ascend/GPU/CPU): GPU
Software Environment:
import numpy as np import mindspore.nn as nn import mindspore.ops as ops from mindspore import Tensor from mindspore import ParameterTuple, Parameter from mindspore import dtype as mstype x = Tensor([[0.8, 0.6, 0.2], [1.8, 1.3, 1.1]], dtype=mstype.float32) y = Tensor([[0.11, 3.3, 1.1], [1.1, 0.2, 1.4], [1.1, 2.2, 0.3]], dtype=mstype.float32) class Net(nn.Cell): def __init__(self): super(Net, self).__init__() self.matmul = ops.MatMul() self.z = Parameter(Tensor(np.array([1.0], np.float32)), name='z') def construct(self, x, y): x = x * self.z out = self.matmul(x, y) return out class GradNetWrtN(nn.Cell): def __init__(self, net): super(GradNetWrtN, self).__init__() self.net = net self.grad_op = ops.GradOperation(sens_param=True) self.grad_wrt_output = Tensor([[0.1, 0.6, 0.2]], dtype=mstype.float32) def construct(self, x, y): gradient_function = self.grad_op(self.net) return gradient_function(x, y, self.grad_wrt_output) output = GradNetWrtN(Net())(x, y) print(output)
报错信息:ValueError: For ‘MatMul’, the input dimensions must be equal, but got ‘x1_col’: 2 and ‘x2_row’: 1. And ‘x’ shape [2, 3](#), ‘y’ shape [1, 3](#).
/root/gitee/mindspore/rank_0/om/analyze_fail.dat
,截取部分如下:grad_math_ops.py
文件中的253行被调用的,是MatMul算子的反向传播规则生成的算子,MatMul算子的反向传播规则如下所示:x
和dout
,x
的shape确认是对的,那就是dout
的shape是错误的。dout
只能从外部传进来,也就是用例中传的self.grad_wrt_output。也就是self.grad_wrt_output的shape是错误的。GradOperation传入的sens值,是脚本从外部传入的关于正向网络输出的梯度,能起到梯度值缩放的作用。既然是关于正向网络输出的梯度,那么sens值的shape是需要跟正向网络的输出shape(可以通过调用一下正向网络,打印它的输出shape得到)一致的。我们把上面用例的self.grad_wrt_output的值改一下,如下:
self.grad_wrt_output = Tensor([[0.1, 0.6, 0.2], [0.8, 1.3, 1.1]], dtype=mstype.float32)
最后就可以解决该问题了。
在MindSpore官方教程的自动微分章节里也能看到相关指导:
执行MindSpore用例报错时,要善于利用报错信息去分析问题,也可以多看看官方教程。
https://www.mindspore.cn/tutorials/zh-CN/r1.7/beginner/autograd.html#梯度值缩放
https://www.mindspore.cn/tutorials/experts/zh-CN/r1.7/debug/mindir.html#如何根据analyze-faildat文件分析图推导失败的原因