昇思MindSpore学习笔记7--函数式自动微分

摘要:

介绍了昇思MindSpore神经网络训练反向传播算法中函数式自动微分的使用方法和步骤。包括构造计算函数和神经网络、grad获得微分函数,以及如何处理停止渐变、获取辅助数据等内容。

一、概念要点

神经网络训练主要使用反向传播算法

        准备模型预测值logits与正确标签label

        损失函数loss function计算loss

        反向传播计算梯度gradients

        更新模型参数parameters

自动微分

        计算可导函数在某点处的导数值

        将复杂的数学运算分解为一系列简单的基本运算

MindSpore函数式自动微分接口

        grad

        value_and_grad

二、环境准备

安装minspore模块

!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.3.0rc1

导入numpy、minspore、nn、ops等相关模块

import numpy as np
import mindspore
from mindspore import nn
from mindspore import ops
from mindspore import Tensor, Parameter

三、函数与计算图

计算图是用图论语言来表示数学函数。

深度学习框架用来表达神经网络模型。

以下图为例构造计算函数和神经网络。

在这个模型中,x为输入,z为预测值,y为目标值,w和b是需要优化的参数。

根据计算图表达的计算过程,构造计算函数。

binary_cross_entropy_with_logits

        损失函数,计算预测值z和目标值y之间的二值交叉熵损失。

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

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)

输出:

1.5375124

四、微分函数与梯度计算

优化模型参数需要对参数w、b求loss的导数:

调用mindspore.grad函数获得function的微分函数。

 注:grad获得微分函数是一种函变换,即输入为函数,输出也为函数。

grad_fn = mindspore.grad(function, (2, 3))

mindspore.grad函数的两个入参:

fn: 求导函数。

grad_position:求导参数的索引位置。

参数 w和b在function入参对应的位置为(2, 3)。

执行微分函数获得w、b对应的梯度。

grads = grad_fn(x, y, w, b)
print(grads)

输出:

(Tensor(shape=[5, 3], dtype=Float32, value=
[[ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]]), 
Tensor(shape=[3], dtype=Float32, value=
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]))

五、Stop Gradient停止渐变

消除某个Tensor对梯度的影响或实现对某个输出项的梯度截断

通常情况下,求导函数的输出只有loss一项。

微分函数会对参数求所有输出项的导数。

function_with_logits修改原function支持同时输出loss和z

获得自动微分函数并执行。

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)

输出:

(Tensor(shape=[5, 3], dtype=Float32, value=
[[ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00],
 [ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00],
 [ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00],
 [ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00],
 [ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00]]),
 Tensor(shape=[3], dtype=Float32, value=
 [ 1.27216899e+00,  1.20658815e+00,  1.28590846e+00]))

wb对应的梯度值变了。

使用ops.stop_gradient接口屏蔽z对梯度的影响

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)

输出:

(Tensor(shape=[5, 3], dtype=Float32, value=
[[ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]]),
 Tensor(shape=[3], dtype=Float32, value=
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]))

此时wb对应的梯度值与初始function求得的梯度值一致。

六、Auxiliary data辅助数据

函数除第一个输出项外的其他输出。

通常会将loss设置为函数的第一个输出,其他的输出即为辅助数据。

grad和value_and_gradhas_aux参数

设置True,自动实现stop_gradient,返回辅助数据同时不影响梯度计算的效果。

下面仍使用function_with_logits,配置has_aux=True,并执行。

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

输出:

(Tensor(shape=[5, 3], dtype=Float32, value=
[[ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]]),
 Tensor(shape=[3], dtype=Float32, value=
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]))
 [1.4928596  0.48854822 1.7965223 ]

此时wb 对应的梯度值与初始function求得的梯度值一致

同时z能够作为微分函数的输出返回。

七、神经网络梯度计算

下面通过继承nn.Cell构造单层线性变换神经网络

利用函数式自动微分来实现反向传播。

使用mindspore.Parameter封装w、b模型参数作为内部属性

在construct内实现相同的Tensor操作。

# 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接口获得微分函数,用于计算梯度。

Cell封装神经网络模型,模型参数为Cell的内部属性,不需要使用grad_position指定对函数输入求导,因此将其配置为None。

使用model.trainable_params()方法从weights参数取出可以求导的参数。

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.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01],
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]]),
 Tensor(shape=[3], dtype=Float32, value=
 [ 2.72169024e-01,  2.06588134e-01,  2.85908401e-01]))

执行微分函数,可以看到梯度值和前文function求得的梯度值一致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/758686.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5个大气的wordpress付费主题

Sesko赛斯科wordpress外贸主题 适合用于重型机械设备公司建外贸官方网站的橙红色wordpress外贸主题。 https://www.jianzhanpress.com/?p5886 Polar钋啦wordpress外贸主题 制造业wordpress网站模板,适合生产制造企业官方网站使用的wordpress外贸主题。 https:/…

【CV炼丹师勇闯力扣训练营 Day22:§7 回溯1】

CV炼丹师勇闯力扣训练营 代码随想录算法训练营第22天 回溯法其实就是暴力查找,回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,一般可以解决如下几种问题: 组合问题:N个数里面按一定规则找出k个数的集合切割…

weiyang**3.控制台01

1. 搭建单群组FISCO BCOS联盟链 使用开发部署工具 build_chain.sh脚本在本地搭建一条4 节点的FISCO BCOS链,以Ubuntu 22.04 64bit系统为例操作。 1.1 安装依赖 sudo apt install -y openssl curl 1.2 创建操作目录, 下载安装脚本 ## 创建操作目录 cd ~ &&a…

YOLO系列笔记(十八)—— YOLOv1和YOLOv2总结与对比

YOLOv1和的v2总结与对比 YOLOv1主要思想算法架构主干网络损失函数 训练过程网络预测主要成果优化方向 YOLOv2算法架构主干网络损失函数 相较之前的优化添加Batch Normalization引入锚框(Anchor Boxes)机制引入DarkNet-9多尺度输入训练 网络训练第一阶段&…

单片机学习(16)--直流电机驱动

直流电机驱动 15.1直流电机驱动基础知识1.直流电机介绍2.电机驱动电路3.PWM介绍 15.2LED呼吸灯和直流电机调速1.LED呼吸灯代码2.直流电机调速(1)产生PWM的方法(2)工程目录(3)main.c函数 15.1直流电机驱动基…

kaggel-汽车价格预测项目

1.读取数据,查看数据基本概况 import pandas as pd datapd.read_csv(r./car_price_prediction.csv)#查看前5行数据 print(data.head(5))output:ID Price Levy ... Wheel Color Airbags 0 45654403 13328 1399 ... Left wheel Silve…

css 滚动词云

css javascript 实现滚动词云效果 // 163css.js var radius 120; var dtr Math.PI / 180; var d 300; var mcList []; var active false; var lasta 1; var lastb 1; var distr true; var tspeed 10; var size 250; var mouseX 0; var mouseY 0; var howElliptic…

宝塔安装rabbitMQ实战

服务器环境说明 阿里云服务器、宝塔、centos7 一、下载erlang 原因:RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang。 下载地址:http://www.erlang.org/downloads 下载对应的版本&…

进程间通信简介-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

进程间通信简介 进程间通信简介 进程间进程简称IPC(interprocess communication),进程间通信就是在不同进程之间传递信息或交换信息 进程间通信的目的 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的…

互联网算法备案 | 填报指南

一、填报入口 登陆互联网信息服务算法备案系统(以下简称备案系统)进行填报,网址为https://beian.cac.gov.cn。系统首页如图1所示。 图1备案系统首页(示意图) 二、填报流程 填报人员需首先注册并登陆备案系统&#x…

用Roofline模型去分析pytorch和Triton算子

用Roofline模型去分析pytorch和Triton算子 1.参考链接2.测试环境3.安装相关依赖4.锁频5.获取理论算力6.创建测试脚本7.运行测试程序生成Roofline图8.NVIDIA Nsight Compute生成Roofline9.效果图A.nn.LinearB.Triton实现 本文演示了如何用Roofline模型去分析pytorch和Triton算子…

探秘 NTHU-DDD:疲劳与哈欠背后的驾驶安全密码(目标检测)

亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 一、引言…

【最新鸿蒙应用开发】——用户信息封装

用户管理工具封装 1. 为什么要封装 在进行如下登录功能时, 通常需要将一些用户信息以及token进行持久化保存,以方便下次进行数据请求时携带这些用户信息来进行访问后端数据。下面分享一下鸿蒙当中实用的持久化封装操作。 2. 步骤 封装用户信息管理工具…

Django 配置静态文件

1,DebugTrue 调试模式 Test/Test/settings.py DEBUG True...STATICFILES_DIRS [os.path.join(BASE_DIR, static),] STATIC_URL /static/ 1.1 创建静态文件 Test/static/6/images/Sni1.png 1.2 添加视图函数 Test/app6/views.py from django.shortcuts impor…

【D3.js in Action 3 精译】1.2.2 可缩放矢量图形(二)

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介 1.1 何为 D3.js?1.2 D3 生态系统——入门须知 1.2.1 HTML 与 DOM1.2.2 SVG - 可缩放矢量图形 ✔️ 第一部分【第二部分】✔️第三部分(精译中 ⏳) 1.2.3 Canvas 与 WebGL&#x…

互联网大厂核心知识总结PDF资料

我们要敢于追求卓越,也能承认自己平庸,不要低估3,5,10年沉淀的威力 hi 大家好,我是大师兄,大厂工作特点是需要多方面的知识和技能。这种学习和积累一般人需要一段的时间,不太可能一蹴而就&…

获取 url 地址栏 ? 后面的查询字符串,并以键值对形式放到对象里面

写在前面 在前端面试当中,关于 url 相关的问题很常见,而对于 url 请求参数的问题也很常见,大部分以笔试题常见,今天就根据这道面试题一起来看一下。 问题 获取 url 地址栏?后面的查询字符串,并以键值对形式放到对象…

【图解大数据技术】Hadoop、HDFS、MapReduce、Yarn

【图解大数据技术】Hadoop、HDFS、MapReduce、Yarn HadoopHDFSHDFS架构写文件流程读文件流程 MapReduceMapReduce简介MapReduce整体流程 Yarn Hadoop Hadoop是Apache开源的分布式大数据存储与计算框架,由HDFS、MapReduce、Yarn三部分组成。广义上的Hadoop其实是指H…

Ubuntu网络管理命令:netstat

安装Ubuntu桌面系统(虚拟机)_虚拟机安装ubuntu桌面版-CSDN博客 顾名思义,netstat命令不是用来配置网络的,而是用来查看各种网络信息的,包括网络连接、路由表以及网络接口的各种统计数据等。 netstat命令的基本语法如…