一、神经网络学习算法的本质
- 当我们搭建好一个神经网络后,无论在什么应用场合,我们的目标都是:将网络的权值和偏置都变成一个最好的值,这个值可以让我们的输入得到理想的输出。
- 可能大家会觉的神经网络架构很非常神秘和复杂,其实任何一个神经网络架构都是一个多层复合的复合函数,我们可以将它们表示为:f(x,w,b)f(x,w,b)f(x,w,b),其中x是输入,www是权值,bbb为偏置。
- 我们的目标就变成了尝试不同的w,bw,bw,b值,使得最后的f(x,w,b)f(x,w,b)f(x,w,b)最接近我们的标签yyy。
- 现在我们需要一个指标来描述接近这个概念,于是产生了损失函数,这里我们将损失函数令为:(f(x,w,b)−y)2=C(w,b)(f(x,w,b)-y)^2=C(w,b)(f(x,w,b)−y)2=C(w,b),现在问题变成:将最小C(w,b)C(w,b)C(w,b)化。
- 将最小C(w,b)C(w,b)C(w,b)化这个问题,我们能够马上想到使用梯度下降算法。即:
- 第一步:求解梯度 [∂C(w,b)∂w1,∂C(w,b)(∂b1),∂C(w,b)∂w2,∂C(w,b)∂b2…,∂C(w,b)(∂wn),∂C(w,b)∂bn]=∂C(w,b)∂[W,b][\frac{∂C(w,b)}{∂w_1 },\frac{∂C(w,b)}{(∂b_1 )},\frac{∂C(w,b)}{∂w_2 },\frac{∂C(w,b)}{∂b_2 }…,\frac{∂C(w,b)}{(∂w_n )},\frac{∂C(w,b)}{∂b_n }]=\frac{∂C(w,b)}{∂[W,b]}[∂w1∂C(w,b),(∂b1)∂C(w,b),∂w2∂C(w,b),∂b2∂C(w,b)…,(∂wn)∂C(w,b),∂bn∂C(w,b)]=∂[W,b]∂C(w,b)
- 第二步:更新参数:[W,b]=[W,b]−η∂C(w,b)∂[W,b][W,b]=[W,b]-η\frac{∂C(w,b)}{∂[W,b]}[W,b]=[W,b]−η∂[W,b]∂C(w,b)其中ηηη为步长。
- 不断迭代上面两步直到函数C(w,b)C(w,b)C(w,b)不能再减少
- 这里解释以下梯度的含义:
- 对于任意一个多元函数f(x1,x2,…,xn)f(x_1,x_2,…,x_n)f(x1,x2,…,xn),它的梯度为: ∇f=[∂f∂x1,∂f∂x2,…,∂f∂xn]∇f=[\frac{∂f}{∂x_1 },\frac{∂f}{∂x_2},…,\frac{∂f}{∂x_n }]∇f=[∂x1∂f,∂x2∂f,…,∂xn∂f]
- 梯度的维度与函数变量维度是一样的,它表示如果自变量沿着梯度方向运动,函数fff的函数值将增长最快。当然反过来,如果沿着梯度的反方向函数值将减少最快,这也是为啥上面用减号。
- 其中∂f∂xi\frac{∂f}{∂x_i }∂xi∂f为函数fff对变量xix_ixi的偏导数,它的含义是其他变量不变的情况下xix_ixi增加1函数值的改变量,即函数相对xix_ixi的的变化率。
- 上面推导的过程的总结:网络权值和偏置更新问题⇒f(x,w,b)\Rightarrow f(x,w,b)⇒f(x,w,b)的结果逼近y⇒C(w,b)=(f(x,w,b)−y)2y\Rightarrow C(w,b)=(f(x,w,b)-y)^2y⇒C(w,b)=(f(x,w,b)−y)2取极小值问题 ⇒C(w,b)\Rightarrow C(w,b)⇒C(w,b)按梯度下降问题⇒\Rightarrow⇒取到极小值,网络达到最优
- 一切都是那么顺利,但是我们忘记了上面推导都是基于一个前提:我们已经提前知道损失函数在当前点的梯度。然而事实并非如此
- 这个问题困扰了NN研究者多年,1969年M.Minsky和S.Papert所著的《感知机》一书出版,它对单层神经网络进行了深入分析,并且从数学上证明了这种网络功能有限,甚至不能解决象"异或"这样的简单逻辑运算问题。同时,他们还发现有许多模式是不能用单层网络训练的,而对于多层网络则没有行之有效的低复杂度算法,最后他们甚至认为神经元网络无法处理非线性问题。然而于1974年,Paul Werbos首次给出了如何训练一般网络的学习算法—back propagation(BP)算法。这个算法可以高效的计算每一次迭代过程中的梯度,让以上我们的推导得以实现。不巧的是,在当时整个人工神经网络社群中无人知晓Paul所提出的学习算法。直到80年代中期,BP算法才重新被David Rumelhart、Geoffrey Hinton及Ronald Williams、David Parker和Yann LeCun独立发现,并获得了广泛的注意,引起了神经网络领域研究的第二次热潮。
二、梯度求解的链式法则
- 上面我们已经已经知道了梯度求解的公式: ∇f=[∂f∂x1,∂f∂x2,…,∂f∂xn]∇f=[\frac{∂f}{∂x_1 },\frac{∂f}{∂x_2},…,\frac{∂f}{∂x_n }]∇f=[∂x1∂f,∂x2∂f,…,∂xn∂f],并且我们也知道了中间的每个元素是函数对相应变量的偏导数∂f∂xi\frac{∂f}{∂x_i }∂xi∂f。我们也知道了偏导数的含义就是:函数相对xix_ixi的的变化率。
- 那么我们只要求出函数fff对每个变量的变化率,我们就可以求出函数fff的梯度,我们使用下面一个例子来说明这个问题。
- 假设有这样一个运算图:
- 假设输入a=2,b=1a=2,b=1a=2,b=1,在这种情况下,如果只考虑相邻层的偏导关系,可以得到下图:
- 根据偏导的含义和上图可知:
- 如果如果其他变量不变,aaa改变1,那么ccc就会改变1,而ccc改变1,eee就会改变2,所有最后得到:aaa改变1,eee就会改变2,即eee相对aaa的变化率为2,即∂e∂a=2\frac{∂e}{∂a}=2∂a∂e=2
- 如果如果其他变量不变,bbb改变1,那么ccc就会改变1并且ddd也会改变1,而ccc改变1,eee就会改变2,ddd改变1,eee就会改变3,所有最后得到:bbb改变1,eee就会改变5,即eee相对aaa的变化率为5,∂e∂b=5\frac{∂e}{∂b}=5∂b∂e=5
- 上面这个过程就是链式法则,最后总结的公式为: ∂e∂a=∂e∂c∗∂c∂a\frac{∂e}{∂a}=\frac{∂e}{∂c}*\frac{∂c}{∂a}∂a∂e=∂c∂e∗∂a∂c∂e∂b=∂e∂c∗∂c∂b+∂∂d∗∂d∂a\frac{∂e}{∂b}=\frac{∂e}{∂c}*\frac{∂c}{∂b}+\frac{∂}{∂d}*\frac{∂d}{∂a}