pytorch的梯度图与autograd.grad和二阶求导

前向与反向


  • 这里我们从 一次计算 开始比如 z=f(x,y) 讨论
  • 若我们把任意对于tensor的计算都看为函数(如将 a*b(数值) 看为 mul(a,b)),那么都可以将其看为2个过程:forward-前向,backward-反向
  • 在pytorch中我们通过继承torch.autograd.Function来实现这2个过程,详细的用法和扩展参考:https://pytorch.org/docs/stable/notes/extending.html
  • 【例子】比如我们要实现一个数值乘法z= ( x ∗ y ) 2 (x*y)^2 (xy)2

前向

  • 在前向过程中,我们主要干的事情为:1. 通过输入计算得到输出。2.保存反向传播求导数所需要的tensor到ctx(在反向传播的时候会对应的传入)
  • 【例子】1.为了反向传播求梯度保存x,y(因为我们知道 d z / d x = 2 ∗ x ∗ y 2 , d z / d y = 2 ∗ y ∗ x 2 dz/dx=2*x*y^2, dz/dy=2*y*x^2 dz/dx=2xy2,dz/dy=2yx2), 2.return ( x ∗ y ) 2 (x*y)^2 (xy)2

反向

  • 在反向传播的时候我们干的事情就是,将传入的导数(梯度)和我们在前向过程中保存的tensor进行加工,最终返回每个输入变量的梯度
  • 【例子】此时反向时应该返回 2 ∗ x ∗ x ∗ y 与 2 ∗ x ∗ y ∗ y 2*x*x*y与2*x*y*y 2xxy2xyy,分别对应 d z / d x , d z / d y dz/dx, dz/dy dz/dx,dz/dy

计算图


  • 那么对于一次计算的讨论完了,现在我们来讨论多次计算,即梯度(导数)是如何一步步的从最终的z=f(a), a=g(b), b=w©… 一层层的 传回x的。
  • 那么在pytorch中,其使用了图的数据结构,在一开始 z = x ∗ x ∗ y ∗ y z=x*x*y*y z=xxyy的例子中,z会指向x与y,方便反向传播求梯度(导数),现在若 w = z ∗ z w=z*z w=zz(关于z的函数),那么w会指向z
  • 那么 d w / d x = d w / d z ∗ d z / d x dw/dx = dw/dz * dz/dx dw/dx=dw/dzdz/dx
  • 在这里插入图片描述

需要梯度?,require_grad

  • 但是很多tensor在计算时是不需要梯度的,而保存上面那种梯度图又很费空间,pytroch默认你创建的tensor是不需要梯度的
  • 如当你使用线性层时,实际上是 w ∗ x + b w*x+b wx+b,但是其实这里传入x是需要梯度的(它又不需要学习),而w与b是模型的参数是nn.Parameters,所以他需要学习,自然需要梯度,
  • 而这里pytorch就使用一个bool标记来说明这个tensor需要梯度嘛,若他需要梯度,那么基于他的计算才会有指针指向它
  • 比如, z = x ∗ y z=x*y z=xy,若x,y都require_grad=False,则根本不会建立计算图,若x的requires_grad=True,则该计算会建立z->x的计算图

梯度函数,grad_fn

  • 当你进行了建立了计算图的计算,比如x.requires_grad=True, z = x ∗ y z=x*y z=xy, 那么z.grad_fn就会有函数指针指向反向传播的计算,这里就是这个 x ∗ y x*y xy
  • 在上图中一个节点虽然向回指向多个变量,但其实对应函数指针,其实是指向一个函数 x ∗ x ∗ y ∗ y x*x*y*y xxyy,2个箭头对应的是2个返回值 ( d z / d x , d z / d y ) (dz/dx,dz/dy) (dz/dx,dz/dy),函数指针可以在运算完了后在tensor.grad_fn看到

梯度,grad

  • 当你在正向计算时,构建完了上述的这样一个计算图,你就可以对最终得到的tensor调用backward函数,那么整个计算图就会从最后一个变量还是反向一步一步的将梯度传给每个需要保存梯度的tensor,这时可以在tensor.grad中看到,此时默认情况tensor.grad_fn会被清空。

torch.autograd.grad


  • 大部分情况下,我们都是得到loss,然后loss.backward(),模型的参数对应的每个tensor就会的到梯度,这个时候opt.step()就会根据学习率优化参数
  • 但有时候我们需要手动求导,可以使用 torch.autograd.grad函数

自变量,input

  • x,即对什么求导,当然该tensor必须requires_grad=True,在因变量的同一梯度图的后继

因变量,output

  • y,即被求导的变量,这里结合x相当于求dy/dx

加权,grad_outputs

  • pytorch中求导的因变量必须是一个shape为[1]的tensor,所以比如当backward时,我们往往取loss.sum() 或者mean(), 那么这里y是个大小不定的tensor,那么这个参数就是和y的shape一样,先令(g代表grad_outputs) L = ∑ g i j ∗ y i j L=∑g_{ij}*y_{ij} L=gijyij, 然后L在对x求导,这里求和往往我们取g=torch.ones_like(y), 相当于y.sum()
  • 一般情况下,不同batch之间的计算是独立的,所以得到的y就算sum后,每个x的得到的梯度其实是batch独立的,但是batch_norm除外,因为batch_norm,不同batch的x会与整个batch的均值做运算, 除非你手写batch_norm,并将数据均值对应的tensor mu detach掉,此时mu对于整个梯度图就是一个常数,否则mu会指向不同batch的x,导致每个x的得到的梯度其实不是batch独立的

输出

  • 输出的shape和x一样,即最终的L对于x每个位置的梯度,这也同样解释了为什么必须要对y求和得L,否则每个x中的每个位置其实对应整个tensor,y

二阶求导,create_graph

  • 那么若想二阶求导,我们举个例子z = f(x,y) , z1 = ∂f/∂x, z2 = ∂z1 / ∂y,在代码里,其实x对应X[:,0], y对应X[:,1](也可以其他对应),其实还是一个tensor
  • 那么首先把torch.autograd.grad整个过程又看为一次新的计算,在反向求导求z1时,程序会按照上述过程一步一步反向传播,而反向传播得到梯度时,其实这里又可以形成新的梯度图,z1处于整个新的梯度图顶端
  • 那么对应代码里,使用函数参数create_graph=True来告诉autograd,我这次得到的tensor是需要产生梯度图的(因为可能进一步求导)
  • 那么在代码里,我们相当于
 z1 = torch.autograd.grad(output=y,input=X,...)[0][:, 0]z2 = torch.autograd.grad(output=z1,input=X,...)[0][:, 1]若你的输入X是将x与y合成一体的,如x=X[:,0], y=X[:,1],那么你求导也只能将整体X作为输入,再从答案中获得对应的列
若你直接在求导时input=X[:,i] 这里实际上你创建了一个新tensor X[:,i] -> X, 而Z->X, 并未指向X[:,i], 故不行

在这里插入图片描述

  • 补充: 画2阶导数的梯度图

将一阶导数的梯度图的每一条边作为新的一个节点,例如s-[q]-> e, q作为一个新节点指向e,然后与其他同样从边引申出来的节点进行相乘链接(导数链式法则)一下是 Q = ( x ∗ x ∗ y ) 2 Q=(x*x*y)^2 Q=(xxy)2的例子
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提高API接口的性能和设计安全可靠的API

如何提高API接口的性能 下图显示了提高 API 性能的 5 种常见技巧。 分页 这是在结果集较大时常用的优化方法。结果会以流式方式传回客户端,以提高服务响应速度。 异步日志 同步日志每次调用都要处理磁盘,会降低系统速度。异步日志会先将日志发送到无…

《手把手教你》系列技巧篇(三十)-java+ selenium自动化测试- Actions的相关操作下篇(详解教程)

1.简介 本文主要介绍两个在测试过程中可能会用到的功能:Actions类中的拖拽操作和Actions类中的划取字段操作。例如:需要在一堆log字符中随机划取一段文字,然后右键选择摘取功能。 2.拖拽操作 鼠标拖拽操作,顾名思义就是&#xff…

文本向量评测MTEB和C-MTEB

文章目录 简介MTEBC-MTEB参考资料 简介 MTEB(Massive Text Embedding Benchmark)是目前评测文本向量很重要的一个参考,其榜单也是各大文本向量模型用来展示与其他向量模型强弱的一个竞技台。 C-MTEB则是专门针对中文文本向量的评测基准。 MTEB MTEB的目的是为了…

vuepress-theme-vdoing博客搭建教程

搭建流程 前言 这是笔者搭建个人博客所经历的流程,特附上笔记 笔者个人博客地址:沉梦听雨的编程指南 一、主题介绍 本博客使用的主题为:vuepress-theme-vdoing,相关介绍和使用方法可以参考该主题的官方文档 官方文档快速上手…

什么是PROFIBUS DP网络布线的1米原则?分支线又是什么?

在上期的文章中,我们介绍了 PROFIBUS DP 网络在连接时涉及到的硬件:DP 线缆、PROFIBUS 插头、终端电阻、中继器和有源终端等。 在今天的文章中,就让我们了解一下在 PROFIBUS DP 网络布线时,需要注意的原则有哪些。 一米原则 当 …

图分割 Graph Partition 学习笔记2

文章目录 前言一、Metis原理二、Metis优点三、Metis软件包安装流程参考链接 前言 今天来学一下Metis算法,经过搜索发现这个算法还是蛮多人在讲解的,我也在这里浅浅记录一下~ 一、Metis原理 METIS是一种层次化的分割算法(multi-level partitio…

梯度剪裁: torch.nn.utils.clip_grad_norm_()

梯度剪裁: torch.nn.utils.clip_grad_norm_() 一、原理 pytorch中梯度剪裁方法为 torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type2)1。三个参数: parameters:希望实施梯度裁剪的可迭代网络参数 max_norm:该组网络参数梯…

勾八头歌之数据科学导论—数据采集实战

一、数据科学导论——数据采集基本概念 第1关:巧妇难为无米之炊 第2关:数据采集概念与内涵 二、数据科学导论——数据采集实战 第1关:单网页爬取 import urllib.request import csv import re# ********** Begin ********** # dataurllib.r…

java项目安全性与权限管理实践与探讨

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 引言 一. 身份验证和授权 二. 输入验证和过滤 2.1. 添加OW…

电机应用-步进电机进阶驱动

步进电机梯形加减速 什么是梯形加减速 假设该装置使用步进电机实现物体X的移动,系统要求从A点出发,到B点停止,移动的时间越短越好且系统稳定。 根据步进电机的特性,最大程度加大电机转速(提高脉冲频率)&a…

10.Java---clone+内部类

一次浅拷贝的过程 打印结果: 一次深拷贝的过程 打印结果: 抽象类和接口的区别 外部类&内部类 1.内部类由static修饰时,不可以是变量 这样就是可以的,他就代表一个常量 2.怎么实例化内部类 当然不可以直接实例化啦! 是这么实例化的,看起来比我们平时麻烦了很多呢! …

SpringCloud OpenFeign 服务接口调用

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第四篇,即介绍 Feign 和 OpenFeign 服务接口调用。 二、概述 2.1 Feign 是什么 Feign 是一…

C++程序设计-练手题集合【期末复习|考研复习】

前言 总结整理不易,希望大家点赞收藏。 给大家整理了一下C程序设计中的练手题,以供大家期末复习和考研复习的时候使用。 C程序设计系列文章传送门: 第一章 面向对象基础 第四/五章 函数和类和对象 第六/七/八章 运算符重载/包含与继承/虚函数…

dolphin schedulerAPI调用(二)——创建任务

(作者:陈玓玏) API文档地址:http://192.168.3.100:21583/dolphinscheduler/swagger-ui/index.html?languagezh_CN&langcn#/task%20definition%20related%20operation/createTaskDefinitionUsingPOST_1 实际使用中&#x…

场的概念---数量场(标量场)和矢量场介绍理解

目录 一、场的概念 二、场的分类 三、数量场(标量场)的等值面 四、矢量场中的矢量线 矢量线方程推导: 一、场的概念 场在数学上是指一个向量到另一个向量或数的映射。场指物体在空间中的分布情况。场是用空间位置函数来表征的。在物理学…

雾锁王国专用服务器设置方法,基于阿里云1分钟开服!

阿里云雾锁王国服务器搭建教程是基于计算巢服务,3分钟即可成功创建Enshrouded游戏服务器,阿里云8核32G雾锁王国专用游戏服务器90元1个月、271元3个月,阿里云服务器网aliyunfuwuqi.com亲自整理雾锁王国服务器详细搭建教程: 一、前…

全自动内衣洗衣机什么牌子好?热心推荐四款全能硬核的内衣洗衣机

内衣洗衣机这一产品是专为有特殊需求的人士所研发的,其的容量往往都比较小,并且体积也很小巧,安装都非常便捷,作为“家中第二台”补充式洗衣机被很多人推崇,可以作为贴身衣物的专用洗衣机,那么这种内衣洗衣…

Kutools For Excel | 新增 300+ 高级功能

Kutools For Excel 是一个便捷的 Excel 插件,具有 300 多种高级功能,可将各种复杂的任务简化为在 Excel 中的几次单击。 功能强大且用户友好的加载项将为 Excel 用户节省大量工作时间,并大大提高工作效率。支持 Excel 2021 / 2019 / 2016 / …

【Linux】调试工具 - gdb

目录 一、gdb概述: 二、list(查看源文件代码): 三、run(运行程序): ​四、断点相关操作: 1、查看断点: 2、在指定行设置断点: 3、在函数入口处设置断…

[计算机效率] 便笺的使用

2.4 便笺 便笺程序是一种方便用户记录、查看和编辑便签的简单应用程序。在Windows系统中,便笺通常作为系统自带的实用工具之一,可以帮助用户快速创建、编辑和组织便签,以便随时记录重要的信息、任务或提醒事项。 便笺程序通常具有以下特点&a…