鱼书学习笔记:数值微分和梯度

舍入误差 

指因省略小数的精细部分的数值(比如,小数点后第8位以后的数值)而造成最终的计算结果上的误差

>>>np.float32(1e-50)

0.0

中心差分

函数f在(x+h)和(h-h)之间的差分。因为这种计算方法以x为中心、计算它左右两边的差分,所以也称为中心差分(而(x+h)和x之间的差分称为前向差分)

基于舍入误差和中心差分来实现的数值微分(数值梯度):

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

如上所示,利用微小的差分求导数的过程称为数值微分。而基于数学是的推导求导数的过程,则用“解析性(analytic)”一词,称为“解析性求解”或者“解析性求导”。解析性求导得到的导数是不含误差的“真的导数”

偏导数

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

梯度

由全部变量的偏导数汇总而成的向量称为梯度。梯度可以像下面这样来实现。

def numerical_gradient(f, x):
    h = 1e-4
    grad = np.zeros_like(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

梯度法

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

这里需要注意的是,梯度表示的是各点处的函数值减小最多的方向。因此,无法保证梯度所指的方向就是函数的最小值或者真正应该前进的方向。实际上,在复杂的函数中,梯度指示的方向基本上都不是函数最小处

根据目的是寻找最小值还是最大值,梯度法的叫法有所不同。严格地讲,寻找最小值地梯度法称为梯度下降法(gradient desent method),寻找最大值的梯度法称为梯度上升法(gradient ascent method)。但是通过反转损失函数的符号,求最小值的问题和求最大值的问题会变成相同的问题,因此“下降”还是“上升”的差异本质上并不重要。一般来说,神经网络(深度学习)中,梯度法主要是指梯度下降法

梯度法数学式:x0 = x0 - ηdf/dx0; x1 = x1 - ηdf/dx1

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

梯度下降法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指定重复的次数。

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

原文地址:https://www.cnblogs.com/J14nWe1/p/14568952.html