昇思25天打卡营-mindspore-ML- Day6-函数式自动微分

Day6 今天学习函数式自动微分
学习背景: net的训练一般用BP算法,模型预测值(logits)与正确标签(label)
送入损失函数(loss function)获得loss,然后反向传播计算,求出gradients梯度
从而更新模型参数(parameters)。

自动微分能够计算函数导数值,将一个复杂的数学运算分解为一系列简单的基本运算
对用户屏蔽了求导细节和过程,降低了使用门槛。


下面是一个简单的单层线性变换模型

## 本地时,考虑下面的操作
##%%capture captured_output
## 实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
##!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
from mindspore import ops
from mindspore import Tensor, Parameter

函数与计算图:

## 计算图是“用图论表示function”,是deeplearning框架表达model的统一方法。

## 接下来,将根据此计算图构造计算函数和神经网络
## (x为输入,y为正确值,u和b是待优化的参数)

## defines the input x, expected output y, weight w, and bias b for a neural network layer.
## These parameters will be used in the training and inference of the neural network.

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计算predict和目标值之间的二值交叉熵损失

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值
loss = function(x, y, w, b)
print(loss)

## 接下来是求导过程的了解,调用mindspore.grad得到function的微分函数
## grad函数有两个参数,fn为待导入的函数;grad_position为制定求导输入位置的索引。
## 然后,求导时,loss对参数的导数可以得到,但只有loss一项
## 如果要得到微分函数的所有输出项对参数的导数,同时实现对某个输出项的梯度截断、
## 需要用到Stop Gradien操作

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


def function_with_logits(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, z

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

## 如果要屏蔽掉z对梯度的影响,只求参数对loss的导数

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(辅助数据):除了第一个输出项外的其他输出

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。

## 下面是通过Cell构造同样的神经网络,再用函数式自动微分实现bp
 

# 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()

## 接着,进行函数式自动微分: 将net和loss function的调用,封装为一个前向计算函数。
# 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)

完成时间:

Summary:

关于MindSpore框架中的函数式自动微分的学习。通过一个简单的单层线性变换模型示例,介绍了如何使用MindSpore进行梯度计算和神经网络训练。以下是详细的笔记:

MindSpore 函数式自动微分教程

- 主题:函数式自动微分在神经网络训练中的应用。

- 目的:介绍如何使用MindSpore实现自动微分,降低深度学习框架的使用门槛。

 1. 函数式自动微分概念

- 反向传播:用于神经网络训练的基本算法。

- 自动微分:计算可导函数在某点处导数值的方法,是实现反向传播的关键技术。

2. MindSpore自动微分接口

- `grad`:基本的梯度计算接口。

- `value_and_grad`:同时获取函数值和梯度的接口。

 3. 示例模型

- 模型类型:单层线性变换模型。

- 参数:权重`w`和偏置`b`。

 4. 计算图与自动微分

- 计算图:表示数学函数和神经网络模型的图论方法。

- MindSpore计算图:用于构建和执行自动微分。

 5. 代码实现

- 导入库:`numpy`, `mindspore`, `nn`, `ops`, `Tensor`, `Parameter`。

- 定义参数:使用`Parameter`封装权重和偏置。

- 构建计算函数:实现单层线性变换和损失函数计算。

 6. 梯度计算

- 使用`grad`:获取梯度计算函数。

- 执行梯度函数:计算损失函数对权重和偏置的梯度。

 7. Stop Gradient操作

- 目的:在某些情况下截断或消除Tensor对梯度的影响。

- 方法:使用`ops.stop_gradient`接口。

 8. 辅助数据(Auxiliary data)

- 概念:函数除第一个输出外的其他输出。

- 使用场景:在自动微分中处理多个输出项。

 9. 神经网络梯度计算

- 面向对象方法:通过继承`nn.Cell`构造神经网络。

- 反向传播实现:使用函数式自动微分进行梯度计算。

 10. 模型实例化与训练

- 模型实例化:创建神经网络实例。

- 损失函数实例化:创建损失函数实例。

- 前向计算封装:将模型和损失函数调用封装为前向计算函数。

 11. 自动微分应用

- `value_and_grad`接口:获取微分函数并计算梯度。

- 模型参数处理:使用`model.trainable_params()`获取可求导参数。

 12. 结果验证

- 梯度一致性:验证通过不同方法计算得到的梯度是否一致。

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值