简单的数学推导,讲解神经网络中常用的梯度下降.
为了便于理解, 我们就用最简单的网络来讲解.比如下面的网络.
此网络只有简单的两层,3个输入 x 1 , x 2 , x 3 x1, x2, x3 x1,x2,x3. 1个输出 y ^ \hat{y} y^,激活函数 f ( h ) f(h) f(h)采用sigmoid函数.梯度下降的目标是求得最合适的权重 w 1 , w 2 , w 3 w1, w2, w3 w1,w2,w3使得预测输出 y ^ \hat{y} y^与真实值 y y y之间的误差 E = 1 2 ( y − y ^ ) E = \frac{1}{2}(y - \hat{y}) E=21(y−y^)最小, 这里的 1 2 \frac{1}{2} 21是为了方便计算. 从下图直观的感受下, 就是沿着梯度下降的方向移动, 逐渐到达 E E E的最小值处.
上图箭头的方向就是梯度下降方向的更新步长
Δ
w
=
−
g
r
a
d
i
e
n
t
\Delta w = -gradient
Δw=−gradient,下面来推导一下如何求得
Δ
w
\Delta w
Δw.
∂
E
∂
w
i
=
∂
∂
w
i
1
2
(
y
−
y
^
)
2
=
(
y
−
y
^
)
∂
∂
w
i
(
y
−
y
^
)
=
−
(
y
−
y
^
)
∂
y
^
∂
w
i
\begin{aligned}\frac{\partial E}{\partial w_{i}} &= \frac{\partial }{\partial w_{i}}\frac{1}{2}(y - \hat{y})^{2} \\&= (y - \hat{y})\frac{\partial }{\partial w_{i}}(y - \hat{y}) \\&= -(y - \hat{y})\frac{\partial \hat{y}}{\partial w_{i}}\end{aligned}
∂wi∂E=∂wi∂21(y−y^)2=(y−y^)∂wi∂(y−y^)=−(y−y^)∂wi∂y^
其中 y ^ = f ( x ) \hat{y} = f(x) y^=f(x) 且 h = ∑ i w i x i h = \sum _{i}w_{i}x_{i} h=∑iwixi, 那我们进一步对上式推导:
∂ E ∂ w i = − ( y − y ^ ) ∂ y ^ ∂ w i = − ( y − y ^ ) f ′ ( h ) ∂ ∂ w i ∑ w i x i \begin{aligned}\begin{aligned}\dfrac {\partial E}{\partial w_{i}}&=-\left( y-\widehat {y}\right) \dfrac {\partial \hat{y}}{\partial w_{i}}\\&= -\left( y-\widehat {y}\right) f'\left( h\right) \dfrac {\partial }{\partial w_{i}}\sum w_{i}x_{i}\end{aligned}\end{aligned} ∂wi∂E=−(y−y )∂wi∂y^=−(y−y )f′(h)∂wi∂∑wixi
其中:
∂
∂
ω
i
∑
i
w
i
x
i
=
∂
∂
ω
i
[
w
1
,
x
1
+
w
2
x
2
+
…
+
w
i
x
i
+
…
w
n
x
n
]
=
x
i
\begin{aligned}\begin{aligned}\dfrac {\partial }{\partial \omega_{i}}\sum _{i}w_{i}x_{i}&=\dfrac {\partial }{\partial \omega _{i}}\left[ w_{1},x_{1}+w_{2}x_{2}+\ldots +w_{i}x_{i}+\ldots w_{n}x_{n}\right] \\ &=x_{i}\end{aligned}\end{aligned}
∂ωi∂i∑wixi=∂ωi∂[w1,x1+w2x2+…+wixi+…wnxn]=xi
到此未知我们就顺利的得到了误差
E
E
E关于
w
i
w_{i}
wi的梯度:
∂
E
∂
ω
i
=
−
(
y
−
y
^
)
f
′
(
h
)
x
i
\begin{aligned}\dfrac {\partial E}{\partial \omega _{i}}=-\left(y- \hat{y}\right) f'\left( h\right) x_{i}\end{aligned}
∂ωi∂E=−(y−y^)f′(h)xi
沿着梯度下降的方向,以一定的学习速率 η \eta η移动,来更行步长: Δ w i = η ∂ E ∂ ω i \begin{aligned}\Delta w_{i}=\eta\dfrac {\partial E}{\partial \omega _{i}}\end{aligned} Δwi=η∂ωi∂E
为了方便表述,也便于求解,将步长更新
Δ
w
i
\Delta w_{i}
Δwi改写为:
Δ
w
i
=
η
δ
x
i
\Delta w_{i}=\eta \delta x_{i}
Δwi=ηδxi
其中:
η
\eta
η为学习速率,值越大权重
w
w
w更新的速度也就越快.
δ
\delta
δ为误差项 error term.
δ
=
−
(
y
−
y
^
)
f
′
(
h
)
\begin{aligned}\delta =-\left(y- \hat{y}\right) f'\left( h\right) \end{aligned}
δ=−(y−y^)f′(h)
有了权重 w w w的步长更新 Δ w \Delta w Δw,我们就可以得到进一步接近最优解的新权重了 w = w + Δ w w= w+\Delta w w=w+Δw.如此反复,经过一步步的迭代,权重 w w w将逐步收敛到最优解,就像上图2示意的那样,这就是梯度下降了.
根据上面的简单网络, 实列演示, 看具体怎么用梯度下降来更新权重 w w w.
import numpy as np
#定义sigmoid函数
def sigmoid(x):
return 1/(1+np.exp(-x))
#sigmoid函数求导
def sigmoid_prime(x):
return sigmoid(x) * (1 - sigmoid(x))
learnrate = 0.5 #学习率
x = np.array([1, 2, 3]) #定义输入.x1,x2,x3
y = np.array(0.5) #定义输出
w = np.array([0.5, -0.5, 0.3]) #初始化权重,也就是上文中的w1,w2,w3.
h = np.dot(x,w) #求得h的值
nn_output = sigmoid(h) #求得f(h)的值
error = y-nn_output #求得误差
error_term = sigmoid_prime(h)*error #求得误差项
del_w = learnrate*error_term*x #权重w的改变del_w
print('网络的输出:')
print(nn_output)
print('误差Error:')
print(error)
print('权重w的改变:')
print(del_w)
网络的输出:
0.598687660112452
误差Error:
-0.098687660112452
权重w的改变del_w:
[-0.01185539 -0.02371077 -0.03556616]