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

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

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


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


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


CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录


本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!

https://v9999.blog.csdn.net/article/details/127587345


欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~

103b746101d146cd93357daedb91d512.png


0.导数和微分


0.1逼近法


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


f2e03efa5a0444d49805cd34eb1c43e2.png


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


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


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


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


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


0.2 导数和微分


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

c21056675bd044e0a08d12a433c5e0ab.png


0.2.1 简单模拟求导过程


609a95d2bdde4832b265ce60241bf6c3.png


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

934ac03afcb14c91a1e1a4e43cb0e90c.png


def numerical_lim(f, x, h):
    return (f(x + h) - f(x)) / h
h = 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.自动求导


6d89cc662b5d4339bd361b9faf9e4cfb.png


603a868e789148d09b0946df0d91ade1.png

2fdabfc809564afeaa053e94f13f49ab.png


84a2ee3e470444b0a113c4665e9e9901.png


b80df1e32cda4e82896cb56bb2a81599.png


092a11435c634fd1b6ea0fb1c7bfea43.png


4413048e30564b1289399ca229b33b9b.png

72240eb171c4488598fea8dabdab4882.png


a7cbde0cf67d49e59b95c9fab7258e55.png


fc26ba58499e49f1a2318d98dc40b594.png


ccae51067c3e458b84a0a84b6d0efcc8.png

aaf0312f23cd482ca5bcf273489265ed.png


86dbf9c86b30420e872bfd46f86837fe.png


2.自动求导实现


2.1ppt截图


53d07e8a6e1f47dda0806def34f49c3f.png


8efcd6d2dc774acbbebfec3ef1e45c01.png

a075f20d757e4f36b1429cd2854a99e9.png


 e0c871b366d5441e9eab0b3c6270c469.png


5eac9123a6324f6eb78dd06ae245acfe.png

55d7462957344eba92a0c1300fb02c2a.png


45327c2ccb464183a49ddebf381ca83e.png


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 * 2
    print(b.norm())
    print("开始循环:")
    while b.norm() < 1000:  # 求L2范数:元素平方和的平方根
        b = b * 2
        print(b)
    print("开始判断")
    if b.sum() > 0:
        c = b
    else:
        c = 100 * b
    return 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/110141537

https://blog.csdn.net/jnbfknasf113/article/details/110141537

目录
相关文章
|
3月前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch 中的动态计算图:实现灵活的神经网络架构
【8月更文第27天】PyTorch 是一款流行的深度学习框架,它以其灵活性和易用性而闻名。与 TensorFlow 等其他框架相比,PyTorch 最大的特点之一是支持动态计算图。这意味着开发者可以在运行时定义网络结构,这为构建复杂的模型提供了极大的便利。本文将深入探讨 PyTorch 中动态计算图的工作原理,并通过一些示例代码展示如何利用这一特性来构建灵活的神经网络架构。
273 1
|
5月前
|
机器学习/深度学习 自然语言处理 算法
【从零开始学习深度学习】49.Pytorch_NLP项目实战:文本情感分类---使用循环神经网络RNN
【从零开始学习深度学习】49.Pytorch_NLP项目实战:文本情感分类---使用循环神经网络RNN
|
3月前
|
机器学习/深度学习 人工智能 PyTorch
【深度学习】使用PyTorch构建神经网络:深度学习实战指南
PyTorch是一个开源的Python机器学习库,特别专注于深度学习领域。它由Facebook的AI研究团队开发并维护,因其灵活的架构、动态计算图以及在科研和工业界的广泛支持而受到青睐。PyTorch提供了强大的GPU加速能力,使得在处理大规模数据集和复杂模型时效率极高。
192 59
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
探索PyTorch:自动微分模块
探索PyTorch:自动微分模块
|
2月前
|
机器学习/深度学习
小土堆-pytorch-神经网络-损失函数与反向传播_笔记
在使用损失函数时,关键在于匹配输入和输出形状。例如,在L1Loss中,输入形状中的N代表批量大小。以下是具体示例:对于相同形状的输入和目标张量,L1Loss默认计算差值并求平均;此外,均方误差(MSE)也是常用损失函数。实战中,损失函数用于计算模型输出与真实标签间的差距,并通过反向传播更新模型参数。
|
3月前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch代码实现神经网络
这段代码示例展示了如何在PyTorch中构建一个基础的卷积神经网络(CNN)。该网络包括两个卷积层,分别用于提取图像特征,每个卷积层后跟一个池化层以降低空间维度;之后是三个全连接层,用于分类输出。此结构适用于图像识别任务,并可根据具体应用调整参数与层数。
|
3月前
|
机器学习/深度学习 PyTorch 测试技术
深度学习入门:使用 PyTorch 构建和训练你的第一个神经网络
【8月更文第29天】深度学习是机器学习的一个分支,它利用多层非线性处理单元(即神经网络)来解决复杂的模式识别问题。PyTorch 是一个强大的深度学习框架,它提供了灵活的 API 和动态计算图,非常适合初学者和研究者使用。
51 0
|
5月前
|
机器学习/深度学习 存储 PyTorch
Pytorch-自动微分模块
PyTorch的torch.autograd模块提供了自动微分功能,用于深度学习中的梯度计算。它包括自定义操作的函数、构建计算图、数值梯度检查、错误检测模式和梯度模式设置等组件。张量通过设置`requires_grad=True`来追踪计算,`backward()`用于反向传播计算梯度,`grad`属性存储张量的梯度。示例展示了如何计算标量和向量张量的梯度,并通过`torch.no_grad()`等方法控制梯度计算。在优化过程中,梯度用于更新模型参数。注意,使用numpy转换要求先`detach()`以避免影响计算图。
|
5月前
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】50.Pytorch_NLP项目实战:卷积神经网络textCNN在文本情感分类的运用
【从零开始学习深度学习】50.Pytorch_NLP项目实战:卷积神经网络textCNN在文本情感分类的运用
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】