# 使用MindSpore报错AttributeError: 'Parameter' object has no attribute 'uniform\_'

**1. 系统环境**

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

软件环境: MindSpore 版本: 2.0.0

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

Python 版本: 3.7.6

操作系统平台: linux

**2. 报错信息**

2.1 问题描述

将pytorch转换成mindspore代码的过程中报错AttributeError: 'Parameter' object has no attribute 'uniform\_'，按照官方文档，将其中的self.parameters\(\)改成了mindspore中nn.Cell模块里面的get\_parameters\(\)方法，返回的也是迭代器。

2.2 脚本信息

```
def init_parameters(self):
        init_range = 0.1
        for param in self.parameters():
            param.data.uniform_(-init_range, init_range)
```

**3. 根因分析**

param.data.uniform\_\(-init\_range, init\_range\) 这个是torch的写法

torch 的Tensor支持uniform\_的api，具体参考https://pytorch.org/docs/stable/generated/torch.Tensor.uniform\_.html\#torch.Tensor.uniform\_

mindspore的Parameter是Tensor的子类，是不支持uniform\_的

然后用uniform\_在mindspore的API文档中查找，https://www.mindspore.cn/docs/zh-CN/r2.2/search.html?q=uniform\_&check\_keywords=yes&area=default

可以找到如下资料。

```
torch.nn.init
torch.nn.init 需要一个Tensor作为输入，将输入的Tensor原地修改为目标结果。

import torch

x = torch.empty(2, 2)
torch.nn.init.uniform_(x)
运行以上代码之后，x将不在是非初始化状态，其元素将服从均匀分布。

mindspore.common.initializer
mindspore.common.initializer 用于在并行模式中延迟Tensor的数据的初始化。只有在调用了 init_data() 之后，才会使用指定的 init 来初始化Tensor的数据。每个Tensor只能使用一次 init_data() 。

import mindspore
from mindspore.common.initializer import initializer, Uniform

x = initializer(Uniform(), [1, 2, 3], mindspore.float32)
```

在运行以上代码之后，x 其实尚未完成初始化。如果此时 x 被用来计算，将会作为0来处理。然而，在打印时，会自动调用 init\_data\(\) 。

**4. 解决方案**

三种解决方法

1.在创建网络的初始化阶段创建一个Parameter对象，用initializer进行Uniform初始化，然后给对应的参数进行初始化操作

2.调用Parameter对象的set\_data\(data, slice\_shape=False\)方法，具体参考https://www.mindspore.cn/docs/zh-CN/r2.2/api\_python/mindspore/mindspore.Parameter.html?highlight=parameter\#mindspore.Parameter

3.利用算子mindspore.ops.assign\(variable, value\) 进行Parameter对象的赋值

这里不建议直接给Parameter对象等于一个Tensor对象进行赋值操作，某些场景下会不起效。

方案1：

```
class Net(nn.Cell):
    def __init__(self):
        super().__init__()
        weight = Parameter(initializer(Uniform(0.1), [3, 3, 1, 1], ms.float32))
        self.conv2d = nn.Conv2d(3, 3, 1, has_bias=False, weight_init=weight)

    def construct(self, x):
        z = self.conv2d(x)
        return z
```

方案2：

```
    def init_parameters(self):
        init_range = ms.Tensor(0.1)
        for param in self.get_parameters():
            param.set_data(ops.uniform(param.shape, -init_range, init_range))
```

方案3：

```
    def init_parameters(self):
        init_range = ms.Tensor(0.1)
        for param in self.get_parameters():
            ops.assign(param, ops.uniform(param.shape, -init_range, init_range))
```

