简单的数学推导,讲解神经网络中常用的梯度下降.
为了便于理解, 我们就用最简单的网络来讲解.比如下面的网络.

此网络只有简单的两层,3个输入x1,x2,x3x1, x2, x3x1,x2,x3. 1个输出y^\hat{y}y^,激活函数f(h)f(h)f(h)采用sigmoid函数.梯度下降的目标是求得最合适的权重w1,w2,w3w1, w2, w3w1,w2,w3使得预测输出y^\hat{y}y^与真实值yyy之间的误差E=12(y−y^)E = \frac{1}{2}(y - \hat{y})E=21(y−y^)最小, 这里的12\frac{1}{2}21是为了方便计算. 从下图直观的感受下, 就是沿着梯度下降的方向移动, 逐渐到达EEE的最小值处.

上图箭头的方向就是梯度下降方向的更新步长Δw=−gradient\Delta w = -gradientΔw=−gradient,下面来推导一下如何求得Δw\Delta wΔw.
∂E∂wi=∂∂wi12(y−y^)2=(y−y^)∂∂wi(y−y^)=−(y−y^)∂y^∂wi\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=∑iwixih = \sum _{i}w_{i}x_{i}h=∑iwixi, 那我们进一步对上式推导:
∂E∂wi=−(y−y^)∂y^∂wi=−(y−y^)f′(h)∂∂wi∑wixi\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∑iwixi=∂∂ωi[w1,x1+w2x2+…+wixi+…wnxn]=xi\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
到此未知我们就顺利的得到了误差EEE关于wiw_{i}wi的梯度:
∂E∂ωi=−(y−y^)f′(h)xi\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η移动,来更行步长:Δwi=η∂E∂ωi\begin{aligned}\Delta w_{i}=\eta\dfrac {\partial E}{\partial \omega _{i}}\end{aligned}Δwi=η∂ωi∂E
为了方便表述,也便于求解,将步长更新Δwi\Delta w_{i}Δwi改写为:
Δwi=ηδxi\Delta w_{i}=\eta \delta x_{i}Δwi=ηδxi
其中: η\etaη为学习速率,值越大权重www更新的速度也就越快. δ\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)
有了权重www的步长更新Δw\Delta wΔw,我们就可以得到进一步接近最优解的新权重了w=w+Δww= w+\Delta ww=w+Δw.如此反复,经过一步步的迭代,权重www将逐步收敛到最优解,就像上图2示意的那样,这就是梯度下降了.
根据上面的简单网络, 实列演示, 看具体怎么用梯度下降来更新权重www.
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]