1 系统环境
- 硬件环境(Ascend/GPU/CPU): Ascend910
- MindSpore版本: mindspore=2.0.0
- 执行模式(PyNative/ Graph): PyNative
- Python版本: Python=3.8
- 操作系统平台: Linux
2 报错信息
2.1 问题描述
在使用MindSpore的PyNative模式进行模型训练时,尝试通过mindspore.value_and_grad接口获取梯度计算函数,但程序抛出了AttributeError异常。具体场景为在自定义损失函数中计算梯度以便进行参数优化。一个简单的全连接神经网络,并在前向计算后使用value_and_grad方法获取梯度。相关代码段如下:
2.2 脚本信息
import mindspore
from mindspore import nn, Tensor
import numpy as np
class SimpleNet(nn.Cell):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc = nn.Dense(10, 1)
def construct(self, x):
return self.fc(x)
net = SimpleNet()
optimizer = nn.SGD(net.trainable_params(), learning_rate=0.01)
def forward_fn(x, y):
output = net(x)
loss = nn.MSELoss()(output, y)
return loss
# 获取梯度函数时出现报错
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)
2.3 报错信息
AttributeError: module ‘mindspore’ has no attribute ‘value_and_grad’
3 根因分析
根据以上信息可以知道使用的MindSpore=2.0.0,在MindSpore=2.0.0版本中value_and_grad不在mindspore.nn模块中。
4 解决方案
通过以上分析可以知道是value_and_grad算子的导入路径不对,查看2.0.0版本的文档可知,value_and_grad是直接在mindspore下面。所以可以如下修改。
import mindspore
from mindspore import nn, Tensor, value_and_grad # 重点:value_and_grad导入
import numpy as np
class SimpleNet(nn.Cell):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc = nn.Dense(10, 1)
def construct(self, x):
return self.fc(x)
net = SimpleNet()
optimizer = nn.SGD(net.trainable_params(), learning_rate=0.01)
def forward_fn(x, y):
output = net(x)
loss = nn.MSELoss()(output, y)
return loss
# 修正:使用 ops.value_and_grad
grad_fn = value_and_grad(forward_fn,
grad_position=None,
weights=optimizer.parameters,
has_aux=False) # 注意:你的函数只返回loss,应设为False
# 使用示例
x = Tensor(np.random.randn(32, 10).astype(np.float32))
y = Tensor(np.random.randn(32, 1).astype(np.float32))
loss, grads = grad_fn(x, y)
print(f"Loss: {loss}")
print(f"Gradients calculated: {len(grads)}")