如何更新权重
在上一篇文章中我们算出了各个层的误差,现在是时候利用这些误差来指导链接权重的修改了。那么该如何修改?
- 暴力枚举: 对于一个三层的神经网络,每层有3个神经元结点,有两个3×33\times 33×3的链接权重矩阵,共有18个权重值。假设每个权重在1和-1之间共有1000种取值,那么我们有1000181000^{18}100018种权重组合,这个数字已经很大了。但是,如果是每层有500个结点呢?那么权重数将达到2×500×500=5000002\times 500\times 500 = 5000002×500×500=500000个,将会有10005000001000^{500000}1000500000种组合。想要遍历这么些种可能得等到人类灭绝…
可见,暴力枚举并不能实际地解决我们的问题。
- 新的思路: 让我们再次明确下我们的最终目的,让误差值降到最小。试着将其转化成数学上的求函数最小值问题。先前我们知道,误差是所有链接权重的函数:
Error=Ferror(w1,1,w2,1,......,wj,k) Error = F_{error}(w_{1,1},w_{2,1},......,w_{j,k}) Error=Ferror(w1,1,w2,1,......,wj,k)
现在我们需要额就是找出该函数的最小值。但由于真正的误差函数的自变量太多,先举个简单的例子:
假设误差函数只有一个自变量(链接权重):
Esimple=Fe(x) E_{simple}=F_e(x) Esimple=Fe(x)
其图像为:
可以将其想象成一个连绵的山脉,有山峰也有山谷。设想将一个小球至于山腰,那么在重力的作用下它必定沿着所在位置的斜率方向向下滚动直到山谷。但是很明显,我们并没有重力帮忙,因此必须人为指定“滚动方向”。
不难发现,当斜率为正时应向左滚动(x–),斜率为负时应向右滚动(x++)。这种方法在数学上被称为梯度下降(gradient descent)。
可能的意外情况:
我们可能会碰到这种情况:当小球的起始位置为左侧山腰时,其很有可能最终会在局部最小值(左侧的山谷)停下,这可不是我们所希望的结果。因为我们的目的是把误差降到最小,那里显然不是最小的地方。
为了避免上述情况,我们应从选择不同的其实位置对神经网络进行多次训练,以确保其并不总是终止于错误的地方。而不同的其实位置意味着不同的链接权重。
选择误差函数的形式
可选项:
- E=tn−onE=t_n-o_nE=tn−on (目标值 - 期望值)
- E=(tn−on)2E=(t_n-o_n)^2E=(tn−on)2 平方差形式
我们选用平方差形式,因为其具有很多优点:
- 可以很容易地使用代数方法(链式法则求解偏导数)计算出梯度下降的斜率
- 误差函数平滑连续,这使得梯度下降算法可以很好地发挥作用
- 越接近最小值梯度(斜率)越小,按照斜率调整步长可以减少越过最佳位置的风险
计算梯度值(斜率)
- 当只有一个链接权重时,误差函数为二维曲线:
k=∂E∂x k=\frac{\partial{E}}{\partial{x}} k=∂x∂E - 当有两个链接权重时,误差函数为一个三维曲面:
k=∂E∂wj,k k=\frac{\partial{E}}{\partial{w_{j,k}}} k=∂wj,k∂E
上述表达式表示了当权重wj,kw_{j,k}wj,k改变时,误差EEE是如何改变的。这是误差函数的斜率,也就是我们希望使用梯度下降的方法达到最小值的方向。 - 当有多个链接权重时(普遍有多个),图像对于地球人这种三维生物已经无法描绘出来了。但是本质(计算方法)还是一样的。
计算梯度:
- 在开始计算前我们回顾一下网络中各个参数的意义:
- 展开误差函数:
由于一个结点的误差只与与其相连的链接权重有关,因此误差函数可以简单地表示为:
E=(tk−ok)2 E=(t_k-o_k)^2 E=(tk−ok)2
其中:ok=Sig(∑j=1nwj,k⋅ohj)o_k=Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}})ok=Sig(∑j=1nwj,k⋅ohj)所以:
E=(tk−Sig(∑j=1nwj,k⋅ohj))2 E=(t_k-Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}))^2 E=(tk−Sig(j=1∑nwj,k⋅ohj))2
所以:
∂E∂wj,k=∂(tk−ok)2∂wj,k \frac{\partial{E}}{\partial{w_{j,k}}}=\frac{\partial{(t_k-o_k)^2}}{\partial{w_{j,k}}} ∂wj,k∂E=∂wj,k∂(tk−ok)2
=∂E∂ok⋅∂ok∂wj,k=−2(tk−ok)⋅∂ok∂wj,k =\frac{\partial{E}}{\partial{o_k}}\cdot \frac{\partial{o_k}}{\partial{w_{j,k}}}=-2(t_k-o_k)\cdot \frac{\partial{o_k}}{\partial{w_{j,k}}} =∂ok∂E⋅∂wj,k∂ok=−2(tk−ok)⋅∂wj,k∂ok
其中:令x=∑j=1nwj,k⋅ohjx=\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}x=∑j=1nwj,k⋅ohj
∂ok∂wj,k=∂Sig(x)∂wj,k=∂Sig(x)∂x⋅∂x∂wj,k \frac{\partial{o_k}}{\partial{w_{j,k}}}=\frac{\partial{Sig(x)}}{\partial{w_{j,k}}}=\frac{\partial{Sig(x)}}{\partial{x}}\cdot \frac{\partial{x}}{\partial{w_{j,k}}} ∂wj,k∂ok=∂wj,k∂Sig(x)=∂x∂Sig(x)⋅∂wj,k∂x
且:
∂Sig(x)∂x=Sig(x)⋅(1−Sig(x)) \frac{\partial{Sig(x)}}{\partial{x}}=Sig(x)\cdot (1-Sig(x)) ∂x∂Sig(x)=Sig(x)⋅(1−Sig(x))
因此,我们得到了以下表达式:
∂E∂wj,k=−2(tk−ok)⋅Sig(∑j=1nwj,k⋅ohj)⋅(1−Sig(∑j=1nwj,k⋅ohj))⋅∂(∑j=1nwj,k⋅ohj)∂wj,k \frac{\partial{E}}{\partial{w_{j,k}}}=-2(t_k-o_k)\cdot Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}})\cdot (1-Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}))\cdot \frac{\partial{(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}})}{\partial{w_{j,k}}} ∂wj,k∂E=−2(tk−ok)⋅Sig(j=1∑nwj,k⋅ohj)⋅(1−Sig(j=1∑nwj,k⋅ohj))⋅∂wj,k∂(∑j=1nwj,k⋅ohj)
=−2(tk−ok)⋅Sig(∑j=1nwj,k⋅ohj)⋅(1−Sig(∑j=1nwj,k⋅ohj))⋅ohj =-2(t_k-o_k)\cdot Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}})\cdot (1-Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}))\cdot o_{hj} =−2(tk−ok)⋅Sig(j=1∑nwj,k⋅ohj)⋅(1−Sig(j=1∑nwj,k⋅ohj))⋅ohj
又由于我们只关心误差函数斜率的方向,因此可以将公式中的常数2省略,并不影响正负号:
∂E∂wj,k=−(tk−ok)⋅Sig(∑j=1nwj,k⋅ohj)⋅(1−Sig(∑j=1nwj,k⋅ohj))⋅ohj \frac{\partial{E}}{\partial{w_{j,k}}}=-(t_k-o_k)\cdot Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}})\cdot (1-Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}))\cdot o_{hj} ∂wj,k∂E=−(tk−ok)⋅Sig(j=1∑nwj,k⋅ohj)⋅(1−Sig(j=1∑nwj,k⋅ohj))⋅ohj
=−(ej)⋅Sig(∑j=1nwj,k⋅ohj)⋅(1−Sig(∑j=1nwj,k⋅ohj))⋅ohj =-(e_j)\cdot Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}})\cdot (1-Sig(\sum_{j=1}^{n}{w_{j,k}\cdot o_{hj}}))\cdot o_{hj} =−(ej)⋅Sig(j=1∑nwj,k⋅ohj)⋅(1−Sig(j=1∑nwj,k⋅ohj))⋅ohj
改变链接权重
之前提到过,权重的改变方向与梯度的方向相反。因此我们规定权重的改变方式为:
wj,knew=wj,kold−α⋅∂E∂wj,k
w_{j,k}^{new}=w_{j,k}^{old}-\alpha \cdot \frac{\partial{E}}{\partial{w_{j,k}}}
wj,knew=wj,kold−α⋅∂wj,k∂E
参数释义:
- α\alphaα为学习因子,可以调节这些权重变化的强度
用矩阵来简化运算:
(△w1,1△w2,1△w3,1...△w1,2△w2,2△w3,2...△w1,3△w2,3△w3,3...............)=α⋅(e1⋅S1⋅(1−S1)e2⋅S2⋅(1−S2)ek⋅Sk⋅(1−Sk)...)⋅(o1,o2,o3,...)
\left(
\begin{matrix}
\vartriangle w_{1,1} & \vartriangle w_{2,1} & \vartriangle w_{3,1} & ...\\
\vartriangle w_{1,2} & \vartriangle w_{2,2} & \vartriangle w_{3,2} & ...\\
\vartriangle w_{1,3} & \vartriangle w_{2,3} & \vartriangle w_{3,3} & ...\\
... & ... & ... & ...
\end{matrix}
\right)=\alpha\cdot \left(\begin{matrix}e_1\cdot S_1\cdot (1-S_1)\\ e_2\cdot S_2\cdot (1-S_2)\\ e_k\cdot S_k\cdot (1-S_k)\\ ...\end{matrix}\right) \cdot (o_1,o_2,o_3,...)
⎝⎜⎜⎛△w1,1△w1,2△w1,3...△w2,1△w2,2△w2,3...△w3,1△w3,2△w3,3...............⎠⎟⎟⎞=α⋅⎝⎜⎜⎛e1⋅S1⋅(1−S1)e2⋅S2⋅(1−S2)ek⋅Sk⋅(1−Sk)...⎠⎟⎟⎞⋅(o1,o2,o3,...)
将Sig函数简化为输出:
△wj,k=α×Ek×Ok×(1−Ok)⋅OjT
\vartriangle w_{j,k} = \alpha\times E_k \times O_k \times (1-O_k) \cdot O_j^T
△wj,k=α×Ek×Ok×(1−Ok)⋅OjT
到此,所有的前期工作都已完成。