共计 2472 个字符,预计需要花费 7 分钟才能阅读完成。
1 报错形容 1.1 零碎环境 Hardware Environment(Ascend/GPU/CPU): GPUSoftware Environment:MindSpore version (source or binary): 1.7.0Python version (e.g., Python 3.7.5): 3.7.5OS platform and distribution (e.g., Linux Ubuntu 16.04): Ubuntu 18.04.4 LTSGCC/Compiler version (if compiled from source): 7.5.01.2 根本信息 1.2.1 源码 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)
1.2.2 报错报错信息: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.
2 起因剖析依据报错信息,是 MatMul 算子在 infer shape 时查看输出的 shape 不正确,具体是 x1 的列数不等于 x2 的行数。关上报错提供的 debug 文件 /root/gitee/mindspore/rank_0/om/analyze_fail.dat,截取局部如下:
参考 analyze_fail.dat 文件剖析领导,可知是第一个红框的 MatMul 在 infer shape 时报错。而后再看第二个红框,该算子的第一个输出的 shape 为 (2, 3),第二个输出的 shape 为 (1, 3),跟报错信息吻合(留神这里 MatMul 的 transpose_a 属性为 True)。最初咱们看第三个红框,该 MatMul 是在 grad_math_ops.py 文件中的 253 行被调用的,是 MatMul 算子的反向流传规定生成的算子,MatMul 算子的反向流传规定如下所示:
咱们看到这个 MatMul 算子的两个输出,别离是 x 和 dout,x 的 shape 确认是对的,那就是 dout 的 shape 是谬误的。从反向主动微分的机制咱们晓得,反向局部的第一个算子是从正向局部的最初一个算子的反向流传规定生成的。而正向网络只有一个 MatMul 算子,且是最初的一个算子,所以 infer shape 报错的这个反向 MatMul 算子,是从这一个正向的 MatMul 算子的反向流传规定生成的(此用例比较简单,正向网络中只有一个 MatMul 算子,更简单的用例能够参考 analyze_fail.dat 文件剖析领导,联合算子输入输出推断出某个反向算子是从哪个正向算子的反向流传规定生成的),而且是反向局部的第一个算子。因而这个反向 MatMul 的第二个输出 dout 只能从内部传进来,也就是用例中传的 self.grad_wrt_output。也就是 self.grad_wrt_output 的 shape 是谬误的。3 解决办法 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 官网教程的主动微分章节里也能看到相干领导:
4 总结执行 MindSpore 用例报错时,要长于利用报错信息去剖析问题,也能够多看看官网教程。5 参考文档 https://www.mindspore.cn/tuto… 梯度值缩放 https://www.mindspore.cn/tuto… 如何依据 analyze-faildat 文件剖析图推导失败的起因