1. 背景:
使用 mindspore 学习神经网络,打卡第6天;
2. 训练的内容:
使用 mindspore 的函数式自动微分常见用法;
3. 常见的用法小节:
函数式自动微分支持一系列常用的函数
3.1 损失函数:
binary_cross_entropy_with_logits 是一个损失函数,计算预测值和目标值之间的二值交叉熵损失
# 使用函数式自动微分的设计理念,
# 自动微分接口 grad 和 value_and_grad
import numpy as np
import mindspore
from mindspore import nn
from mindspore import ops
from mindspore import Tensor, Parameter
# 构建输入参数
x = ops.ones(5, mindspore.float32)
y = ops.zeros(3, mindspore.float32)
w = Parameter(Tensor(np.random.randn(5, 3), mindspore.float32), name='w')
b = Parameter(Tensor(np.random.randn(3,), mindspore.float32), name='b')
# binary_cross_entropy_with_logits 是一个损失函数,计算预测值和目标值之间的二值交叉熵损失。
def function_x_y(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(x, y, w, b)
print(loss)
3.2 微分函数与梯度计算
为了优化模型参数,需要求参数对loss的导数, 可使用 mindspore 的 grad 方法;grad函数的两个入参
- fn: 求导的函数;
- grad_position: 求导输入位置索引
grad_fn = mindspore.grad(function_x_y, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)
# stop gradient
# 将function改为同时输出loss和z的function_with_logits
def fucntion_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(fucntion_with_logits, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)
3.3 Stop Gradient
当我们希望函数输出多项时,微分函数会求所有输出项对参数的导数。此时如果想实现对某个输出项的梯度截断,或消除某个Tensor对梯度的影响,需要用到Stop Gradient操作
# 想实现对某个输出项的梯度截断,或消除某个Tensor对梯度的影响,需要用到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)
3.4 神经网络梯度计算
通过Cell构造同样的神经网络,利用函数式自动微分来实现反向传播
# 神经网络梯度计算
# 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
# 使用 trainable_params()方法取出求导的参数
grad_fn = mindspore.value_and_grad(
forward_fn, None,
weights=model.trainable_params())
loss, grads = grad_fn(x, y)
print(grads)
相关链接:
- https://xihe.mindspore.cn/events/mindspore-training-camp
- https://gitee.com/mindspore/docs/blob/r2.3.0rc2/tutorials/source_zh_cn/beginner/autograd.ipynb
文章评论