机器学习入门——反向传播神经网络数学推导


机器学习顾名思义,即是让机器来进行学习,我们希望计算机可以通过海量的数据的输入,来学习处理某些图形或者事件的方法。
机器学习的方法有许许多多,具体可以参见之前的这篇文章,其中一种较为简单的方法是使用反向传播神经网络,配合方向传播算法。
我们以有一个隐藏层的神经网络为例,一个隐藏层即表示该神经网络有输入层 input_units, 隐藏层 hidden_units,和输出层 output_units。即我们输入的数值是以 input_units -> hidden_units -> output_units 的路径传递的。
而具体的传递方式为,我们 input_units 到 hidden_units 和 hidden_units 到 output_units 都有对应的权值。
$$temp\_hidden\_units(i) = \sum_{j = 0}^{n}input\_units[j] * input\_weigths[j][i]$$
这里之所以用用 temp_hidden_units 是因为我们想要得到并非线性相关的曲线。也就是说我们生活中很多关系都不是线性的,若我们只将神经网络局限于线性关系,将对结果带来很大影响。因此,我们额外需要使用函数
\begin{equation}
S(x) = \frac{1}{1+\mathrm{e}^{-x}}
\end{equation}

\begin{equation}
hidden\_units[i] = \frac{1}{1+\mathrm{e}^{-temp\_hidden\_units[i]}}
\end{equation}
我们对 temp_output_units 和 output_units 也进行同样的处理。
之所以使用这个函数,是因为它求导数及其方便,有
\begin{equation}
S'(x) = \frac{\mathrm{e}^{-x}}{(1+\mathrm{e}^{-x})^2} = S(x){(1-S(x))}
\end{equation}
这样,我们就完成了输入数值的前向传播,接着,我们要计算各个输出节点(output_units)产生的误差,并且计算各个权值对误差的贡献(即误差对权值求偏导数)
首先是总误差
\begin{equation}
Error_{total} = \sum_{i = 0}^{n}\frac{1}{2}(target[i] – output\_units[i])^2
\end{equation}

我们现在要将各个权值对总误差的贡献率求出,即将误差反向传播。

第一步,对于隐藏层的权值 hidden_weights[i][j] 求偏导数

我们可以得到
\begin{equation}
\frac{\partial Error_{total}}{\partial hidden\_weights[i][j]} = \frac{\partial Error_{total}}{\partial output\_units[j]} * \frac{\partial output\_units[j]}{\partial temp\_output_units[j]} * \frac{\partial temp\_output\_units[j]}{\partial hidden\_weights[i][j]}
\end{equation}
将偏导数求出来后就可以得到
\begin{equation}
\begin{split}
\frac{\partial Error_{total}}{\partial hidden\_weights[i][j]} = -(target[j] – output\_units[j]) * output\_units[j]
* (1 – output\_units[j]) * hidden\_units[i]
\end{split}
\end{equation}
若是令
\begin{equation}
\delta(output\_units[i]) = -(target[j] – output\_units[j]) * output\_units[j]
\end{equation}
我们就有
\begin{equation}
\frac{\partial Error_{total}}{\partial hidden\_weights[i][j]} = \delta(output\_units[j]) * hidden\_units[i]
\end{equation}
这样在编写程序的时候,先将各个 δ 算出来,再带入上面的公式,就可以计算出隐藏层各个权值对我们总误差的贡献率。

第二步,对于输入层的权值 input_weights[i][j] 求偏导数

我们可以得到
\begin{equation}
\frac{\partial Error_{total}}{\partial input\_weights[i][j]} = (\sum_{q = 0}^{n}{\delta(output\_units[q]) * hidden\_weights[q][j]) * hidden\_units[j] * (1 – hidden\_units[j]) * input\_units[i]}
\end{equation}
若令
\begin{equation}
\delta(hidden\_units[i]) = (\sum_{q = 0}^{n}{\delta(output_units[q]) * hidden\_weights[q}[j]) * hidden\_units[j] * (1 – hidden\_units[j])
\end{equation}
我们有
\begin{equation}
\frac{\partial Error_{total}}{\partial input\_weights[i][j]} = \delta(hidden\_units[j]) * input\_units[i]
\end{equation}
这样,所有的权值对总误差的贡献率就求了出来。我们接着需要对权值进行调整,一般来说是减去总误差对该权值的偏导数乘以学习速率 0.3,可任意调整学习速率,但若学习速率过高,会使我们的机器学习效果过拟合。
通过大量的数据进行大量的学习,反复调整我们所有的权值,即可使训练出的神经网络接近预期结果。
以上即是构造反向传播神经网络的大致思路。