MindSpore报错“The function construct need xx positional argument ...“怎么办

昇思报错"The function construct need xx positional argument …"怎么办

1. 系统环境

Hardware Environment(Ascend/GPU/CPU): ALL
Software Environment:
MindSpore version (source or binary): 1.6.0 & Earlier versions
Python version (e.g., Python 3.7.5): 3.7.6
OS platform and distribution (e.g., Linux Ubuntu 16.04): Ubuntu
GCC/Compiler version (if compiled from source):

2. python代码样例

from mindspore.nn import Cell

class Net(Cell):
    def construct(x):
        return x

net = Net()
net(2)

3. 报错信息

Traceback (most recent call last):
File “error_map/01/param_not_match.py”, line 10, in
net(2)
File “/usr/local/python3.7/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 469, in call
self._check_construct_args(*args, **kwargs)
File “/usr/local/python3.7/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 400, in _check_construct_args
f"The function construct needs {positional_args} positional argument and {default_args} default "
TypeError: The function construct needs 0 positional argument and 0 default argument, but provided 1

4. 原因分析

首先查看报错信息“TypeError: The function construct needs 0 positional argument and 0 default argument, but provided 1”

报错信息直译为:函数construct需要0个位置参数和0个默认参数,但提供了1个

为了理解报错信息的含义,需要解释两个名词positional argumentdefault argument。要解释这两个名词首先要理解什么是argument(调用时输入的实参,有具体的值),说argument就必须要说Parameter(函数定义时声明的形参,没有具体的值)。以样例代码为列函数def construct(x)定义中的x是Parameter, net(2)中的2是argument。positional argument是需要通过输入顺序(位置)来识别具体输入和Parameter绑定关系的argument。 Python官方资料中并没有default argument这个概念,只有default value;含有default value的Parameter在函数调用时可以不输入对应的argument, 框架在函数调用时会使用default value作为argument。

理解位置参数默认参数后,可以将报错信息更直白表述为:类Netconstruct函数需要0个入参,但提供了1个

这样一来文字本身的含义是清晰了, 但依然存在两个疑问:

  1. 什么时候如何调用了类Netconstruct函数?
  2. Netconstruct函数原型def construct(x)有一个入参数x,为何报错信息胡扯需要0个入参?

疑问1的答案是:

MindSpore框架代码为类nn.Cell重写了魔法函数__call__,并在__call__中调用了construct,重写 __call__的效果是可以像调用函数一样调用类实例,例如样例代码中的:net(2);感兴趣的同学可以自行查看框架发布包中nn.Cell.__call__的定义。

疑问2的答案是:

construct是通过NetInstance methods机制调用的, construct的首个入参是由Python框架插入的类实例(与函数声明中的第一个Parameter对应,一般叫作self, 样例中叫x),调用时输入的2其实是它的第2个argument。经过python框架的调用原型为 construct(net, 2),它有2个arguments。

用如下Python原生代码会报类似错误:TypeError: construct() takes 1 positional argument but 2 were given

class Net:
    def construct(x):
        print(str(x))

net = Net()
net.construct(1)

MindSpore的报错信息是站在直接调用Instance methods角度来报的,它并不认为Python框架插入的类实例为用户输入argument,从def construct(x)的声明来看,它不需要调用方提供arguments,所以样例代码中MindSpore报错:“TypeError: The function construct needs 0 positional argument and 0 default argument, but provided 1”

5. 解决方法

通过上一章节的分析可以看出def construct(x):的定义是错误的,缺少了self入参,其正确定义为:def construct(self, x):

6. 平台改进点

报错信息上尽量与原生python保持一致,方便开发者进行理解。

优化后报错信息如下:

Traceback (most recent call last):
File “/home/zhangzhaoju/ms_dev/error_map/01/param_not_match.py”, line 10, in
net(2)
File “/usr/local/python3.7/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 475, in call
self._check_construct_args(*args, **kwargs)
File “/usr/local/python3.7/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 402, in _check_construct_args
raise TypeError(f"Method construct() of class {self.class.name}, "
TypeError: Method construct() of class Net takes 0 positional arguments but 1 were given.

7. 总结

MindSpore前端语法是Python语法的子集, 撰写模型时需要遵循Python语法。学习一些python语言的书籍,对于MindSpore运行机制理解和问题定位很有帮助。

8. 参考文档

魔法函数原理:https://docs.python.org/3/reference/datamodel.html#special-method-names

实例函数原理:https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy (instanse method 章节)

9.工程案例

可以访问https://gitee.com/qmckw/mindspore_test/blob/master/%E6%AD%A3%E5%88%99%E5%8C%96%E5%AE%9E%E9%AA%8C.ipynb查看。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

irrationality

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值