首页 > 其他分享 >【pytorch学习】之微积分

【pytorch学习】之微积分

时间:2024-04-23 17:24:40浏览次数:29  
标签:set partial 函数 微积分 axes matplotlib 学习 pytorch frac

4 微积分

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

事实上,逼近法就是积分(integral calculus)的起源。2000多年后,微积分的另一支,微分(differentialcalculus)被发明出来。在微分学最重要的应用是优化问题,即考虑如何把事情做到最好。这种问题在深度学习中是无处不在的。在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。通常情况下,变得更好意味着最小化一个损失函数(loss function),即一个衡量“模型有多糟糕”这个问题的分数。最终,我们真正关心的是生成一个模型,它能够在从未见过的数据上表现良好。但“训练”模型只能将模型与我们实际能看到的数据相拟合。因此,我们可以将拟合模型的任务分解为两个关键问题:

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

4.1 导数和微分

我们首先讨论导数的计算,这是几乎所有深度学习优化算法的关键步骤。在深度学习中,我们通常选择对于模型参数可微的损失函数。简而言之,对于每个参数,如果我们把这个参数增加或减少一个无穷小的量,可以知道损失会以多快的速度增加或减少,假设我们有一个函数\(f : \mathbb{R} \rightarrow \mathbb{R}\) ,其输入和输出都是标量。如果f的导数存在,这个极限被定义为

\[f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h} \]

如果f在一个区间内的每个数上都是可微的,则此函数在此区间中是可微。如果f′(a)存在,则称f在a处是可微(differentiable)的。
我们可以将导数f′(x)解释为f(x)相对于x的瞬时(instantaneous)变化率。所谓的瞬时变化率是基于x中的变化h,且h接近0。为了更好地解释导数,让我们做一个实验。

%matplotlib inline
import numpy as np
from matplotlib_inline import backend_inline
def f(x):
    return 3 * x ** 2 - 4 * x

当x = 1时,导数u′是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
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

为了对导数的这种解释进行可视化,我们将使用matplotlib,这是一个Python中流行的绘图库。要配
置matplotlib生成图形的属性,我们需要定义几个函数。在下面,use_svg_display函数指定matplotlib软件包输出svg图表以获得更清晰的图像。

def use_svg_display(): #@save

    backend_inline.set_matplotlib_formats('svg')

我们定义set_figsize函数来设置图表大小。因为导入语句 from matplotlib mport pyplot as plt已标记为保存中。

def set_figsize(figsize=(3.5, 2.5)): #@save
    """设置matplotlib的图表大小"""
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = 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()

通过这三个用于图形配置的函数,定义一个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):
    """绘制数据点"""
    if legend is None:
        legend = []
    set_figsize(figsize)
    axes = axes if axes else d2l.plt.gca()
    # 如果X有一个轴,输出True
    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()
    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)

现在我们可以绘制函数u = f(x)及其在x = 1处的切线y = 2x − 3,其中系数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)'])

image

4.2 偏导数

到目前为止,我们只讨论了仅含一个变量的函数的微分。在深度学习中,函数通常依赖于许多变量。因此,我们需要将微分的思想推广到多元函数(multivariate function)上。
设\(y = f(x_1, x_2, . . . , x_n)\)是一个具有n个变量的函数。\(y\)关于第\(i\)个参数\(x_i\)的偏导数(partial derivative)为:

\[\frac{\partial f}{\partial x_i} = \lim_{{h \to 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} \]

4.3 梯度

我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的梯度(gradient)向量。具体而言,设
函数\(f: \mathbb{R}^n \rightarrow \mathbb{R}\)的输入是一个n维向量\(\mathbf{x} = [x_1, x_2, \ldots, x_n]^T\),并且输出是一个标量。函数f(x)相对于x的梯度是一个包含n个偏导数的向量:

\[\nabla f(\mathbf{x}) = \left[ \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \ldots, \frac{\partial f}{\partial x_n} \right]^T \]

4.4 链式法则

然而,上面方法可能很难找到梯度。这是因为在深度学习中,多元函数通常是复合(composite)的,所以难以应用上述任何规则来微分这些函数。幸运的是,链式法则可以被用来微分复合函数。
让我们先考虑单变量函数。假设函数y = f(u)和u = g(x)都是可微的,根据链式法则:

\[\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx} \]

现在考虑一个更一般的场景,即函数具有任意数量的变量的情况。假设可微分函数y有变量 $( x_1, x_2, \ldots, x_n ) $,其中每个可微分函数 \(u_i\) 都有变量 \(( u_1, u_2, \ldots, u_m )\)。注意,y是 $( x_1, x_2, \ldots, x_n ) $的函数。链式法则给出:

\[\frac{{\partial y}}{{\partial x_i}} = \sum_{j=1}^{m} \frac{{\partial y}}{{\partial u_j}} \cdot \frac{{\partial u_j}}{{\partial x_i}} \]

声明:
本系列学习笔记主要以《动手学深度学习》的pytorch版本为主。
详细见GitHub:https://github.com/d2l-ai/d2l-zh
或者 https://zh.d2l.ai/

标签:set,partial,函数,微积分,axes,matplotlib,学习,pytorch,frac
From: https://www.cnblogs.com/zx-demo/p/18151660

相关文章

  • PyTorch中的优化器
    SDG优化器参数说明:(引用:https://developer.baidu.com/article/detail.html?id=2705103)学习率(LearningRate):学习率决定了模型权重更新的步长。较大的学习率可能导致模型训练不稳定,而较小的学习率可能导致训练速度缓慢。通常,你可以通过尝试不同的学习率来找到最佳值。默认情况下,学......
  • ROS1学习记录(3.0)
    学习视频:10.发布者Publisher的编程实现_哔哩哔哩_bilibili学习创建发布者:依据小海龟功能构建一个发布者先创建一个功能包,其中依赖加上小海龟的数据的结构 创建功能包后打开功能包往功能包内放置相应代码,设置CMakeList.txt设置相应指令;add_executable(velocity_publisher......
  • 深度学习学习率(Learning Rate)lr理解
    现在是2024年4月23日13:54,在看代码了,嗯,不能逃避,逃避可耻,会痛苦,看不懂多看几遍多写一下就好了,不能跑了哈,一点一点来就是了,我还有救。 如何理解深度学习中的学习率(LearningRate):学习率(LearningRate)是神经网络和其他机器学习算法中非常重要的一个超参数。它决定了在优化过程......
  • 【rust】《Rust深度学习[6]-简单实现逻辑回归(Linfa)》
    什么是LinfaLinfa是一组Rust高级库的集合,提供了常用的数据处理方法和机器学习算法。Linfa对标Python上的 scikit-learn,专注于日常机器学习任务常用的预处理任务和经典机器学习算法,目前Linfa已经实现了scikit-learn中的全部算法。项目结构依赖[package]name="rust-ml-e......
  • 【rust】《Rust深度学习[4]-理解线性网络(Candle)》
    全连接/线性在神经网络中,全连接层,也称为线性层,是一种层,其中来自一层的所有输入都连接到下一层的每个激活单元。在大多数流行的机器学习模型中,网络的最后几层是完全连接的。实际上,这种类型的层执行基于在先前层中学习的特征输出类别预测的任务。全连接层的示例,具有四个输入节点......
  • 【rust】《Rust深度学习[5]-理解卷积神经网络(Candle)》
    卷积神经网络ConvolutionalNeuralNetwork,简称为CNN。CNN与一般的顺传播型神经网络不同,它不仅是由全结合层,还由卷积层(ConvolutionLayer)和池层(PoolingLayer)构成的神经网络。在卷积层和池化层中,如下图所示,缩小输入神经元的一部分区域,局部地与下一层进行对应。每一层都有一个称......
  • 【rust】《Rust深度学习[2]-数据分析和挖掘库(Polars)》
    什么是Polars?Polars是一个用于操作结构化数据的高性能DataFrame库,可以用来进行数据清洗和格式转换、数据分析和统计、数据可视化、数据读取和存储、数据合并和拼接等等,相当于Rust版本的Pandas库。Polars读写数据支持如下:  常见数据文件:csv、parquet(不支持xlsx、json文件) ......
  • 【rust】《Rust深度学习[3]-数据可视化(Plotters)》
    什么是Plotters?Plotters是一个用纯Rust开发的图形库,用于中渲染图形、图表和数据可视化。它支持静态图片渲染和实时渲染,并支持多种后端,包括:位图格式(png、bmp、gif等)、矢量图(svg)、窗口和HTML5Canvas。Plotters对不同后端使用统一的高级API,并允许开发者自定义坐标系。在Plotters......
  • 【rust】《Rust深度学习[1]-科学计算库(Ndarray)》
    什么是Ndarray?ndarray是Rust生态中用于处理数组的库。它包含了所有常用的数组操作。简单地说ndarray相当于Rust版本的numpy。ndarray生态系统中crate的文档:ndarray基础库ndarray-rand随机数生成库ndarray-stats统计方法  顺序统计(最小、最大、中值、分位数等);  汇总......
  • 用户下单+微信支付学习记录
    开始之前补充两个知识点,因为之前写mapper.xml文件中sql语句时,没有提示功能就会很麻烦,补充了此功能:IDEAsql自动补全/sql自动提示/sql列名提示_idea提示sql语句-CSDN博客查看类源码:ctrl+shift+/,查看方法详情:ctrl+mouse1用户下单 接口设计     直接看过了,手动导......