这篇Blog的主要内容是关于梯度下降法的一些理解,以及相关的公式推导。梯度下降法很早之前就接触过,但是因为长时间不用,所以理解上也有了一些欠缺,今天看了一些参考文献,写一下自己的一些理解。便于以后帮助自己回忆。
Artificial Neural Network
关于人工神经网络,这是目前使用最广泛的一类算法了。神经网络和其他的算法相比较,计算更加直接。不需要去推导公式,去计算两者的关系,直接通过网络的方式连接,然后用大量的数据训练,没有关系的连接权重逐渐变弱,有关系的权重逐渐变强。如果把输入和输出的函数关系写出来,会发现是一个很复杂的非线性公式。也正是因为这一点,神经网络的拟合程度比普通的线性,非线性算法都要好。
Gradient Descent
对于用梯度下降法训练神经网络,我之前一直没有弄明白的点是为什么梯度的方向就是函数增加最快的方向, 我理解梯度方向是变化最快的方向,但是一直不理解为什么是增加的。今天看了一些参考文献,理解了一点。
对于神经网络,我们会有训练集的数据 { x 0 , y 0 } \{x_0, y_0\} {x0,y0}, x x x和 y y y之间有函数关系 y = f ( x ) y = f(x) y=f(x),函数有自己的参数 p p p,对应于神经网络的权值。所以有 y = f ( p , x ) y = f(p, x) y=f(p,x)。为了能够训练神经网络,让输出和预期值越来越接近,可以定义损失函数(Loss Function),有 l = L ( x 0 , y 0 , y ) l = L(x_0, y_0, y) l=L(x0,y0,y)。其中 y = f ( p , x 0 ) y = f(p, x_0) y=f(p,x0),所以:
l = L ( p , y 0 , x 0 ) l = L(p, y_0, x_0) l=L(p,y0,x0)
计算 l l l关于 p p p的梯度,所以:
▽ C x r ( p ) = < ∂ C x r ∂ p ( 0 ) , . . . , ∂ C x r ∂ p ( n ) \bigtriangledown{C_{xr}(p)} = < \frac{\partial{C_{xr}}}{\partial{p^{(0)}}}, ..., \frac{\partial{C_{xr}}}{\partial{p^{(n)}}} ▽Cxr(p)=<∂p(0)∂Cxr,...,∂p(n)∂Cxr
沿梯度方向,损失函数 l l l的值是逐渐增加的
对这句话的理解,在于是什么量沿着梯度方向的变化。应该是自变量 p p p。例如:
当 ∂ C x r ∂ p ( 0 ) ( p 0 ) > 0 \frac{\partial{C_{xr}}}{\partial{p^{(0)}}}(p_0) > 0 ∂p(0)∂Cxr(p0)>0时,也就是说,函数 l ( p 0 ) l(p^{0}) l(p0)在 p 0 p_0 p0点时,函数曲线沿 p = p 0 p=p^0 p=p0的切线斜率是大于0的,也就是说,在很小的一个区间 ( p 0 − δ , p 0 + δ ) (p_0-\delta, p_0+\delta) (p0−δ,p0+δ),如果 p 1 > p 0 p_1 > p_0 p1>p0, 那么有 l ( p 1 ) > l ( p 0 ) l(p_1) > l(p_0) l(p1)>l(p0)。所以,如果沿着梯度的负方向,损失函数的值也会降低。对于梯度大于0,会比较好理解,因为 l l l是增函数。
如果 ∂ C x r ∂ p ( 0 ) ( p 0 ) < 0 \frac{\partial{C_{xr}}}{\partial{p^{(0)}}}(p_0) < 0 ∂p(0)∂Cxr(p0)<0,那么有 l ( p 0 ) l(p^0) l(p0)是减函数,也就是说,函数在 p 0 p_0 p0点沿 p = p 0 p = p^0 p=p0的切线斜率是小于0的。即,在很小的一个区间 ( p 0 − δ , p 0 + δ ) (p_0-\delta, p_0+\delta) (p0−δ,p0+δ),如果 p 1 > p 0 p_1 > p_0 p1>p0, 那么有 l ( p 1 ) < l ( p 0 ) l(p_1) < l(p_0) l(p1)<l(p0)。但是由于梯度本身小于0,所以梯度的反方向就是 p 0 p^0 p0递增的方向。又因为 l ( p 0 ) l(p^0) l(p0)是减函数,所以沿梯度的负方向, l ( p 0 ) l(p^0) l(p0)还是会逐渐降低。
Neural Network中梯度下降法的推导
这里用最简单的全连接网络为例,如图所示:
x x x:网络的输入值
w 1 , w 2 , w 3 w_1, w_2, w_3 w1,w2,w3:层与层的连接参数
h 1 , h 2 h_1, h_2 h1,h2:中间层的输入值
o 1 , o 2 o_1,o_2 o1,o2:中间层的输出值
y y y:网络的输出值
假设输入参数的个数为 m m m,输出参数的个数为 n n n,第一层的神经元个数为 a a a,第二层的神经元参数为 b b b,所以:
x ∈ R 1 ∗ m x \in R^{1*m} x∈R1∗m
y ∈ R 1 ∗ n y \in R^{1*n} y∈R1∗n
h 1 , o 1 ∈ R 1 ∗ a h_1, o_1 \in R^{1*a} h1,o1∈R1∗a
h 2 , o 2 ∈ R 1 ∗ b h_2, o_2 \in R^{1*b} h2,o2∈R1∗b
w 1 ∈ R m ∗ a w_1 \in R^{m*a} w1∈Rm∗a
w 2 ∈ R a ∗ b w_2 \in R^{a*b} w2∈Ra∗b
w 3 ∈ R b ∗ n w_3 \in R^{b*n} w3∈Rb∗n
网络中每层的激活函数(activation function)用sigmoid函数:
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1
sigmoid函数的导数有如下特点(可以自己推导):
f ′ ( x ) = f ( x ) ∗ ( 1 − f ( x ) ) f'(x) = f(x)*(1-f(x)) f′(x)=f(x)∗(1−f(x))
假设用来训练的数据集为 < x , r > <x, r> <x,r>, x x x为输入值, r r r为输出值
损失函数为:
L = 1 2 ∗ ( y − r ) 2 L = \frac{1}{2}*(y-r)^{2} L=21∗(y−r)2
所以有如下公式:
h 1 = w 1 ∗ x + b 1 h_1=w_1*x+b_1 h1=w1∗x+b1
o 1 = s i g m o i d ( h 1 ) o_1=sigmoid(h_1) o1=sigmoid(h1)
h 2 = w 2 ∗ o 1 + b 2 h_2=w_2*o_1+b_2 h2=w2∗o1+b2
o 2 = s i g m o i d ( h 2 ) o_2=sigmoid(h_2) o2=sigmoid(h2)
h 3 = w 3 ∗ o 2 + b 3 h_3=w_3*o_2+b_3 h3=w3∗o2+b3
y = s i g m o i d ( h 3 ) y=sigmoid(h_3) y=sigmoid(h3)
计算 L L L关于 w 3 w_3 w3的梯度,有:
∂ L ∂ w 3 = ( y − r ) ∗ ∂ ( y − r ) ∂ w 3 \frac{\partial{L}}{\partial{w_3}}=(y-r)*\frac{\partial{(y-r)}}{\partial{w_3}} ∂w3∂L=(y−r)∗∂w3∂(y−r)
= ( y − r ) ∗ ∂ ( y − r ) ∂ h 3 ∗ ∂ h 3 ∂ w 3 =(y-r)*\frac{\partial{(y-r)}}{\partial{h_3}}*\frac{\partial{h_3}}{\partial{w_3}} =(y−r)∗∂h3∂(y−r)∗∂w3∂h3
= ( y − r ) ∗ ( y − r ) ∗ [ 1 − ( y − r ) ] ∗ o 2 = (y-r)*(y-r)*[1- (y-r)]*o_2 =(y−r)∗(y−r)∗[1−(y−r)]∗o2
= ( y − r ) 2 ∗ ( 1 − y + r ) ∗ o 2 = (y-r)^{2} * (1-y+r) * o_2 =(y−r)2∗(1−y+r)∗o2
类似的,可以得到:
∂ L ∂ b 3 = ( y − r ) 2 ∗ ( 1 − y + r ) \frac{\partial{L}}{\partial{b_3}}=(y-r)^{2}*(1-y+r) ∂b3∂L=(y−r)2∗(1−y+r)
∂ L ∂ w 2 = ( y − r ) 2 ∗ ( 1 − y + r ) ∗ w 3 ∗ o 2 ∗ ( 1 − o 2 ) ∗ o 1 \frac{\partial{L}}{\partial{w_2}}=(y-r)^{2} * (1-y+r) * w_3 * o_2 * (1-o_2) * o_1 ∂w2∂L=(y−r)2∗(1−y+r)∗w3∗o2∗(1−o2)∗o1
∂ L ∂ b 2 = ( y − r ) 2 ∗ ( 1 − y + r ) ∗ w 3 ∗ o 2 ∗ ( 1 − o 2 ) \frac{\partial{L}}{\partial{b_2}}=(y-r)^{2} * (1-y+r) * w_3 * o_2 * (1-o_2) ∂b2∂L=(y−r)2∗(1−y+r)∗w3∗o2∗(1−o2)
∂ L ∂ w 1 = ( y − r ) 2 ∗ ( 1 − y + r ) ∗ w 3 ∗ o 2 ∗ ( 1 − o 2 ) ∗ o 1 ∗ ( 1 − o 1 ) ∗ x \frac{\partial{L}}{\partial{w_1}}=(y-r)^{2} * (1-y+r) * w_3 * o_2 * (1-o_2) * o_1 * (1-o_1) * x ∂w1∂L=(y−r)2∗(1−y+r)∗w3∗o2∗(1−o2)∗o1∗(1−o1)∗x
∂ L ∂ b 1 = ( y − r ) 2 ∗ ( 1 − y + r ) ∗ w 3 ∗ o 2 ∗ ( 1 − o 2 ) ∗ o 1 ∗ ( 1 − o 1 ) \frac{\partial{L}}{\partial{b_1}}=(y-r)^{2} * (1-y+r) * w_3 * o_2 * (1-o_2) * o_1 * (1-o_1) ∂b1∂L=(y−r)2∗(1−y+r)∗w3∗o2∗(1−o2)∗o1∗(1−o1)
计算损失函数 L L L关于网络权重的梯度后,网络权重的变化为:
△ W = − η ∗ ∂ L ∂ W \bigtriangleup W = - \eta * \frac{\partial{L}}{\partial{W}} △W=−η∗∂W∂L
其中, W W W是网络中的权重参数,一般只通过学习率来调节网络训练的快慢,是不够的。会加入动态变化量,以加快学习过程。所以:
△ W = − η ∗ ∂ L ∂ W + α ∗ ∂ L ∂ W \bigtriangleup W=-\eta * \frac{\partial{L}}{\partial{W}} + \alpha * \frac{\partial{L}}{\partial{W}} △W=−η∗∂W∂L+α∗∂W∂L
其中, α \alpha α表示动态变化项,是一个常数。