# 使用MindSpore Cell的construct报错AttributeError: For 'Cell', the method 'construct' is not defined.

**1. 系统环境**

硬件环境\(Ascend/GPU/CPU\): Ascend/GPU/CPU

软件环境: MindSpore 版本: 2.0.0

执行模式（静态图/动态图）： 不限

Python 版本: 3.7

操作系统平台: linux

**2. 报错信息**

2.1 问题描述

在pytorch迁移MindSpore过程中，错误信息如下。

2.2 报错信息

```
File "main_attention.py", line 88, in <module>
    autofe.fit_attention(args)
  File "/root/FETCH-main/autofe.py", line 251, in fit_attention
    actions, log_probs, m1_output, m2_output, m3_output, action_softmax = self.ppo.choose_action_c(
  File "/root/FETCH-main/feature_engineer/attention_searching/ppo.py", line 48, in choose_action_c
    action_softmax, m1_output, m2_output, m3_output = self.actor_c(input_c, step)
  File "/root/miniconda3/lib/python3.8/site-packages/mindspore/nn/cell.py", line 659, in __call__
    raise AttributeError("For 'Cell', the method 'construct' is not defined.")
AttributeError: For 'Cell', the method 'construct' is not defined.
```

2.3 脚本信息

```
actions, log_probs, m1_output, m2_output, m3_output, action_softmax = self.ppo.choose_action_c(workers_c[i].states[-1], step, epoch, c_ops, sample_rule)

actions, log_probs, m1_output, m2_output, m3_output, action_softmax = ppo.choose_action_c(state_c, step, epoch, c_ops, sample_rule)
```

脚本定义如下：

```
self.actor_c = Actor(args, data_nums, operations_c, d_model, d_k, d_v, d_ff, n_heads, dropout=dropout, enc_load_pth=args.enc_c_pth)

class Actor(nn.Cell):
    def __init__(self, args, data_nums, operations, d_model, d_k, d_v, d_ff, n_heads, dropout=None, enc_load_pth=None):
        super(Actor, self).__init__()
        self.args = args
        self.reduction_dimension = ReductionDimension(data_nums, d_model)
        self.encoder = EncoderLayer(d_model, d_k, d_v, d_ff, n_heads, dropout)
        logging.info(f"Randomly initial encoder")
        if os.path.exists(enc_load_pth):
            self.encoder.load_state_dict(mindspore.load(enc_load_pth))
            logging.info(f"Successfully load encoder, enc_load_pth:{enc_load_pth}")
        self.select_operation = SelectOperations(d_model, operations)
        self.c_nums = len(args.c_columns)
        self.layernorm = nn.LayerNorm(normalized_shape=(data_nums,))
    def forward(self, input, step):
        input_norm = self.layernorm(input)
        data_reduction_dimension = self.reduction_dimension(input_norm)
        data_reduction_dimension = mindspore.ops.where(mindspore.ops.isnan(data_reduction_dimension),
                                               mindspore.ops.full_like(data_reduction_dimension, 0), data_reduction_dimension)
        encoder_output = self.encoder(data_reduction_dimension)
        encoder_output = mindspore.ops.where(mindspore.ops.isnan(encoder_output), mindspore.ops.full_like(encoder_output, 0), encoder_output)
        output = self.select_operation(encoder_output)
        output = mindspore.ops.where(mindspore.ops.isnan(output), mindspore.ops.full_like(output, 0), output)
        operation_softmax = mindspore.ops.softmax(output, dim=-1)
        return operation_softmax, data_reduction_dimension.squeeze(), \
               encoder_output.squeeze(), output
```

**3. 根因分析**

根据文档：[https://www.mindspore.cn/docs/zh-CN/r2.0/migration\_guide/typical\_api\_comparision.html?highlight=device\#nn.Module](https://www.mindspore.cn/docs/zh-CN/r2.0/migration_guide/typical_api_comparision.html?highlight=device#nn.Module)

使用 PyTorch 构建网络结构时，我们会用到nn.Module 类，通常将网络中的元素定义在\_\_init\_\_ 函数中并对其初始化，将网络的图结构表达定义在forward 函数中，通过调用这些类的对象完成整个模型的构建和训练。nn.Module 不仅为我们提供了构建图接口，它还为我们提供了一些常用的 API ，来帮助我们执行更复杂逻辑。

MindSpore 中的 nn.Cell 类发挥着和 PyTorch 中 nn.Module 相同的作用，都是用来构建图结构的模块，MindSpore 也同样提供了丰富的 API 供开发者使用，虽然名字不能一一对应，但 nn.Module 中常用的功能都可以在nn.Cell 中找到映射。

**4. 解决方案**

```
import mindspore as ms
from mindspore import ops, nn
class Actor(nn.Cell):
    def __init__(self, args, data_nums, operations, d_model, d_k, d_v, d_ff, n_heads, dropout=None, enc_load_pth=None):
        super(Actor, self).__init__()
        pass # 原代码
    def construct(self, input, step):
        pass # 原代码
```

