昇思25天学习打卡营第5天 |昇思MindSpore 函数式自动微分学习与总结

神经网络的训练主要使用反向传播算法,该算法通过计算梯度来优化模型参数。自动微分是一种计算可导函数在某点处导数值的方法,它是反向传播算法的基础。自动微分能够将复杂的数学运算分解为一系列简单的基本运算,极大地简化了求导过程。

MindSpore通过函数式自动微分的设计理念,提供了更接近数学语义的自动微分接口gradvalue_and_grad

环境配置

%%capture captured_output
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14

函数与计算图

计算图是用图论语言表示数学函数的一种方式。在深度学习中,计算图用于表达神经网络模型的计算过程。下面的计算图展示了一个简单的单层线性变换模型。

  • 输入:𝑥
  • 目标值:𝑦
  • 参数:𝑤和𝑏
import numpy as np
import mindspore
from mindspore import nn, ops, Tensor, Parameter

x = ops.ones(5, mindspore.float32)  # input tensor
y = ops.zeros(3, mindspore.float32)  # expected output
w = Parameter(Tensor(np.random.randn(5, 3), mindspore.float32), name='w') # weight
b = Parameter(Tensor(np.random.randn(3,), mindspore.float32), name='b') # bias

计算函数

根据计算图描述的计算过程,构造计算函数。使用binary_cross_entropy_with_logits计算损失。

def function(x, y, w, b):
    z = ops.matmul(x, w) + b
    loss = ops.binary_cross_entropy_with_logits(z, y, ops.ones_like(z), ops.ones_like(z))
    return loss

loss = function(x, y, w, b)
print(loss)  # 输出:Tensor(shape=[], dtype=Float32, value= 0.914285)

微分函数与梯度计算

为了优化模型参数,需要计算参数对loss的导数:∂loss/∂𝑤 和 ∂loss/∂𝑏。使用mindspore.grad函数获得微分函数。

grad_fn = mindspore.grad(function, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)

Stop Gradient

如果希望屏蔽某个输出项对梯度的影响,可以使用ops.stop_gradient操作。

def function_stop_gradient(x, y, w, b):
    z = ops.matmul(x, w) + b
    loss = ops.binary_cross_entropy_with_logits(z, y, ops.ones_like(z), ops.ones_like(z))
    return loss, ops.stop_gradient(z)

grad_fn = mindspore.grad(function_stop_gradient, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)

Auxiliary Data

使用gradvalue_and_grad接口的has_aux参数,可以自动实现前文手动添加stop_gradient的功能。

grad_fn = mindspore.grad(function_with_logits, (2, 3), has_aux=True)
grads, (z,) = grad_fn(x, y, w, b)
print(grads, z)

神经网络梯度计算

使用面向对象编程范式的nn.Cell构造神经网络模型,并使用函数式自动微分来实现反向传播。

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

model = Network()
loss_fn = nn.BCEWithLogitsLoss()

def forward_fn(x, y):
    z = model(x)
    loss = loss_fn(z, y)
    return loss

grad_fn = mindspore.value_and_grad(forward_fn, None, weights=model.trainable_params())
loss, grads = grad_fn(x, y)
print(grads)

总结

通过上述示例,展示了MindSpore中如何使用函数式自动微分接口gradvalue_and_grad来计算梯度。
这些接口提供了更接近数学语义的自动微分方式,大大简化了深度学习模型的训练过程。自动微分通过将复杂的数学运算分解为一系列简单的基本运算,极大地降低了框架的使用门槛。

总结

操作说明示例
ops.ones创建全为1的Tensorops.ones(5, mindspore.float32)
ops.zeros创建全为0的Tensorops.zeros(3, mindspore.float32)
Parameter定义参数Parameter(Tensor(np.random.randn(5, 3), mindspore.float32), name='w')
mindspore.grad计算梯度函数grad_fn = mindspore.grad(function, (2, 3))
ops.stop_gradient停止梯度传播ops.stop_gradient(z)
nn.Cell定义神经网络模型class Network(nn.Cell):
value_and_grad计算值和梯度grad_fn = mindspore.value_and_grad(forward_fn, None, weights=model.trainable_params())

本章总结

自动微分
计算图
函数与计算函数
微分函数与梯度计算
Stop Gradient
Auxiliary Data
神经网络梯度计算
  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值