函数式自动微分
mindspore这门课程中把它叫做函数自动微分,其实就是反向传播。
MindSpore使用函数式自动微分的设计理念,提供更接近于数学语义的自动微分接口grad和value_and_grad。
微分函数与梯度计算
为了优化模型参数,需要求参数对loss的导数:此时我们调用mindspore.grad函数,来获得function的微分函数。
这里使用了grad函数的两个入参,分别为:
fn:待求导的函数。
grad_position:指定求导输入位置的索引。
grad_fn = mindspore.grad(function, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)
神经网络梯度计算
首先定义一个神经网络,并对他进行实例化。
# Define model
class Network(nn.Cell):
def __init__(self):
super().__init__()
self.w = w
self.b = b
def construct(self, x):
z = ops.matmul(x, self.w) + self.b
return z
# Instantiate model
model = Network()
# Instantiate loss function
loss_fn = nn.BCEWithLogitsLoss()
完成后,由于需要使用函数式自动微分,需要将神经网络和损失函数的调用封装为一个前向计算函数。
# Define forward function
def forward_fn(x, y):
z = model(x)
loss = loss_fn(z, y)
return loss
完成后,我们使用value_and_grad接口获得微分函数,用于计算梯度。
grad_fn = mindspore.value_and_grad(forward_fn, None, weights=model.trainable_params())
loss, grads = grad_fn(x, y)
print(grads)
输出:
(Tensor(shape=[5, 3], dtype=Float32, value=
[[ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02],
[ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02],
[ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02],
[ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02],
[ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02]]), Tensor(shape=[3], dtype=Float32, value= [ 2.48264950e-02, 3.22011769e-01, 2.47933399e-02]))
打卡: