【Pytorch神经网络基础理论篇】 06 自动求导+导数与微分

同学你好!本文章于2021年末编写,已与实际存在较大的偏差!

故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现,

Pytorch深度学习·理论篇(2023版)目录地址为:

CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!https://v9999.blog.csdn.net/article/details/127587345欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~

 

0.导数和微分

0.1逼近法

在2500年前,古希腊人把一个多边形分成三角形,并把它们的面积相加,才找到计算多边形面积的方法。 为了求出曲线形状(比如圆)的面积,古希腊人在这样的形状上刻内接多边形,内接多边形的等长边越多,就越接近圆。这个过程也被称为逼近法。

在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。通常情况下,变得更好意味着最小化一个损失函数(loss function),即一个衡量“我们的模型有多糟糕”这个问题的分数。这个问题比看上去要微妙得多。

最终,我们真正关心的是生成一个能够在我们从未见过的数据上表现良好的模型。但我们只能将模型与我们实际能看到的数据相拟合。

因此,我们可以将拟合模型的任务分解为两个关键问题:

(1)优化(optimization):用模型拟合观测数据的过程;

(2)泛化(generalization):数学原理和实践者的智慧,能够指导我们生成出有效性超出用于训练的数据集本身的模型

0.2 导数和微分

在深度学习中,我们通常选择对于模型参数可微的损失函数。这意味着,对于每个参数, 如果我们把这个参数增加或减少一个无穷小的量,我们可以知道损失会以多快的速度增加或减少。

 0.2.1 简单模拟求导过程

%matplotlib inline
import numpy as np
from IPython import display
from d2l import torch as d2ldef f(x):return 3 * x ** 2 - 4 * x

def numerical_lim(f, x, h):return (f(x + h) - f(x)) / hh = 0.1
for i in range(5):print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')h *= 0.1
h=0.10000, numerical limit=2.30000
h=0.01000, numerical limit=2.03000
h=0.00100, numerical limit=2.00300
h=0.00010, numerical limit=2.00030
h=0.00001, numerical limit=2.00003

1.自动求导

 

 

 

 

 

 

 

 

 

 

 

 

 2.自动求导实现

2.1ppt截图

 

 

 

 

  

 

2.2 代码实现

import torch
print('1.自动梯度计算')
x = torch.arange(4.0, requires_grad=True)  # 1.将梯度附加到想要对其计算偏导数的变量
print('x:', x)
print('x.grad:', x.grad)
1.自动梯度计算
x: tensor([0., 1., 2., 3.], requires_grad=True)
x.grad: None

y = 2 * torch.dot(x, x)  # 2.记录目标值的计算 对应位置相乘再相加
print('y:', y) 
y: tensor(28., grad_fn=<MulBackward0>)
y.backward()  # 3.y=2*x*x  执行它的反向传播函数
print('x.grad:', x.grad)  # 4.访问得到的梯度
print('x.grad == 4*x:', x.grad == 4 * x)
x.grad: tensor([ 0.,  4.,  8., 12.])
x.grad == 4*x: tensor([True, True, True, True])
## 计算另一个函数
x.grad.zero_() #梯度清零
print('x:', x)
y = x.sum()
print('y:', y)
y.backward()
print('x.grad:', x.grad)
x: tensor([0., 1., 2., 3.], requires_grad=True)
y: tensor(6., grad_fn=<SumBackward0>)
x.grad: tensor([1., 1., 1., 1.])
# 非标量变量的反向传播
x.grad.zero_()
print('x:', x)
y = x * x
y.sum().backward()
print('x.grad:', x.grad)
x: tensor([0., 1., 2., 3.], requires_grad=True)
x.grad: tensor([0., 2., 4., 6.])
def f(a):b = a * 2print(b.norm())print("开始循环:")while b.norm() < 1000:  # 求L2范数:元素平方和的平方根b = b * 2print(b)print("开始判断")if b.sum() > 0:c = belse:c = 100 * breturn c
print('2.Python控制流的梯度计算')
a = torch.tensor(2.0)  # 初始化变量
print(a)
a.requires_grad_(True)  # 1.将梯度赋给想要对其求偏导数的变量
print('a:', a)
d = f(a)  # 2.记录目标函数
print('d:', d)
d.backward()  # 3.执行目标函数的反向传播函数
print('a.grad:', a.grad)  # 4.获取梯度
2.Python控制流的梯度计算
tensor(2.)
a: tensor(2., requires_grad=True)
tensor(4., grad_fn=<CopyBackwards>)
开始循环:
tensor(8., grad_fn=<MulBackward0>)
tensor(16., grad_fn=<MulBackward0>)
tensor(32., grad_fn=<MulBackward0>)
tensor(64., grad_fn=<MulBackward0>)
tensor(128., grad_fn=<MulBackward0>)
tensor(256., grad_fn=<MulBackward0>)
tensor(512., grad_fn=<MulBackward0>)
tensor(1024., grad_fn=<MulBackward0>)
开始判断
d: tensor(1024., grad_fn=<MulBackward0>)
a.grad: tensor(512.)

QA

1.显示构造:先将整个计算写出来,再去写入参数值。

2.在深度网络求梯度的时候,需要正向算一遍(将y的函数值算出来),反向算一遍。

3.pytorch默认累计梯度的原因:累计梯度的情况主要是在批量的情况下,Pytorch对于内存的管理不够好,批量计算的内存大小较大,因此将其分开计算,故需要默认累计梯度。

4.为什么深度学习中一般都去标量求导,而不是对矩阵和向量,如果我的loss是包含向量或矩阵的情况下,在求导之前是否需要将其变成标量的形式?
答:loss通常是一个标量

5.多个loss分别反向的情况下,需要累计梯度

6.为什么获取grad前需要backward?
因为backward占用内存较大

7.pytorch上可以实现矢量求导吗?
可以,高阶求导,但是通常需要优化算法。

在PyTorch中data.norm()是含义_Escape the bug的博客-CSDN博客https://blog.csdn.net/jnbfknasf113/article/details/110141537https://blog.csdn.net/jnbfknasf113/article/details/110141537
 

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

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

相关文章

EXPORT_SYMBOL

linux2.6的“/prob/kallsyms”文件对应着内核符号表&#xff0c;记录了符号以及符号所在的内存地址。 模块可以使用如下宏导出符号到内核符号表&#xff1a; [c-sharp] view plaincopy EXPORT_SYMBOL(符号名); EXPORT_SYMBOL_GPL(符号名) 导出的符号可以被其他模块使用&…

数据结构链表之栈,Python3简单实现——5

数据结构链表之栈 栈的概述 定义&#xff1a;栈是一种基于先进后出(FILO)的数据结构&#xff0c;是一种只能在一段进行插入和删除操作的特殊线性表。引入名词&#xff1a;将数据存入栈的动作称为压栈&#xff0c;将数据取出栈的动作称为弹栈栈的特点&#xff1a;先进入栈的元…

【转】【Linux】linux awk命令详解

简介 awk是一个强大的文本分析工具&#xff0c;相对于grep的查找&#xff0c;sed的编辑&#xff0c;awk在其对数据分析并生成报告时&#xff0c;显得尤为强大。简单来说awk就是把文件逐行的读入&#xff0c;以空格为默认分隔符将每行切片&#xff0c;切开的部分再进行各种分析处…

8X25Q充电部分软件梳理(CP侧)

分享链接&#xff1a;http://note.youdao.com/share/?id4f6665eee6bad5ea27eee47f74bcfa4b&typenote 8X25Q充电部分软件梳理&#xff08;CP侧&#xff09; 作者&#xff1a;韦启发 目录 1、过放电池的充电阶段介绍... 2 2、Autonomous充电介绍... 5 3、USB充电器检测... 6…

【Pytorch神经网络基础理论篇】 08 Softmax 回归 + 损失函数 + 图片分类数据集

同学你好&#xff01;本文章于2021年末编写&#xff0c;已与实际存在较大的偏差&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)…

CI Weekly #11 | 微服务场景下的自动化测试与持续部署

又一周过去了&#xff0c;最近我们的工程师正在搞一个“大事情” ——「flow.ci 配置文件」&#xff0c;稍微剧透一下&#xff0c;这个功能预计会在春节前上线。详情请大家关注 flow.ci Changelog 或其他官方通知:) 本期 CI Weekly 收录了的CI/CD实践、微服务自动化测试与持续部…

数据结构链表之栈——解决括号匹配问题和逆波兰表达式求值问题——6

括号匹配问题和逆波兰表达式求值问题 基于上一节已经使用python代码对栈进行了简单的实现&#xff0c;这一节我们在其基础上解决两个常见的问题 案例 括号匹配问题(点我直接到代码实现)逆波兰表达式求值问题(点我直接到代码实现) 括号匹配问题 在给定的字符串中&#xff0…

ubuntu server 12.04中文显示不完整

发现有台服务器ubuntu server 12.04在远程过去时文件名的中文现实没有问题&#xff0c;但ls的时候时间居然乱码。 搜索了一下&#xff0c;应该是locale的问题&#xff0c;可以这样处理&#xff1a; 1. 编辑/var/lib/locales/supported.d/local文件&#xff0c;内容改成如下&am…

Java_基础阶段笔记总结汇总

一、Java简介 1、Java语言平台性介绍 2、JDK_JRE_JVM的组成和作用 JVM: Java虚拟机&#xff0c;是专门用来运行Java程序的,但是不能单独安装 JRE: Java运行环境&#xff0c;包含JVM(Java虚拟机,是专门用来运行Java程序的)和核心类库 JDK: Java开发工具包&#xff0c;包含JRE和…

数据结构链表之队列,Python3实现——7

数据结构链表之队列 队列概述 定义&#xff1a;队列是一种基于先进先出(FIFO)的数据结构&#xff0c;队列只能在一段进行插入和删除操作的结构&#xff0c;第一个进入队列的元素在读取时会第一个被读取 队列可以使用顺序表(Python中列表)实现&#xff0c;也可以用链表实现&am…

IDEA上Debug调试全流程

一、什么是Debug模式 是供程序员使用的程序调试工具&#xff0c;它可以用于查看程序的执行流程&#xff0c;也可以用于追踪程序执行过程来调试程序。使用IDEA的断点调试功能&#xff0c;查看程序的运行过程 Debug调试窗口介绍。 二、Debug模式操作流程【应用】 能够使用断点调…

数据结构链表之符号表,Python3实现——8

数据结构链表之符号表 符号表的介绍 之前章节介绍的顺序表和链表都是一个节点储存一个元素的表&#xff0c;但在日常生活中我们还有很多一次需要储存成对或多个值的情况&#xff0c;例如&#xff1a; 符号表最主要的目的将一对元素&#xff0c;用一个键和一个值将其联系起来&…

OpenCV_01 简介+无版权安装+模块分析

OpenCV是应用广泛的开源图像处理库&#xff0c;我们以其为基础&#xff0c;介绍相关的图像处理方法&#xff1a;包括基本的图像处理方法&#xff1a;几何变换&#xff0c;形态学变换&#xff0c;图像平滑&#xff0c;直方图操作&#xff0c;模板匹配&#xff0c;霍夫变换等&…

KMP 算法 学习 整理

我自己整理的KMP算法的PDF文件&#xff1a;http://pan.baidu.com/s/1o8yKIi2提取密码&#xff1a;8291 别的就不多说啥了&#xff0c;感谢来自海子 博客园的 资料-- 转载于:https://www.cnblogs.com/suishiguang/p/6285979.html

OpenCV_02 图像的基本操作:图像IO+绘制图形+像素点+属性+图像通道+色彩空间的改变

1 图像的IO操作 这里我们会给大家介绍如何读取图像&#xff0c;如何显示图像和如何保存图像。 1.1 读取图像 API cv.imread()参数&#xff1a; 要读取的图像 读取方式的标志 cv.IMREAD*COLOR&#xff1a;以彩色模式加载图像&#xff0c;任何图像的透明度都将被忽略。这是默…

数据结构之树:树的介绍——9

数据结构之树&#xff0c;介绍篇 树的基本定义 介绍&#xff1a;树&#xff08;tree&#xff09;是计算机中非常重要的数据结构&#xff0c;它的外形看起来像一颗倒挂着的的树&#xff0c;使用树这种结构可以描述生活中很多的事物&#xff0c;如族谱&#xff0c;单位的组织架…

页面的宽度

页面的宽度等于内容 paddingmargin100%转载于:https://www.cnblogs.com/Zhaoyanguang/p/6292783.html

数据结构之二叉树:二叉查找树基本功能,Python代码实现——10

数据结构之二叉查找树的代码实现 定义 二叉查找树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;&#xff0c;是一种内存中特殊的树类型的存储结构&#xff0c;它允许对存储在其结点的数据进行增删改查&#xff0c;或者用作动态的数据集合&#xff0c;或是通过k…

OpenCV_03 图像的算数操作:图像的加法+图像的混合

1.图像的加法 你可以使用OpenCV的cv.add()函数把两幅图像相加&#xff0c;或者可以简单地通过numpy操作添加两个图像&#xff0c;如res img1 img2。两个图像应该具有相同的大小和类型&#xff0c;或者第二个图像可以是标量值。 注意&#xff1a;OpenCV加法和Numpy加法之间存…

【bzoj2806】 Ctsc2012—Cheat

http://www.lydsy.com/JudgeOnline/problem.php?id2806 (题目链接) 题意 给出M个字符串组成“标准库”。定义L表示将一个字符串分成若干段&#xff0c;每一段的长度不小于L&#xff0c;其中是在标准库中任一字符串的子串的字符“段”的长度之和不小于原字符串长度之和的90%。N…