aaJamesJones 2019-06-26
神经网络算法( Neural Network
)是机器学习中非常非常重要的算法。这是整个深度学习的核心算法,深度学习就是根据神经网络算法进行的一个延伸。理解这个算法的是怎么工作也能为后续的学习打下一个很好的基础。
神经网络是受神经元启发的,对于神经元的研究由来已久,1904年生物学家就已经知晓了神经元的组成结构。
Perceptron
)。Backpropagation
,BP)算法,这是最著名的一个神经网络算法。多层神经网络由三部分组成:输入层( input layer
), 隐藏层 ( hidden layers
), 输出层 ( output layers
)。
每一层都是有单元( units
)组成,其中,输入层是由训练集中实例特征向量传入,根据连接点之间的权重传递到下一层,这样一层一层向前传递。
输入层和输出层都只有一层,隐藏层的个数可以是任意的。神经网络的层数计算中不包括输入层,比方说一个神经网络中有2个隐藏层,我们就说这是一个3层的神经网络。
作为多层向前神经网络,理论上,如果有足够多的隐藏层和训练集,是可以模拟出任何方程的。
神经网络可以用来解决分类( classification
)问题,也可以解决回归( regression
)问题。
由两层神经网络构成了单层神经网络,它还有个别名———— 感知器
。
如图中,有3个输入,连接线的权值分别是 w1, w2, w3。将输入与权值进行乘积然后求和,作为 z 单元的输入,如果 z 单元是函数 g ,那么就有 z = g(a1 * w1 + a2 * w2 + a3 * w3)
。
单层神经网络的扩展,也是一样的计算方式:
在多层神经网络中,只不过是将输出作为下一层的输入,一样是乘以权重然后求和:
使用神经网络进行训练之前,必须确定神经网络的层数,以及每一层中单元的个数。整个训练过程就是调整连接点之间的权重值。
特征向量在被传入输入层前,通常要先标准化为 0 到 1 之间的数,这是为了加速学习过程。
对于分类问题,如果是两类,可以用一个输出单元(0 和 1 表示分类结果)进行表示。如果是多分类问题,则每一个类别用一个输出单元表示。分类问题中,输出层单元个数通常等于类别的数量。
目前没有明确的规则来设计最好有多少个隐藏层,通常是根据实验测试和误差,以及准确度来进行改进。
如何来预测准确度呢?在SVM的应用篇中,有个方法就是将数据集分为两类,训练集和测试集,利用测试集的数据将模型的预测结果进行对比,得出准确度。这里介绍另一个常用但更科学的方法————交叉验证方法( Cross-Validation
)。
这个方法不局限于将数据集分成两份,它可以分成 k 份。用第一份作为训练集,其余作为测试集,得出这一部分的准确度 ( evaluation
)。再用第二份作为训练集,其余作为测试集,得出这第二部分的准确度。以此类推,最后取各部分的准确度的平均值。从而可以得到设计多少层最佳。
BP 算法 ( Backpropagation
)是多层神经网络的训练一个核心的算法。目的是更新每个连接点的权重,从而减小预测值( predicted value
)与真实值 ( target value
)之间的差距。输入一条训练数据就会更新一次权重,反方向(从输出层=>隐藏层=>输入层)来以最小化误差(error)来更新权重(weitht)。
在训练神经网络之前,需要初始化权重( weights
)和偏向( bias
),初始化是随机值, -1 到 1 之间,每个单元有一个偏向。
数据集用 D
表示,学习率用 l
表示。对于每一个训练实例 X,都是一样的步骤。
利用上一层的输入,得到本层的输入:
$$I_j = \sum_i w_{i,j}O_i + \theta{j}$$
得到输入值后,神经元要怎么做呢?我们先将单个神经元进行展开如图:
得到值后需要进行一个非线性转化,这个转化在神经网络中称为激活函数( Activation function
),这个激活函数是一个 S 函数,图中以 f 表示,它的函数为:
$$O_j = \frac1{1+e^{-I_j}}$$
通过上面的传递规则,可以得到最终的输出,而训练实例中包含实际的值,因此可以得到训练和实际之间的误差。根据误差(error)反向传送。
对于输出层的误差为:
$$Err_j = O_j(1 - O_j)(T_j - O_j)$$
其中 Oj
表示预测值, Tj
表示真实值。
对隐藏层的误差:
$$Err_j = O_j(1 - O_j)\sum_k Err_kw_{j,k}$$
更新权重:
$$\begin{align*}\Delta w_{i,j} &= (l)Err_jO_i \\w_{i,j} &= w_{i,j} + \Delta w_{i,j}\end{align*}$$
这里的 l
是学习率。偏向更新:
$$\begin{align*}\Delta \theta{j} &= (l)Err_j \\\theta{j} &= \theta{j} + \Delta \theta{j}\end{align*}$$
怎样才算是一个训练好了的神经网络呢?满足下面一个情况即可:
假设有一个两层的神经网络,结构,权重和数据集如下:
计算误差和更新权重: