zoukankan      html  css  js  c++  java
  • 深度学习入门|第四章 神经网络的学习(二)

    第四章 神经网络的学习

    前言

    此为本人学习《深度学习入门》的学习笔记

    三、数值微分

    梯度法使用梯度的信息决定前进的方向

    1、导数

    frac{df(x)}{dx}=lim_{h	o0} frac{f(x+h)-f(x)}{h}      (4.4)

    式(4.4)表示的是函数的导数。左边的符号 frac{{
m d}f(x)}{{
m d}x} 表示 fx)关于 x 的导数,即fx)相对于 x 的变化程度。式(4.4)表示的导数的含义是,x 的“微小变化”将导致函数 fx)的值在多大程度上发生变化。其中,表示微小变化的 h 无限趋近 0,表示为 lim_{h	o0}

    图 4-5 真的导数(真的切线)和数值微分(近似切线)的值不同

    def numerical_diff(f, x):
        h = 1e-4 # 0.0001
        return (f(x+h) - f(x-h)) / (2*h)

    如上所示,利用微小的差分求导数的过程称为数值微分(numerical differentiation)。而基于数学式的推导求导数的过程,则用“解析性”(analytic)一词,称为“解析性求解”或者“解析性求导”。比如,y = x2的导数,可以通过 frac{{
m d} y}{{
m d} x}=2x 解析性地求解出来。因此,当 x = 2 时,y 的导数为 4。解析性求导得到的导数是不含误差的“真的导数”。

    2、数值微分的例子

    用上述的数值微分对简单函数进行求导,以y=0.01x2+0.1x为例。

    计算该函数在x=5和x=10处的导数

    图 4-7 x=5、x=10处的切线:直线的斜率使用数值微分的值

    3、偏导数

    如函数表达式f(x_{0},x_{1}  )=x_{0}^2+x_{1}^2  ,,有两个变量

    用python实现

    def function_2(x):
    return x[0]**2 + x[1]**2
    # 或者return np.sum(x**2)

    函数图像

    图 4-8 f(x_{0},x_{1}  )=x_{0}^2+x_{1}^2  的图像

    把这里讨论的有多个变量的函数的导数称为偏导数。用数学式表示的话,可以写成 frac{partial f}{partial x_0}frac{partial f}{partial x_1}

    问题 1:求 x0=3,x1=4时,关于 x_0 的偏导数 frac{partial f}{partial x_0}

    >>> def function_tmp1(x0):
    ...     return x0*x0 + 4.0**2.0
    ...
    >>> numerical_diff(function_tmp1, 3.0)
    6.00000000000378

    问题 2:求 x0=3,x1=4 时,关于 x_1 的偏导数 frac{partial f}{partial x_1}

    >>> def function_tmp2(x1):
    ...     return 3.0**2.0 + x1*x1
    ...
    >>> numerical_diff(function_tmp2, 4.0)
    7.999999999999119

    偏导数和单变量的导数一样,都是求某个地方的斜率。不过,偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。

    四、梯度

     Bigl(frac{partial f}{partial x_0},frac{partial f}{partial x_1}Bigr) 这样的由全部变量的偏导数汇总而成的向量称为梯度(gradient)。梯度可以像下面这样来实现。

    def numerical_gradient(f, x):
        h = 1e-4 # 0.0001
        grad = np.zeros_like(x) # 生成和x形状相同的数组
    
        for idx in range(x.size):
            tmp_val = x[idx]
            # f(x+h)的计算
            x[idx] = tmp_val + h
            fxh1 = f(x)
    
            # f(x-h)的计算
            x[idx] = tmp_val - h
            fxh2 = f(x)
    
            grad[idx] = (fxh1 - fxh2) / (2*h)
            x[idx] = tmp_val # 还原值
    
        return grad

    求点 (3, 4)、(0, 2)、(3, 0) 处的梯度

    1.梯度法

    机器学习的主要任务是在学习时寻找最优参数。同样地,神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数。一般而言,损失函数很复杂,参数空间庞大,我们不知道它在何处能取得最小值。而通过巧妙地使用梯度来寻找函数最小值(或者尽可能小的值)的方法就是梯度法

    注意:梯度表示的是各点处的函数值减小最多的方向。

    函数的极小值、最小值以及被称为鞍点(saddle point)的地方,梯度为 0。极小值是局部最小值,也就是限定在某个范围内的最小值。鞍点是从某个方向上看是极大值,从另一个方向上看则是极小值的点。虽然梯度法是要寻找梯度为 0 的地方,但是那个地方不一定就是最小值(也有可能是极小值或者鞍点)。此外,当函数很复杂且呈扁平状时,学习可能会进入一个(几乎)平坦的地区,陷入被称为“学习高原”的无法前进的停滞期。

    通过不断地沿梯度方向前进,逐渐减小函数值的过程就是梯度法(gradient method)。梯度法是解决机器学习中最优化问题的常用方法,特别是在神经网络的学习中经常被使用。

    用数学式来表示梯度法,如式(4.7)所示

    式(4.7)的 η 表示更新量,在神经网络的学习中,称为学习率(learning rate)。学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数。

    用 Python 来实现梯度下降法

    def gradient_descent(f, init_x, lr=0.01, step_num=100):
        x = init_x
    
        for i in range(step_num):
            grad = numerical_gradient(f, x)
            x -= lr * grad
    
        return x

    参数 f 是要进行最优化的函数,init_x 是初始值,lr 是学习率 learning rate,step_num 是梯度法的重复次数。numerical_gradient(f,x) 会求函数的梯度,用该梯度乘以学习率得到的值进行更新操作,由 step_num 指定重复的次数。

     实例;用梯度法求 f(x_0+x_1)=x^2_0+x^2_1 的最小值。

    设初始值为 (-3.0, 4.0),开始使用梯度法寻找最小值。最终的结果是(-6.1e-10, 8.1e-10),非常接近 (0, 0)。实际上,真的最小值就是 (0, 0),所以说通过梯度法我们基本得到了正确结果。

    注意:学习率过大的话,会发散成一个很大的值;反过来,学习率过小的话,基本上没怎么更新就结束了。也就是说,设定合适的学习率是一个很重要的问题。

    像学习率这样的参数称为超参数。这是一种和神经网络的参数(权重和偏置)性质不同的参数。相对于神经网络的权重参数是通过训练数据和学习算法自动获得的,学习率这样的超参数则是人工设定的。一般来说,超参数需要尝试多个值,以便找到一种可以使学习顺利进行的设定。

    2. 神经网络的梯度

    神经网络的学习也要求梯度。这里所说的梯度是指损失函数关于权重参数的梯度。比如,有一个只有一个形状为 2 × 3 的权重 W 的神经网络,损失函数用 L 表示。此时,梯度可以用 frac{partial L}{partial oldsymbol{W}} 表示。用数学式表示的话,如下所示

    frac{partial L}{partial oldsymbol{W}} 的元素由各个元素关于 W 的偏导数构成。比如,第 1 行第 1 列的元素 frac{partial L}{partial w_{11}} 表示当 w_{11}  稍微变化时,损失函数 L 会发生多大变化。这里的重点是,frac{partial L}{partial oldsymbol{W}} 的形状和 W 相同。实际上,式(4.8)中的 W 和 frac{partial L}{partial oldsymbol{W}} 都是 2 × 3 的形状。

    五、学习算法的实现

    前提

    神经网络存在合适的权重和偏置,调整权重和偏置以便拟合训练数据的过程称为“学习”。神经网络的学习分成下面 4 个步骤。

    步骤 1(mini-batch)

    从训练数据中随机选出一部分数据,这部分数据称为 mini-batch。我们的目标是减小 mini-batch 的损失函数的值。

    步骤 2(计算梯度)

    为了减小 mini-batch 的损失函数的值,需要求出各个权重参数的梯度。梯度表示损失函数的值减小最多的方向。

    步骤 3(更新参数)

    将权重参数沿梯度方向进行微小更新。

    步骤 4(重复)

    重复步骤 1、步骤 2、步骤 3。

  • 相关阅读:
    Python_02
    iOS架构模式浅析
    Swift学习目录
    Flutter基础系列之混合开发(二)
    iOS性能优化
    Flutter基础系列之入门(一)
    iOS应用卡顿分析
    Weex是如何让JS调用产生原生UIView的?
    WeexSDK之注册Modules
    WeexSDK之注册Handlers
  • 原文地址:https://www.cnblogs.com/zyqy/p/10809463.html
Copyright © 2011-2022 走看看