top of page
アンカー 1

一、前文回顾

上一节我们讲到神经网络的自主学习过程,其实就是通过不断的调整权重值,使得损失函数达到最小值的过程。今天的内容就是具体怎么实现这个过程。


二、上山容易下山难

举个例子,假如你在爬山的途中突然遇到恶劣天气想要赶紧下山,这时候你就要找到一条能最快下山的路,但是你没带地图,而且你的视野有限,只能看到周围十米的地方。那该怎么做才能最快的到达山脚呢?

我比较蠢所以会选择下面这个方法:

先环顾四周,找一个坡度最陡峭的下山路,因为是最陡峭所以很大概率就是最快能到达山脚的路。那么怎么知道哪条路最陡峭呢?当时是看哪条路的落差最大,也就是你朝每条路同样迈出一步,哪个更深哪个就落差最大,也就是最陡。然后我们就按照这个方法一直走,理论上就可以最快下山。

那么放在神经网络里面来解释的话,山就好比是损失函数,是一个连续的三维曲面,经度和纬度分别代表权重W1和W2,海拔高度代表损失函数值E,而这个人初始站的位置就是初始权重的坐标值(w1,w2,e),而他要找到的最陡峭的那条路的方向就是损失函数E在点(w1,w2,e)处的梯度


三、什么是梯度

梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。这个梯度怎么算出来呢?为了容易理解从二维平面先举个例子。

我们在二维平面画一条曲线

假设这条曲线就是损失函数,横轴是权重参数,纵轴为损失函数值。假如我们随机初期化权重参数为w1,此时的损失函数为e1,那么要走到这个函数的最小值(w2,e2),那么就得看看当前点w1的左边和右边的哪个更陡峭,怎么求呢?我往左跨一小步h,然后算出当前的损失函数值E(w1-h),再减去初始位置的损失函数值E(w1)便可以得出我这一小步导致损失函数值变化了多少,也就是E(w1-h)-E(w1)。同样的道理,我往右跨同样的一小步h,求得往右一小步损失函数的变化量E(w1+h)-E(w1)。如果往左跨步损失函数变化量大于朝右跨步,那么说明朝左走比较陡峭,可以最快到达最小值。而为了更精确,我们需要求出刚才那一步h无限小接近于零的时候,损失函数的变化量。也就是损失函数E在w1处的微分值。看看数学表达式

(为什么一定要h要无限接近于零,因为你的一步h如果刚好跨过了最小值,那就没得玩了)

在这里为了减少误差,对微分公式进行了一丢丢改动,变为下面的样子:


其实也很好理解,就是把跨一步变为了左右各跨一步然后除以双倍的步幅。

我们再回到前面说的下山的例子里面的三维平面,那么就要再加上损失函数E在点w2处的微分

我们把上边两个微分合并起来用向量来表示

这就是损失函数E在某一点(w1,w2)出的梯度。

实际中,损失函数是更高维度的东西,也就是说损失函数E在某一点(w1,w2,w3,,,,,wn)处的梯度为:

看起来很复杂,那我们用python来实现一下就简单多了:

def numerical_gradient(f, x):
    # 我们每一步跨出去的步幅,是个很小很小的值
    h = 1e-4  # 0.0001
    # 创建一个全部为零并且和参数x相同构造的变量
    grad = np.zeros_like(x)

    for idx in range(x.size):
        tmp_val = x[idx]
        # 右跨一小步f(x+h)
        x[idx] = float(tmp_val) + h
        fxh1 = f(x)  # f(x+h)
        # 左跨一小步f(x-h)
        x[idx] = tmp_val - h
        fxh2 = f(x)  # f(x-h)
        # 求函数的变化量
        grad[idx] = (fxh1 - fxh2) / (2 * h)
        x[idx] = tmp_val
    return grad

三、梯度长什么样

为了更直观的理解梯度是个什么东西,我们用下面这个函数来说明一下。


E代表损失函数,w0和w1分别代表两个权重参数。这个函数用三维图画出来就是这样子


然后再看看它在各个点的梯度图


你会发现它在每一点的梯度都指向这个曲面的最小值点(0,0,0),而这个性质恰恰就是我们想要的,因为我们只要按着梯度方向走很大概率可以很快的走到最低点,也就是找到损失函数的最小值。

※为什么不是肯定可以走到最低点?因为如果你在一个连绵不绝的山脉中,你走到的很可能只是它的一个山谷底部,并不是山脚,专业的叫极小值和最小值。以后还会提到这个东西。


四、总结

自主学习能力(自动调整权重参数)是神经网络的最厉害的地方,学习的过程如下:

①随机设置权重参数

②数据输入神经网络进行推理

③通过损失函数计算推理结果和正确结果的偏差

如果损失函数没有达到最小值,也就是推理值和真实值差的比较远,为了缩小这个差距,就要根据损失函数在这个点的梯度值相应的更新权重参数。

⑤更新完参数参数以后返回步骤②继续推理→比较

下一节就来看看怎么样根据梯度值更新权重参数,也就是怎么样朝着梯度方向一步步的下山。

bottom of page