大火的神经网络到底是什么 | 机器学习

163 阅读6分钟

1. 问题

神经网络这几年成了最炙手可热的技术,大有一统江湖的气势。不搞懂神经网络,出去都不好意思和人吹牛自己学过机器学习。

今天我们就来剖析一下神经网络到底是怎么回事。

2. 分析

2.1. 正向传播

之前我们讨论的逻辑回归,可以用图形表示为

x0+---+
      |
x1+---+
      |
x2+-------g(z)--> Output y
      |
x3+---+
      |
x4+---+

其中 ,是X的一个线性组合。

通过组合,我们将X转换成了一个中间单元 z,然后再对 z 进行加工。因为梯度下降, z 可以比原始数据 X 更好的特性。

举个例子,比如我们预测房价,房子长度、宽度是可以直接测量的,但实际上面积和房价相关性更好,而面积就是由长度和宽度加工出来的。

所以我们很自然的就会想到,如果不仅仅使用一个拟合,是不是可以有更好的效果?那么就会有下面的情况

x0+--+       a20---+
     |             |
x1+--+   +---a21---+
     |   |         |
x2+------+---a22---+--> Output y
     |   |         |
x3+--+   +---a23---+
     |   
x4+--+   

其中

这样,我们就通过变换,把原始输入X,变成了中间单元 a,然后用 a 再计算最终结果。所以 a 既不是输入也不是输出,我们是看不到的,故而称之为隐藏层(Hidden Layer)。

上面图中的 a0 有点特殊,它并不是像其他中间元一样,由 X 得出,而是额外添加的解释单元。可以理解为线性函数里面的截距。

用身高和年龄的关系打个比方就容易理解了。身高和年龄肯定是有一定关系的。如果我们把孩子出生的那一刻定为 x=0,身高在 x=0的时候显然不为0,而是某一个正数,我们用额外的变量截距来表达。

偏置单元也可以这样理解。

上式里面,有

  • : X的线性变换矩阵,通过 得出激活函数需要的参数 z。也称为权重(Weights);
  • : 激活函数,用于将 X 的线性组合 Z 转换成神经元的有效值。比如我们依然可以用类似逻辑回归的 作为激活函数,将神经元的值转换为 [0, 1]之间的概率;

经过上述处理,把 X 转换成 a 以后,就可以把 a 作为输入单元,再进行下一步类似计算。

具体而言,我们用

来得出最终的y。

我们大脑在处理信息的时候也是类似情况,现将外界输入信息在神经元处加工,然后输入大脑进行处理。

中间层类似于加工外界信息的神经元,模型又是由多个神经元及输入层组成的网状结构,所以这种模型称之为神经网络模型。

2.2. 反向传播

当我们有了 以后,就可以把 X 加工成 Z、T,然后加工成 y,从而给出预测。但问题是我们如何得到 呢?这就需要用到反向传播。

我们以分类模型为例。如果输出结果是二元变量,即只有 [0, 1] 两个值,那么模型就和逻辑回归类似。如果输出结果是多个值,我们就需要考虑多种情况。通常情况下,我们会为 k 个输出结果定义一个 k 阶向量,其中只有一个结果为 1,其他均为0。即

这样,我们就把神经网络的多分类问题,转换成了类似逻辑回归的问题。

那么类似于逻辑回归的代价函数,我们只需要增加一个对 k 个结果的循环,即可得到神经网络的代价函数

呃,上面这个公式很复杂,复杂到我看着它都觉得累。而实际上,还有正规化(Regularization)部分没有加入。不过我们先不要在意这些细节,继续往下挖挖。

所谓反向传播,是和正向传播相对的。我们从输入值 X 一步步计算到输出值 y 的过程,就是正向传播的过程;反向反过来,就是反向传播。只是反向传播的是误差,不是输入值。

我们以一个四层神经网络为例,如下图所示。其中a1是输入层,a2/a3是两个隐藏层,a4是输出层。

随机初始化,通过正向传播我们可以求出预测的结果和实际值之间的误差,也即

然后利用这个误差值来计算前一层的误差:

其中, 是权重导致的误差的和。类似的,我们可以继续计算前一层误差

由此,我们就可以由后面一层的误差,传递到前面一层。

有了所有的误差的表达式后,便可以计算代价函数的偏导数了

有了偏导数,我们就可以用梯度下降的方法,逐步逼近求解出合适的 了。

有了权重,针对新的输入 X,我们就可以计算出相应的预测结果 y 了。

3. 实现

相对之前聊的线性回归和逻辑回归,神经网络是一种更为复杂的算法。向前传播求解、向后传播误差求参数是其核心思想。具体数学细节没有办法在一篇文章里面讲清楚,而且对于绝大多数人来说,也没有必要完全实现其背后的公式推导。对数学原理感兴趣的朋友可以参考文献 [2] ,里面有详细的公式推导和数学原理讲解。

另外,上面举例是用的分类算法,实际上神经网络也可以输出连续值。这种情况下输出单元就只有一个,最后一步采用回归即可。逻辑和原理与分类算法一样。

在实际应用中,除非为了练习,我们无需自己编写代码实现神经网络。现在已经有很成熟的软件包可以用。我们以 scikit learning 为例。

import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split

data = np.loadtxt('assets\ex3data.txt', delimiter=' ')
X = data[:, 0:400]; y = data[:, -1]

X_train, X_test, y_train, y_test = train_test_split(X, y)
mlp = MLPClassifier(solver='lbfgs', random_state=1).fit(X_train, y_train)

print("Training set score: {:.2f}".format(mlp.score(X_train, y_train)))
print("Test set score: {:.2f}".format(mlp.score(X_test, y_test)))

输出

Training set score: 1.00
Test set score: 0.92

呃,这个训练集是不是存在 Overfit 的情况啊……

4. 交流

独学而无友则孤陋寡闻。现有「数据与统计科学」微信交流群,内有数据行业资深从业人员、海外博士、硕士等,欢迎对数据科学、数据分析、机器学习、人工智能有兴趣的朋友加入,一起学习讨论。

大家可以扫描下面二维码,添加荔姐微信邀请加入,暗号:机器学习加群。

5. 扩展

5.1. 延伸阅读

5.2. 参考文献

  1. G. James, D. Witten, T. Hastie R. Tibshirani, An introduction to statistical learning: with applications in R. New York: Springer, 2013.
  2. T. Hastie, R. Tibshirani, J. H. Friedman, The elements of statistical learning: data mining, inference, and prediction, 2nd ed. New York, NY: Springer, 2009.
  3. W. Härdle, L. Simar, Applied multivariate statistical analysis, 3rd ed. Heidelberg ; New York: Springer, 2012.

本文使用 mdnice 排版