0x2a

Don't Panic.

Steve's avatar Steve

神经网络的简单理解

前言

好几个月没有写博文了, 感觉虚度了很多光阴. 最近在重新看吴恩达的<机器学习>, 相比于上次, 这次更多原理能看懂理解了, 这篇文章主要记录一下自己对神经网络的理解.

为什么要神经网络

在之前我们曾尝试过使用Linear Regression以及Logistic Regression来解决预测问题, 但是一旦我们的特征多了起来, 我们使用的多项式中的二项式的特征复杂度将士$O(N^2)$. 这样会导致过拟合以及计算资源耗费过大等问题. 当然我们也可以只使用到这些二次项的子集, 但是这必然带来了欠拟合的问题. 甚至更夸张的, 希望包括这些多项式的三次项, 复杂度就会高达$O(N^3) $

为了解决更复杂的预测 分类问题, 我们就需要用到神经网络.

神经网络的基础

神经网络表示

神经网络建立在很多神经元上, 而每个神经元又是一个个学习模型.

那我们结合多个神经元组成神经网络:

一些参数表示:

  • $a^{(j)}_i$:第 $j$ 层的第$i​$个激活单元
  • $\theta^j_{ab}$ : 表示计算$j+1$层时第$a$项, 第$j$层第$b$项的参数
  • $\theta^{(j)}$ : 将第$j$层变成第$j+1$层的参数
  • $L$ : layer总数目 上图 $L = 3$
  • $S_l$: 第l层由n个单位 如上图 $S_2=4$

对于上图模型, 激活单元和输出可以表示为:

这样我们就可以根据公式, 将所有的训练集都喂给神经网络, 计算出所有的输出. 我们将这种从左到右的算法称为前向传播算法 Forward Propagation

利用向量化的方法可以简化整个过程:

那么, 如果我们希望计算第二层的的值, 可以:

将其展开则为:

令 $z ^ { ( 2 ) } = \theta ^ { ( 1 ) } x$ 则 $a ^ { ( 2 ) } = g \left( z ^ { ( 2 ) } \right)$ 并且加上bias unit: $a _ { 0 } ^ { ( 2 ) } = 1$ 计算输出值

又$z ^ { ( 3 ) } = \theta ^ { ( 2 ) } a ^ { ( 2 ) }$, 则 $h _ { \theta } ( x ) = a ^ { ( 3 ) } = g \left( z ^ { ( 3 ) } \right)$

以上只是针对某个训练样本, 但是我们需要针对整个样本进行计算. 我们需要将训练集特征矩阵进行转置,使得同一个实例的特征都在同一列里。即:

一个传统的神经网络就可以看成多个Logistic Regression模型的输出作为另一个Logistic Regression模型的输入的“组合模型”。其实神经网络的底层思想和Logistic Regression很相似, 我们只保留输出层和最后一个隐藏层:

那么此时神经网络就只剩一个Logistic Regression了:

我们可以把$a _ { 0 } , a _ { 1 } , a _ { 2 } , a _ { 3 }$看作更高级的的特征, 但是他们还是由$x_i$决定的. 这些高级特征值比仅仅用$x_i$用作预测有效果, 这也是神经网络比线性回归更有效的原因之一.

偏置的作用

偏置项让神经网络更加灵活, 更容易收敛. 我们来看一个比较简单的例子: 考虑一个只有一个输入以及一个输出(没有bias unit)的网络.

那么这个网络的输出经过权重w0的计算以及激活函数(如sigmoid函数)后, 输出如图所示:

我们修改$w_0$的值可以改变函数的陡峭程度, 但是如果我们的输入$x_i=1$时 要求输出$y_o$为2时, 无论我们怎么修改$w_0$, 也无法达成要求. 我们希望整个函数图像可以向右移动, 这样就可以满足要求了.

这就是bias unit的作用:

当我们添加一个bias unit 以及他也有自己的$weight$, 我们的输出就变成了$sigmoid(w_0 x + w_1 1)$ 如图:

这样, 红色线就能满足我们的要求: $x = 2$时$y_o = 0 $ .

多分类

上述的神经网络都是只有单个输出, 只能用于而分类问题. 当我们需要使用神经网络解决多分类问题时, 需要进行一定的处理.

如上图, 可能的输出为:

四种情况分别对应一种结果.

神经网络的学习

代价函数

先回顾一下Logistic RegressionCost Function:

然而, 在Logistic Regression中我们只有一个输出变量, 但是在神经网络中, 我们由很多输出变量:

看起来比Logistic Regression回归复杂了很多, 但是背后的思想是一样的: 我们希望通过Cost Function来衡量我们当前预测结果和真实情况的误差有多大, 相比于Logistic Regression, 由于神经网络有多个输出值, 我们需要选出可能性在最高的那个与我们的实际值进行比较.

反向传播算法

为了根据我们训练集的输出误差来调整整个网络的权值, 我们可以使用一种叫做反向传播的算法. 对应前面所说的用于计算输出值的正向传播, 反向传播可以计算最后一层的误差, 然后再一层一层反向求出各层的误差, 直到倒数第二层, 进而改变相关的参数.

一开始看反向传播算法觉得一头雾水, 直到看到了A Step by Step Backpropagation Example这篇博文, 才直观地感受到了反向传播的整体意义. 记录一下这篇文章对反向传播过程的推导.

假设我们有以下神经网络:

第一层是输入层, 有两个输入神经元$i_1, i_2$ 同时包括一个偏置项$b_1$; 第二层是隐含层, 包含神经元$h_1,h_2$以及偏置项$b_2$; 第三层是输出层$o_1, o_2$. 初始化一组权值:

我们的目标是调整神经网络的权值,以保证输出可以尽可能拟合我们的实际值。在图片的例子中,我们希望输入是0.05 0.1时 输出是0.01和0.99。

1. 前向传播:

对于$h_1$有:

既:

再将$h_1$经过sigmoid函数就可以算出$out_{h1}$:

同理可以计算出$out_{h2} = 0.5968$.
$o_1$是由两个项决定的:

同理, $out_{o2} = 0.7729$

2. 计算总误差

我们这样定义总误差Squared Error:

其中target是我们计算出的预测值,output是数据集实际值。(有些资料会用ideal代表targetactual代表output

同理可以算出$a$。所以:

3. 反向传播

我们希望先探讨一下$w_5$对于Total Error的影响,那么很容易想到我们可以求偏导:$\frac{\partial{E_{total}}}{\partial{w5}}$

根据链式法则:

在本例中:

根据链式法则继续往下算:

最后可以计算出$w_{5}$对$o_{1}$的影响:

将他们整合起来:

我们常常使用$\delta _{o1}$来表示输出层的误差:

所以:

$\frac { \partial E _ { \text { total } } } { \partial w _ { 5 } } = \delta _ { o 1 } out _ { h 1 }$

求得$w_{5}$对$E_{total}$的影响后, 就可以更新$w_{5}$了:

其中$\eta$是学习率 Learning rate, 有些资料也会用 $\alpha$ 或 $\epsilon$ 表示.

同样的我们可以更新$w_{6},w_{7},w_{8}$值.

在更新完输出层的权值后, 我们开始计算隐藏层的权值

比如我们需要计算$w_{1}$对$E_{\text{total}}$的影响:

从上图可知, $\frac { \partial E _ { \text { total } } } { \partial \text {out} _ { h 1 } }$由两部分组成:

接下来计算$\frac { \partial E _ { o 1 } } { \partial \omega u t _ { h 1 } }$:

$\frac { \partial E _ { o 1 } } { \partial n e t _ { o 1 } }$使用之前计算过的数据可以直接求得:

同时 容易证明$\frac { \partial n e t _ { 0 } 1 } { \partial \omega u t _ { h 1 } } = u _ { 5 }$

将计算出来的值代回原式计算:

同理可计算出:

因此:

现在我们已经有了$\frac { \partial E _ { \text {total} } } { \partial o u t _ { h 1 } }$, 我们需要计算出$\frac { \partial o u t _ { h 1 } } { \partial n e t _ { h 1 } }$ 然后计算出每个$w$对$net_{h1}$的影响:

又:

将他们代入原式计算:

现在我们就可以更新隐藏层的权值:

同样的我们也可以这样更新$w_{2},w_{3},w_{4}$

到此 一个循环的反向传播算法已经结束, 利用多次迭代, 就可以将权值更新到一个可以使输出较为准确的数值, 这就是反向传播的基本思想.

后话

总算把一直没有怎么认真看的神经网络给啃了, 当然这里面的只是涉及到神经网络的一些很基本的理论, 看有没有时间再更一篇比较跟得上时代的神经网络文章吧.

以及, 一步步推导公式还是很有意思的, 虽然打latex公式还是很累. 顺便安利一下Mathpix 这款软件, 省了我不少打公式的时间!!!