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

事实上,逼近法就是积分(integral calculus)的起源。
 2000多年后,微积分的另一支,微分(differential calculus)被发明出来。
 在微分学最重要的应用是优化问题,即考虑如何把事情做到最好。
在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。
 通常情况下,变得更好意味着最小化一个损失函数(loss function),即一个衡量“模型有多糟糕”这个问题的分数。
最终,我们真正关心的是生成一个模型,它能够在从未见过的数据上表现良好。
 但“训练”模型只能将模型与我们实际能看到的数据相拟合。因此,我们可以将拟合模型的任务分解为两个关键问题:
- 优化(optimization):用模型拟合观测数据的过程;
- 泛化(generalization):数学原理和实践者的智慧,能够指导我们生成出有效性超出用于训练的数据集本身的模型。
本节提供了一个非常简短的入门教程,帮助读者快速掌握深度学习中常用的微分知识。
导数和微分
我们首先讨论导数的计算,这是几乎所有深度学习优化算法的关键步骤。
 在深度学习中,我们通常选择对于模型参数可微的损失函数。
 简而言之,对于每个参数,
 如果我们把这个参数增加或减少一个无穷小的量,可以知道损失会以多快的速度增加或减少,
假设我们有一个函数 
     
      
       
       
         f 
        
       
         : 
        
       
         R 
        
       
         → 
        
       
         R 
        
       
      
        f: \mathbb{R} \rightarrow \mathbb{R} 
       
      
    f:R→R,其输入和输出都是标量。
 (如果 
      
       
        
        
          f 
         
        
       
         f 
        
       
     f的导数存在,这个极限被定义为)
( f ′ ( x ) = lim  h → 0 f ( x + h ) − f ( x ) h . f'(x) = \lim_{h \rightarrow 0} \frac{f(x+h) - f(x)}{h}. f′(x)=h→0limhf(x+h)−f(x).)
如果 
     
      
       
        
        
          f 
         
        
          ′ 
         
        
       
         ( 
        
       
         a 
        
       
         ) 
        
       
      
        f'(a) 
       
      
    f′(a)存在,则称 
     
      
       
       
         f 
        
       
      
        f 
       
      
    f在 
     
      
       
       
         a 
        
       
      
        a 
       
      
    a处是可微(differentiable)的。
 如果 
     
      
       
       
         f 
        
       
      
        f 
       
      
    f在一个区间内的每个数上都是可微的,则此函数在此区间中是可微的。
 我们可以将的导数 
     
      
       
        
        
          f 
         
        
          ′ 
         
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
      
        f'(x) 
       
      
    f′(x)解释为 
     
      
       
       
         f 
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
      
        f(x) 
       
      
    f(x)相对于 
     
      
       
       
         x 
        
       
      
        x 
       
      
    x的瞬时(instantaneous)变化率。所谓的瞬时变化率是基于 
     
      
       
       
         x 
        
       
      
        x 
       
      
    x中的变化 
     
      
       
       
         h 
        
       
      
        h 
       
      
    h,且 
     
      
       
       
         h 
        
       
      
        h 
       
      
    h接近 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0。
为了更好地解释导数,让我们做一个实验。
 (定义 
      
       
        
        
          u 
         
        
          = 
         
        
          f 
         
        
          ( 
         
        
          x 
         
        
          ) 
         
        
          = 
         
        
          3 
         
         
         
           x 
          
         
           2 
          
         
        
          − 
         
        
          4 
         
        
          x 
         
        
       
         u=f(x)=3x^2-4x 
        
       
     u=f(x)=3x2−4x)如下:
%matplotlib inline  #这是 IPython 的一个魔法命令,其作用是让 Matplotlib 绘制的图形能够直接在 Jupyter Notebook 等环境中显示。
import numpy as np #导入numpy库并简称为np,numpy是 Python 中用于科学计算的基础库,可处理数组、矩阵等数据结构。
from matplotlib_inline import backend_inline #导入matplotlib_inline库中的backend_inline模块,该模块可用于配置 Matplotlib 的内联显示设置。
from d2l import torch as d2l #(动手学深度学习)库中导入torch相关模块并简称为d2l,d2l库为深度学习相关的学习和实践提供了诸多实用工具和函数。
def f(x):
    return 3 * x ** 2 - 4 * x
[通过令 
      
       
        
        
          x 
         
        
          = 
         
        
          1 
         
        
       
         x=1 
        
       
     x=1并让 
      
       
        
        
          h 
         
        
       
         h 
        
       
     h接近 
      
       
        
        
          0 
         
        
       
         0 
        
       
     0,] 中( 
      
       
        
         
          
          
            f 
           
          
            ( 
           
          
            x 
           
          
            + 
           
          
            h 
           
          
            ) 
           
          
            − 
           
          
            f 
           
          
            ( 
           
          
            x 
           
          
            ) 
           
          
         
           h 
          
         
        
       
         \frac{f(x+h)-f(x)}{h} 
        
       
     hf(x+h)−f(x)的数值结果接近 
      
       
        
        
          2 
         
        
       
         2 
        
       
     2)。
 虽然这个实验不是一个数学证明,但稍后会看到,当 
     
      
       
       
         x 
        
       
         = 
        
       
         1 
        
       
      
        x=1 
       
      
    x=1时,导数 
     
      
       
        
        
          u 
         
        
          ′ 
         
        
       
      
        u' 
       
      
    u′是 
     
      
       
       
         2 
        
       
      
        2 
       
      
    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={numerical_lim(f, 1, h):.5f}')
    h *= 0.1

让我们熟悉一下导数的几个等价符号。
 给定 
     
      
       
       
         y 
        
       
         = 
        
       
         f 
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
      
        y=f(x) 
       
      
    y=f(x),其中 
     
      
       
       
         x 
        
       
      
        x 
       
      
    x和 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y分别是函数 
     
      
       
       
         f 
        
       
      
        f 
       
      
    f的自变量和因变量。以下表达式是等价的:
f ′ ( x ) = y ′ = d y d x = d f d x = d d x f ( x ) = D f ( x ) = D x f ( x ) , f'(x) = y' = \frac{dy}{dx} = \frac{df}{dx} = \frac{d}{dx} f(x) = Df(x) = D_x f(x), f′(x)=y′=dxdy=dxdf=dxdf(x)=Df(x)=Dxf(x),
其中符号 
     
      
       
        
        
          d 
         
         
         
           d 
          
         
           x 
          
         
        
       
      
        \frac{d}{dx} 
       
      
    dxd和 
     
      
       
       
         D 
        
       
      
        D 
       
      
    D是微分运算符,表示微分操作。
 我们可以使用以下规则来对常见函数求微分:
- D C = 0 DC = 0 DC=0( C C C是一个常数)
- D x n = n x n − 1 Dx^n = nx^{n-1} Dxn=nxn−1(幂律(power rule), n n n是任意实数)
- D e x = e x De^x = e^x Dex=ex
- D ln  ( x ) = 1 / x D\ln(x) = 1/x Dln(x)=1/x
为了微分一个由一些常见函数组成的函数,下面的一些法则方便使用。
 假设函数 
     
      
       
       
         f 
        
       
      
        f 
       
      
    f和 
     
      
       
       
         g 
        
       
      
        g 
       
      
    g都是可微的, 
     
      
       
       
         C 
        
       
      
        C 
       
      
    C是一个常数,则:
常数相乘法则
  
      
       
        
         
         
           d 
          
          
          
            d 
           
          
            x 
           
          
         
        
          [ 
         
        
          C 
         
        
          f 
         
        
          ( 
         
        
          x 
         
        
          ) 
         
        
          ] 
         
        
          = 
         
        
          C 
         
         
         
           d 
          
          
          
            d 
           
          
            x 
           
          
         
        
          f 
         
        
          ( 
         
        
          x 
         
        
          ) 
         
        
          , 
         
        
       
         \frac{d}{dx} [Cf(x)] = C \frac{d}{dx} f(x), 
        
       
     dxd[Cf(x)]=Cdxdf(x),
加法法则
d d x [ f ( x ) + g ( x ) ] = d d x f ( x ) + d d x g ( x ) , \frac{d}{dx} [f(x) + g(x)] = \frac{d}{dx} f(x) + \frac{d}{dx} g(x), dxd[f(x)+g(x)]=dxdf(x)+dxdg(x),
乘法法则
d d x [ f ( x ) g ( x ) ] = f ( x ) d d x [ g ( x ) ] + g ( x ) d d x [ f ( x ) ] , \frac{d}{dx} [f(x)g(x)] = f(x) \frac{d}{dx} [g(x)] + g(x) \frac{d}{dx} [f(x)], dxd[f(x)g(x)]=f(x)dxd[g(x)]+g(x)dxd[f(x)],
除法法则
d d x [ f ( x ) g ( x ) ] = g ( x ) d d x [ f ( x ) ] − f ( x ) d d x [ g ( x ) ] [ g ( x ) ] 2 . \frac{d}{dx} \left[\frac{f(x)}{g(x)}\right] = \frac{g(x) \frac{d}{dx} [f(x)] - f(x) \frac{d}{dx} [g(x)]}{[g(x)]^2}. dxd[g(x)f(x)]=[g(x)]2g(x)dxd[f(x)]−f(x)dxd[g(x)].
现在我们可以应用上述几个法则来计算 
     
      
       
        
        
          u 
         
        
          ′ 
         
        
       
         = 
        
        
        
          f 
         
        
          ′ 
         
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
         = 
        
       
         3 
        
        
        
          d 
         
         
         
           d 
          
         
           x 
          
         
        
        
        
          x 
         
        
          2 
         
        
       
         − 
        
       
         4 
        
        
        
          d 
         
         
         
           d 
          
         
           x 
          
         
        
       
         x 
        
       
         = 
        
       
         6 
        
       
         x 
        
       
         − 
        
       
         4 
        
       
      
        u'=f'(x)=3\frac{d}{dx}x^2-4\frac{d}{dx}x=6x-4 
       
      
    u′=f′(x)=3dxdx2−4dxdx=6x−4。
 令 
     
      
       
       
         x 
        
       
         = 
        
       
         1 
        
       
      
        x=1 
       
      
    x=1,我们有 
     
      
       
        
        
          u 
         
        
          ′ 
         
        
       
         = 
        
       
         2 
        
       
      
        u'=2 
       
      
    u′=2:在这个实验中,数值结果接近 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2,
 这一点得到了在本节前面的实验的支持。
 当 
     
      
       
       
         x 
        
       
         = 
        
       
         1 
        
       
      
        x=1 
       
      
    x=1时,此导数也是曲线 
     
      
       
       
         u 
        
       
         = 
        
       
         f 
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
      
        u=f(x) 
       
      
    u=f(x)切线的斜率。
[为了对导数的这种解释进行可视化,我们将使用matplotlib],
 这是一个Python中流行的绘图库。
 要配置matplotlib生成图形的属性,我们需要(定义几个函数)。
 在下面,use_svg_display函数指定matplotlib软件包输出svg图表以获得更清晰的图像。
注意,注释#@save是一个特殊的标记,会将对应的函数、类或语句保存在d2l包中。
 因此,以后无须重新定义就可以直接调用它们(例如,d2l.use_svg_display())。
def use_svg_display():  #@save
    """使用svg格式在Jupyter中显示绘图"""
    backend_inline.set_matplotlib_formats('svg')
代码解释
这行代码
backend_inline.set_matplotlib_formats('svg')的主要作用是设定Matplotlib在Jupyter Notebook等环境里绘图的输出格式为SVG(可缩放矢量图形)。下面是详细解释:模块和函数说明
backend_inline:它属于matplotlib_inline库中的一个模块。matplotlib_inline库专门用于优化Matplotlib在Jupyter Notebook等交互式环境下的显示效果。
set_matplotlib_formats:这是backend_inline模块里的一个函数,其功能是设置Matplotlib绘图的输出格式。参数说明
'svg':此为传递给set_matplotlib_formats函数的参数,表明要将绘图的输出格式设定为SVG。SVG是一种基于XML的矢量图形格式,具备诸多优点,例如可以无损缩放,在不同分辨率的设备上都能清晰显示,而且文件体积通常较小。工作原理
在Jupyter Notebook这类交互式环境中,Matplotlib默认的绘图输出格式可能是光栅图像(像PNG)。通过调用
backend_inline.set_matplotlib_formats('svg'),能够把输出格式更改为SVG。这样一来,后续在该环境中使用Matplotlib绘制的图形就会以SVG格式显示,从而提升图形的显示质量和可交互性。
我们定义set_figsize函数来设置图表大小。
 注意,这里可以直接使用d2l.plt,因为导入语句from matplotlib import pyplot as plt已标记为保存到d2l包中。
#@save
def set_figsize(figsize=(3.5, 2.5)):#接收一个参数 figsize,该参数默认值为 (3.5, 2.5),表示图表的宽度为 3.5,高度为 2.5(单位通常为英寸)  
    """设置matplotlib的图表大小"""
    
    use_svg_display()#调用上述定义函数,将绘图的输出格式为SVG
    
    d2l.plt.rcParams['figure.figsize'] = figsize
    #用于存储 Matplotlib 的全局配置参数。通过将 figsize 赋值给 rcParams['figure.figsize'],可以设置后续绘制的图表的大小。
下面的set_axes函数用于设置由matplotlib生成图表的轴的属性。
#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    """设置matplotlib的轴"""
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)
    axes.set_yscale(yscale)
    axes.set_xlim(xlim)
    axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    axes.grid()
函数定义与参数
这段Python代码定义了一个名为
set_axes的函数,它的主要功能是对Matplotlib绘图时的坐标轴进行设置。 函数定义与参数
axes:代表Matplotlib的坐标轴对象,通过它能对坐标轴进行各类设置操作。
xlabel:表示x轴的标签,也就是x轴的名称。
ylabel:表示y轴的标签,即y轴的名称。
xlim:是一个包含两个元素的元组或者列表,用来指定x轴的取值范围,例如(0, 10)。
ylim:同样是一个包含两个元素的元组或者列表,用于指定y轴的取值范围。
xscale:指定x轴的缩放类型,常见的取值有'linear'(线性)、'log'(对数)等。
yscale:指定y轴的缩放类型,和xscale类似。
legend:图例信息,一般是一个字符串列表,用来标识不同曲线的含义。若为None,则不显示图例。if legend: axes.legend(legend)若
legend参数不为None,就会在图表中显示图例。axes.grid()这行代码会在图表中添加网格线,方便观察数据点的位置。
通过这三个用于图形配置的函数,定义一个plot函数来简洁地绘制多条曲线,以便我们我们可视化曲线。
#@save
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
         ylim=None, xscale='linear', yscale='linear',
         fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
'''
X:表示 x 轴的数据,可以是一维数组或列表。
Y:表示 y 轴的数据,默认为 None。如果为 None,则 X 会被当作 y 轴数据。
xlabel:x 轴的标签,默认为 None。
ylabel:y 轴的标签,默认为 None。
legend:图例列表,默认为 None。
xlim:x 轴的取值范围,默认为 None。
ylim:y 轴的取值范围,默认为 None。
xscale:x 轴的缩放类型,默认为 'linear'(线性)。
yscale:y 轴的缩放类型,默认为 'linear'(线性)。
fmts:线条格式列表,默认为 ('-', 'm--', 'g-.', 'r:')。
figsize:图形的大小,默认为 (3.5, 2.5)。
axes:指定绘图的坐标轴对象,默认为 None
'''
    """绘制数据点"""
    if legend is None:
        legend = []
    set_figsize(figsize)#设置图形的大小
    
    #如果 axes 为 None,则使用 d2l.plt.gca() 获取当前的坐标轴对象。
	axes = axes if axes else d2l.plt.gca()
    
    # 如果X有一个轴,输出True
    def has_one_axis(X):#该函数用于判断 X 是否为一维数据
        return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
                and not hasattr(X[0], "__len__"))
    if has_one_axis(X):
        X = [X]
    if Y is None:
        X, Y = [[]] * len(X), X
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X * len(Y)
    '''
    1. has_one_axis 是一个辅助函数,用于判断 X 是否为一维数据。如果 X 是一维的(如一维的 NumPy 数组或者普通列表),就把它转换为只包含该一维数据的列表。这样做的目的是为了让后续处理逻辑更统一,将一维数据也视为列表形式。
    2. 当 Y 为 None 时,表明没有传入 Y 轴的数据。此时,代码会把 X 当作 Y 轴的数据,同时将 X 替换为空列表组成的列表,列表长度与原 X 的长度一致。这样做是为了保证后续绘图时能正确处理这种特殊情况。
    3. 若 Y 不为 None 且是一维数据,就把它转换为只包含该一维数据的列表,和处理 X 一维数据的目的相同,是为了统一数据格式。
    4. 检查 X 和 Y 的长度是否一致。如果不一致,就把 X 重复拼接,使其长度与 Y 相同。这一步是为了保证在后续绘图时,X 和 Y 中的数据能一一对应。
    '''
         
    axes.cla()#清除当前坐标轴上的所有内容。
    
    for x, y, fmt in zip(X, Y, fmts):#见下方详细解释
        if len(x):
            axes.plot(x, y, fmt)
        else:
            axes.plot(y, fmt)
            
    set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
代码功能概述
这段代码的主要功能是使用
matplotlib库在指定的坐标轴axes上绘制曲线。它会遍历X、Y和fmts三个可迭代对象,根据X数据是否为空来决定绘图时传入的参数,进而完成多条曲线的绘制。代码详细解释
1.
zip(X, Y, fmts)
zip函数会将X、Y和fmts这三个可迭代对象中的元素一一对应地组合成元组,然后返回一个迭代器。每次迭代时,从这三个对象中各取出一个元素组成一个三元组(x, y, fmt)。
X:通常是一个包含多个列表或数组的可迭代对象,代表每条曲线的 x 轴数据。
Y:同样是一个包含多个列表或数组的可迭代对象,代表每条曲线的 y 轴数据。
fmts:是一个包含多种线条格式字符串的可迭代对象,用于指定每条曲线的绘制样式(如颜色、线型等)。2.
for x, y, fmt in zip(X, Y, fmts)这是一个
for循环,会遍历zip(X, Y, fmts)返回的迭代器。每次循环时,将当前三元组中的元素分别赋值给变量x、y和fmt。3.
if len(x):这是一个条件判断语句,用于检查
x的长度是否大于 0。len(x)会返回x所包含元素的数量,如果x不为空列表或数组,len(x)的值就大于 0,条件判断结果为True;反之,如果x是空列表或数组,len(x)的值为 0,条件判断结果为False。4.
axes.plot(x, y, fmt)当
x不为空时,调用axes对象的plot方法绘制曲线。该方法接收三个参数:
x:表示曲线在 x 轴上的数据点。
y:表示曲线在 y 轴上的数据点。
fmt:是一个字符串,用于指定曲线的绘制样式,例如'-'表示实线,'m--'表示洋红色的虚线等。5.
axes.plot(y, fmt)当
x为空时,调用axes对象的plot方法绘制曲线。此时只传入y和fmt两个参数,matplotlib会默认使用从 0 开始的整数序列作为 x 轴的数据点。
现在我们可以[绘制函数 u = f ( x ) u=f(x) u=f(x)及其在 x = 1 x=1 x=1处的切线 y = 2 x − 3 y=2x-3 y=2x−3],其中系数 2 2 2是切线的斜率。
x = np.arange(0, 3, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])

偏导数
到目前为止,我们只讨论了仅含一个变量的函数的微分。
 在深度学习中,函数通常依赖于许多变量。
 因此,我们需要将微分的思想推广到多元函数(multivariate function)上。
设 
     
      
       
       
         y 
        
       
         = 
        
       
         f 
        
       
         ( 
        
        
        
          x 
         
        
          1 
         
        
       
         , 
        
        
        
          x 
         
        
          2 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
        
          n 
         
        
       
         ) 
        
       
      
        y = f(x_1, x_2, \ldots, x_n) 
       
      
    y=f(x1,x2,…,xn)是一个具有 
     
      
       
       
         n 
        
       
      
        n 
       
      
    n个变量的函数。
  
     
      
       
       
         y 
        
       
      
        y 
       
      
    y关于第 
     
      
       
       
         i 
        
       
      
        i 
       
      
    i个参数 
     
      
       
        
        
          x 
         
        
          i 
         
        
       
      
        x_i 
       
      
    xi的偏导数(partial derivative)为:
∂ y ∂ x i = lim  h → 0 f ( x 1 , … , x i − 1 , x i + h , x i + 1 , … , x n ) − f ( x 1 , … , x i , … , x n ) h . \frac{\partial y}{\partial x_i} = \lim_{h \rightarrow 0} \frac{f(x_1, \ldots, x_{i-1}, x_i+h, x_{i+1}, \ldots, x_n) - f(x_1, \ldots, x_i, \ldots, x_n)}{h}. ∂xi∂y=h→0limhf(x1,…,xi−1,xi+h,xi+1,…,xn)−f(x1,…,xi,…,xn).
为了计算 
     
      
       
        
         
         
           ∂ 
          
         
           y 
          
         
         
         
           ∂ 
          
          
          
            x 
           
          
            i 
           
          
         
        
       
      
        \frac{\partial y}{\partial x_i} 
       
      
    ∂xi∂y,
 我们可以简单地将 
     
      
       
        
        
          x 
         
        
          1 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
         
         
           i 
          
         
           − 
          
         
           1 
          
         
        
       
         , 
        
        
        
          x 
         
         
         
           i 
          
         
           + 
          
         
           1 
          
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
        
          n 
         
        
       
      
        x_1, \ldots, x_{i-1}, x_{i+1}, \ldots, x_n 
       
      
    x1,…,xi−1,xi+1,…,xn看作常数,
 并计算 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y关于 
     
      
       
        
        
          x 
         
        
          i 
         
        
       
      
        x_i 
       
      
    xi的导数。
 对于偏导数的表示,以下是等价的:
∂ y ∂ x i = ∂ f ∂ x i = f x i = f i = D i f = D x i f . \frac{\partial y}{\partial x_i} = \frac{\partial f}{\partial x_i} = f_{x_i} = f_i = D_i f = D_{x_i} f. ∂xi∂y=∂xi∂f=fxi=fi=Dif=Dxif.
梯度
我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的梯度(gradient)向量。
 具体而言,设函数 
     
      
       
       
         f 
        
       
         : 
        
        
        
          R 
         
        
          n 
         
        
       
         → 
        
       
         R 
        
       
      
        f:\mathbb{R}^n\rightarrow\mathbb{R} 
       
      
    f:Rn→R的输入是
 一个 
     
      
       
       
         n 
        
       
      
        n 
       
      
    n维向量 
     
      
       
       
         x 
        
       
         = 
        
       
         [ 
        
        
        
          x 
         
        
          1 
         
        
       
         , 
        
        
        
          x 
         
        
          2 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
        
          n 
         
        
        
        
          ] 
         
        
          ⊤ 
         
        
       
      
        \mathbf{x}=[x_1,x_2,\ldots,x_n]^\top 
       
      
    x=[x1,x2,…,xn]⊤,并且输出是一个标量。
 函数 
     
      
       
       
         f 
        
       
         ( 
        
       
         x 
        
       
         ) 
        
       
      
        f(\mathbf{x}) 
       
      
    f(x)相对于 
     
      
       
       
         x 
        
       
      
        \mathbf{x} 
       
      
    x的梯度是一个包含 
     
      
       
       
         n 
        
       
      
        n 
       
      
    n个偏导数的向量:
∇ x f ( x ) = [ ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , … , ∂ f ( x ) ∂ x n ] ⊤ , \nabla_{\mathbf{x}} f(\mathbf{x}) = \bigg[\frac{\partial f(\mathbf{x})}{\partial x_1}, \frac{\partial f(\mathbf{x})}{\partial x_2}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_n}\bigg]^\top, ∇xf(x)=[∂x1∂f(x),∂x2∂f(x),…,∂xn∂f(x)]⊤,
其中 ∇ x f ( x ) \nabla_{\mathbf{x}} f(\mathbf{x}) ∇xf(x)通常在没有歧义时被 ∇ f ( x ) \nabla f(\mathbf{x}) ∇f(x)取代。
假设 x \mathbf{x} x为 n n n维向量,在微分多元函数时经常使用以下规则:
- 对于所有 A ∈ R m × n \mathbf{A} \in \mathbb{R}^{m \times n} A∈Rm×n,都有 ∇ x A x = A ⊤ \nabla_{\mathbf{x}} \mathbf{A} \mathbf{x} = \mathbf{A}^\top ∇xAx=A⊤
- 对于所有 A ∈ R n × m \mathbf{A} \in \mathbb{R}^{n \times m} A∈Rn×m,都有 ∇ x x ⊤ A = A \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} = \mathbf{A} ∇xx⊤A=A
- 对于所有 A ∈ R n × n \mathbf{A} \in \mathbb{R}^{n \times n} A∈Rn×n,都有 ∇ x x ⊤ A x = ( A + A ⊤ ) x \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} \mathbf{x} = (\mathbf{A} + \mathbf{A}^\top)\mathbf{x} ∇xx⊤Ax=(A+A⊤)x
- ∇ x ∥ x ∥ 2 = ∇ x x ⊤ x = 2 x \nabla_{\mathbf{x}} \|\mathbf{x} \|^2 = \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{x} = 2\mathbf{x} ∇x∥x∥2=∇xx⊤x=2x
同样,对于任何矩阵 
     
      
       
       
         X 
        
       
      
        \mathbf{X} 
       
      
    X,都有 
     
      
       
        
        
          ∇ 
         
        
          X 
         
        
       
         ∥ 
        
       
         X 
        
        
        
          ∥ 
         
        
          F 
         
        
          2 
         
        
       
         = 
        
       
         2 
        
       
         X 
        
       
      
        \nabla_{\mathbf{X}} \|\mathbf{X} \|_F^2 = 2\mathbf{X} 
       
      
    ∇X∥X∥F2=2X。
 正如我们之后将看到的,梯度对于设计深度学习中的优化算法有很大用处。
链式法则
然而,上面方法可能很难找到梯度。
 这是因为在深度学习中,多元函数通常是复合(composite)的,
 所以难以应用上述任何规则来微分这些函数。
 幸运的是,链式法则可以被用来微分复合函数。
让我们先考虑单变量函数。假设函数 y = f ( u ) y=f(u) y=f(u)和 u = g ( x ) u=g(x) u=g(x)都是可微的,根据链式法则:
d y d x = d y d u d u d x . \frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}. dxdy=dudydxdu.
现在考虑一个更一般的场景,即函数具有任意数量的变量的情况。
 假设可微分函数 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y有变量 
     
      
       
        
        
          u 
         
        
          1 
         
        
       
         , 
        
        
        
          u 
         
        
          2 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          u 
         
        
          m 
         
        
       
      
        u_1, u_2, \ldots, u_m 
       
      
    u1,u2,…,um,其中每个可微分函数 
     
      
       
        
        
          u 
         
        
          i 
         
        
       
      
        u_i 
       
      
    ui都有变量 
     
      
       
        
        
          x 
         
        
          1 
         
        
       
         , 
        
        
        
          x 
         
        
          2 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
        
          n 
         
        
       
      
        x_1, x_2, \ldots, x_n 
       
      
    x1,x2,…,xn。
 注意, 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y是 
     
      
       
        
        
          x 
         
        
          1 
         
        
       
         , 
        
        
        
          x 
         
        
          2 
         
        
       
         , 
        
       
         … 
        
       
         , 
        
        
        
          x 
         
        
          n 
         
        
       
      
        x_1, x_2, \ldots, x_n 
       
      
    x1,x2,…,xn的函数。
 对于任意 
     
      
       
       
         i 
        
       
         = 
        
       
         1 
        
       
         , 
        
       
         2 
        
       
         , 
        
       
         … 
        
       
         , 
        
       
         n 
        
       
      
        i = 1, 2, \ldots, n 
       
      
    i=1,2,…,n,链式法则给出:
∂ y ∂ x i = ∂ y ∂ u 1 ∂ u 1 ∂ x i + ∂ y ∂ u 2 ∂ u 2 ∂ x i + ⋯ + ∂ y ∂ u m ∂ u m ∂ x i \frac{\partial y}{\partial x_i} = \frac{\partial y}{\partial u_1} \frac{\partial u_1}{\partial x_i} + \frac{\partial y}{\partial u_2} \frac{\partial u_2}{\partial x_i} + \cdots + \frac{\partial y}{\partial u_m} \frac{\partial u_m}{\partial x_i} ∂xi∂y=∂u1∂y∂xi∂u1+∂u2∂y∂xi∂u2+⋯+∂um∂y∂xi∂um
小结
- 微分和积分是微积分的两个分支,前者可以应用于深度学习中的优化问题。
- 导数可以被解释为函数相对于其变量的瞬时变化率,它也是函数曲线的切线的斜率。
- 梯度是一个向量,其分量是多变量函数相对于其所有变量的偏导数。
- 链式法则可以用来微分复合函数。


![[Linux] 进程管理与调度机制](https://i-blog.csdnimg.cn/direct/4c307892f97e44888c1e66f857449f9e.jpeg)
















