深度学习基础6(微分,偏导,梯度,链式法则)

本文介绍了微积分在深度学习中的基础概念,包括导数、偏导数、梯度和链式法则。导数是优化算法的关键,梯度指向值变化最大的方向。链式法则帮助我们处理复合函数的微分问题,是深度学习模型训练的核心。

微积分

如下图所示,内接多边形的等长边越多,就越接近圆。 这个过程也被称为逼近法(method of exhaustion)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMshcFTY-1648199976900)(C:\Users\Lenovo\Documents\Tencent Files\850604703\FileRecv\MobileFile\Image%HTGE}R0]R(J[NDZ3KM(A.png)]

事实上,逼近法就是**积分(integral calculus)**的起源

微积分的另一支,**微分(differential calculus)**被发明出来。

在微分学最重要的应用是优化问题,即考虑如何把事情做到最好,这种问题在深度学习中是无处不在的。

在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。

通常情况下,变得更好意味着最小化一个损失函数(loss function)

真正关心的是生成一个模型,它能够在从未见过的数据上表现良好。

但“训练”模型只能将模型与我们实际能看到的数据相拟合, 因此,我们可以将拟合模型的任务分解为两个关键问题

  • 优化(optimization):用模型拟合观测数据的过程;
  • 泛化(generalization):生成出有效性超出用于训练的数据集本身的模型。

导数和微分

这是几乎所有深度学习优化算法的关键步骤。

在深度学习中,通常选择对于模型参数可微的损失函数

简而言之,对于每个参数, 如果把这个参数增加或减少一个无穷小的量,我们可以知道损失会以多快的速度增加或减少,

假设我们有一个函数𝑓:Rn→R,其输入和输出都是标量。 (如果𝑓的导数存在,这个极限被定义为)

UN8TED5I`3X8)FAMJOIO

如果𝑓′(𝑎)存在,则称𝑓在𝑎处是可微(differentiable)的。

如果𝑓在一个区间内的每个数上都是可微的,则此函数在此区间中是可微的。

可以将图中的导数𝑓′(𝑥)解释为𝑓(𝑥)相对于𝑥的瞬时(instantaneous)变化率。 所谓的瞬时变化率是基于𝑥中的变化ℎ,且ℎ接近0。

为了更好地解释导数,举个例子

定义𝑢=𝑓(𝑥)=3𝑥2−4𝑥如下:

%matplotlib inline
import numpy as np
import d2l
from IPython import display
from d2l import torch as d2l


def f(x):
    return 3 * x ** 2 - 4 * x

通过令𝑥=1并让ℎ接近0

**![U@%SLGY2Q9C~7K}W`ZL478.png) 的数值结果接近2**)。 稍后会看到,当𝑥=1时,导数𝑢′是2。

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=
在机器学习中,自动微分(Automatic Differentiation, AD)是用于高效、准确地计算函数数的技术,尤其在深度学习中扮演着核心角色。自动微分的实现依赖于链式法则(Chain Rule),通过将复杂函数分解为基本操作,并记录这些操作的顺序,最终利用链式法则计算出数。 ### 自动微分的代码实现 在代码实现中,自动微分通常通过两种方式实现:**基本表达式法**和**操作符重载**。 基本表达式法通过将函数分解为一系列基本操作(如加法、乘法、指数等),并在程序中使用专门的库来替代这些操作。这些库会自动记录操作的顺序,并在反向传播计算梯度。例如,在自定义函数使用这些库的方法,可以确保每一步操作都被正确记录并用于后续的数计算[^3]。 操作符重载则利用现代编程语言的多态特性(如 Python、C++),对基本运算操作符进行封装,使其在执行记录操作信息。例如,加法、乘法等操作符被重载后,会在执行构建一个计算图,记录输入与输出之间的关系。在反向传播,系统会根据这个计算图,利用链式法则计算出最终的梯度[^4]。 ### 链式法则与自动微分的关系 链式法则是自动微分的核心数学基础。它允许我们将复合函数数拆解为多个部分的乘积,从而简化数的计算。假设函数 $ f(x) = g(h(x)) $,则其数可表示为: $$ f'(x) = g'(h(x)) \cdot h'(x) $$ 在自动微分中,链式法则被广泛应用于反向传播过程中。系统会从输出变量出发,沿着计算图反向遍历,依次计算每个节点的数,并通过链式法则将它们组合起来,最终得到输入变量的梯度。这种方式可以高效地处理高维输入和复杂模型的梯度计算[^1]。 ### 示例代码:基于链式法则的自动微分实现 以下是一个简单的 Python 示例,展示了如何手动实现一个基于链式法则的自动微分机制: ```python class Variable: def __init__(self, value, grad=0): self.value = value self.grad = grad # 用于存储梯度 def __add__(self, other): result = Variable(self.value + other.value) # 加法的数为两个输入的梯度之和 def grad_fn(): self.grad += result.grad other.grad += result.grad return result, grad_fn def __mul__(self, other): result = Variable(self.value * other.value) # 乘法的数为链式法则的应用 def grad_fn(): self.grad += other.value * result.grad other.grad += self.value * result.grad return result, grad_fn def backward(result): result.grad = 1 # 反向传播 for grad_fn in reversed(grad_fns): grad_fn() # 示例计算 x = Variable(2) y = Variable(3) z, grad_z = x * y w, grad_w = z + y # 记录梯度函数 grad_fns = [grad_w, grad_z] # 执行反向传播 backward(w) print(f"dz/dx = {x.grad}") # 输出: 3 print(f"dz/dy = {y.grad}") # 输出: 2 + 1 = 3 ``` 在上述代码中,`__add__` 和 `__mul__` 方法分别实现了加法和乘法操作,并通过定义 `grad_fn` 函数来记录每个操作的梯度计算方式。`backward` 函数则负责从输出变量出发,按照链式法则依次计算每个输入变量的梯度。 ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NDNPOMDFLR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值