李沐动手学Al笔记--06 矩阵计算

本文介绍了深度学习中的关键概念,包括如何通过最小化损失函数进行模型优化,以及导数和微分在模型训练中的作用。重点讲解了如何计算导数、偏导数、梯度以及链式法则的应用,这些都是构建和理解复杂神经网络模型的基础。
摘要由CSDN通过智能技术生成

06 矩阵计算

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

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

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

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

导数和微分

在深度学习中,我们通常选择对于模型参数可微的损失函数。对于每个参数,如果我们把这个参数增加减少一个无穷小的量**,可以知道损失会以多快的速度增加或减少,假设我们有一个函数 f : R → R f: \mathbb{R} \rightarrow \mathbb{R} f:RR,其输入和输出都是标量。

定义 u = f ( x ) = 3 x 2 − 4 x u=f(x)=3x^2-4x u=f(x)=3x24x如下:

%matplotlib inline  # 将 matplotlib 绘制的图像直接在 notebook 中显示,而不是在独立的窗口中显示。
import numpy as np  # numpy是一个由多维数组对象和用于处理数组的例程集合组成的库。
from matplotlib_inline import backend_inline 
from d2l import torch as d2l


def f(x):
    return 3 * x ** 2 - 4 * x
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

给定 y = f ( x ) y=f(x) y=f(x) 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微分运算符,表示微分操作。

假设函数 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)].

在这里插入图片描述

为了对导数的这种解释进行可视化,我们将使用matplotlib,这是一个Python中流行的绘图库。要配置matplotlib生成图形的属性,我们需要(定义几个函数)。

def use_svg_display():  #@save
    """使用svg格式在Jupyter中显示绘图,用于设置 Matplotlib 图形的输出格式为 SVG"""
    backend_inline.set_matplotlib_formats('svg')

#@save是一个特殊标记,将对应的函数、类或语句保存在d2l包中。以后无须重新定义就可以直接调用它们(例如,d2l.use_svg_display())。

def set_figsize(figsize=(3.5, 2.5)):  #@save
    """设置matplotlib的图表大小"""
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = figsize

这里可以直接使用d2l.plt,因为导入语句 from matplotlib import pyplot as plt已标记为保存到d2l包中。

#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    """设置matplotlib的轴"""
    axes.set_xlabel(xlabel) # 横坐标 label 
    axes.set_ylabel(ylabel) # 纵坐标 label 
    axes.set_xscale(xscale) # x轴比例类型
    axes.set_yscale(yscale) # y轴比例类型
    axes.set_xlim(xlim) # x轴范围
    axes.set_ylim(ylim) # y轴范围
    if legend: # legend 设置图例的位置 比如左上、右下等
        axes.legend(legend)
    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):
    """绘制数据点"""
    # 格式字符串fmt由'[marker][line][color]'即线条的标记、线形、颜色三部分组成(顺序不是固定的,可以随意组合)。题中给出为('直线', '紫色虚线', '绿色虚点线', '红色点线')
    if legend is None:
        legend = []

    set_figsize(figsize)
    axes = axes if axes else d2l.plt.gca() # 获取当前的坐标轴对象

    # 如果X有一个轴,输出True
    # hasattr()函数 用来判断函数是否包含某一个对象
    # isinstance()函数 判断一个对象是否是一个已知的类型
    def has_one_axis(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)
    axes.cla() # # 清除axes,即当前 figure 中的活动的axes,但其他axes保持不变。创建太多的 figure 对象会引起警告,故推荐只创建一个 figure 对象,在画下一个图之前,使用 plt.clf() 清理掉 axes,这样可以复用 figure
    for x, y, fmt in zip(X, Y, fmts): # zip()函数用来并行遍历列表。
        if len(x):
            axes.plot(x, y, fmt)
        else:
            axes.plot(y, fmt)
    set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
x = np.arange(0, 3, 0.1)  # 这里三个参数指起点、终点和步长,决定了描点绘图的平滑度
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])

在这里插入图片描述

偏导数

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}. xiy=h0limhf(x1,,xi1,xi+h,xi+1,,xn)f(x1,,xi,,xn).
为了计算 ∂ y ∂ x i \frac{\partial y}{\partial x_i} xiy,我们可以简单地将 x 1 , … , x i − 1 , x i + 1 , … , x n x_1, \ldots, x_{i-1}, x_{i+1}, \ldots, x_n x1,,xi1,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. xiy=xif=fxi=fi=Dif=Dxif.

梯度

连结一个多元函数对其所有变量的偏导数,就是该函数的梯度(gradient)向量

函数 f : R n → R f:\mathbb{R}^n\rightarrow\mathbb{R} f:RnR输入是一个 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)=[x1f(x),x2f(x),,xnf(x)],其中 ∇ x f ( x ) \nabla_{\mathbf{x}} f(\mathbf{x}) xf(x)通常在没有歧义时被 ∇ f ( x ) \nabla f(\mathbf{x}) f(x)取代。

  • 行向量偏导形式(又称行偏导向量形式)

    ∇ x f ( x ) = ∂ f ( x ) ∂ x T = [ ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , … , ∂ f ( x ) ∂ x n ] \nabla_{\mathbf{x}} f(\mathbf{x})=\frac{\partial f(\mathbf{x})}{\partial \mathbf{x}^{T}}= \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] xf(x)=xTf(x)=[x1f(x),x2f(x),,xnf(x)]

假设 x \mathbf{x} x n n n维向量,在微分多元函数时经常使用以下规则:

  • 对于所有 A ∈ R m × n \mathbf{A} \in \mathbb{R}^{m \times n} ARm×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} ARn×m,都有 ∇ x x ⊤ A = A \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} = \mathbf{A} xxA=A
  • 对于所有 A ∈ R n × n \mathbf{A} \in \mathbb{R}^{n \times n} ARn×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} xxAx=(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} xx2=xxx=2x
  • 对于任何矩阵 X \mathbf{X} X,都有 ∇ X ∥ X ∥ F 2 = 2 X \nabla_{\mathbf{X}} \|\mathbf{X} \|_F^2 = 2\mathbf{X} XXF2=2X

在这里插入图片描述

在这里插入图片描述

分子布局,就是分子是列向量形式;分母布局,就是分母是列向量形式。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

链式法则

假设函数 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} xiy=u1yxiu1+u2yxiu2++umyxium

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

galaxy_Fannn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值