本文主要是介绍大火的神经网络到底是什么 | 机器学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 问题
神经网络这几年成了最炙手可热的技术,大有一统江湖的气势。不搞懂神经网络,出去都不好意思和人吹牛自己学过机器学习。
今天我们就来剖析一下神经网络到底是怎么回事。
2. 分析
2.1. 正向传播
之前我们讨论的逻辑回归,可以用图形表示为
x0+---+|
x1+---+|
x2+-------g(z)--> Output y|
x3+---+|
x4+---+
其中 z = θ T X z = \theta^T X z=θTX,是X的一个线性组合。
通过组合,我们将X转换成了一个中间单元 z,然后再对 z 进行加工。因为梯度下降, z 可以比原始数据 X 更好的特性。
举个例子,比如我们预测房价,房子长度、宽度是可以直接测量的,但实际上面积和房价相关性更好,而面积就是由长度和宽度加工出来的。
所以我们很自然的就会想到,如果不仅仅使用一个拟合,是不是可以有更好的效果?那么就会有下面的情况
x0+--+ a20---+| |
x1+--+ +---a21---+| | |
x2+------+---a22---+--> Output y| | |
x3+--+ +---a23---+|
x4+--+
其中
a = g ( Θ X ) a = g(\Theta X) a=g(ΘX)
这样,我们就通过变换,把原始输入X,变成了中间单元 a,然后用 a 再计算最终结果。所以 a 既不是输入也不是输出,我们是看不到的,故而称之为隐藏层(Hidden Layer)。
上面图中的 a0 有点特殊,它并不是像其他中间元一样,由 X 得出,而是额外添加的解释单元。可以理解为线性函数里面的截距。
用身高和年龄的关系打个比方就容易理解了。身高和年龄肯定是有一定关系的。如果我们把孩子出生的那一刻定为 x=0,身高在 x=0的时候显然不为0,而是某一个正数,我们用额外的变量截距来表达。
偏置单元也可以这样理解。
上式里面,有
- Θ \Theta Θ: X的线性变换矩阵,通过 z = Θ X z = \Theta X z=ΘX 得出激活函数需要的参数 z。也称为权重(Weights);
- g ( z ) g(z) g(z): 激活函数,用于将 X 的线性组合 Z 转换成神经元的有效值。比如我们依然可以用类似逻辑回归的 g ( z ) = 1 1 − e − z g(z) = \dfrac{1}{1-e^{-z}} g(z)=1−e−z1作为激活函数,将神经元的值转换为 [0, 1]之间的概率;
经过上述处理,把 X 转换成 a 以后,就可以把 a 作为输入单元,再进行下一步类似计算。
具体而言,我们用
Z = Θ ( 1 ) X a = g ( Z ) T = Θ ( 2 ) a h ( X ) = g ( T ) \begin{aligned} Z & = \Theta^{(1)} X\\ a & = g(Z)\\ T & = \Theta^{(2)} a\\ h(X) &= g(T) \end{aligned} ZaTh(X)=Θ(1)X=g(Z)=Θ(2)a=g(T)
来得出最终的y。
我们大脑在处理信息的时候也是类似情况,现将外界输入信息在神经元处加工,然后输入大脑进行处理。
中间层类似于加工外界信息的神经元,模型又是由多个神经元及输入层组成的网状结构,所以这种模型称之为神经网络模型。
2.2. 反向传播
当我们有了 Θ \Theta Θ 以后,就可以把 X 加工成 Z、T,然后加工成 y,从而给出预测。但问题是我们如何得到 Θ \Theta Θ 呢?这就需要用到反向传播。
我们以分类模型为例。如果输出结果是二元变量,即只有 [0, 1] 两个值,那么模型就和逻辑回归类似。如果输出结果是多个值,我们就需要考虑多种情况。通常情况下,我们会为 k 个输出结果定义一个 k 阶向量,其中只有一个结果为 1,其他均为0。即
h Θ ( x ) ≈ [ 1 ⋮ 0 0 ⋮ 0 ] k , … h Θ ( x ) ≈ [ 0 ⋮ 0 1 ⋮ 0 ] k , … h Θ ( x ) ≈ [ 0 ⋮ 0 0 ⋮ 1 ] k h_{\Theta}(x) \approx \begin{bmatrix} 1\\ \vdots\\ 0\\ 0\\ \vdots\\ 0\\ \end{bmatrix}_k, \quad\dotsc \quad h_{\Theta}(x) \approx \begin{bmatrix} 0\\ \vdots\\ 0\\ 1\\ \vdots\\ 0 \end{bmatrix}_k,\quad\dotsc \quad h_{\Theta}(x) \approx \begin{bmatrix} 0\\ \vdots\\ 0\\ 0\\ \vdots\\ 1 \end{bmatrix}_k hΘ(x)≈⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡1⋮00⋮0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤k,…hΘ(x)≈⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡0⋮01⋮0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤k,…hΘ(x)≈⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡0⋮00⋮1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤k
这样,我们就把神经网络的多分类问题,转换成了类似逻辑回归的问题。
那么类似于逻辑回归的代价函数,我们只需要增加一个对 k 个结果的循环,即可得到神经网络的代价函数
J ( Θ ) = − 1 m ∑ i = 1 m ∑ k = 1 k [ y k ( i ) log ( h Θ ( x ( i ) ) ) k + ( 1 − y k ( i ) ) log ( 1 − ( h Θ ( x ( i ) ) ) k ) ] J(\Theta)=-\frac{1}{m}\sum_{i=1}^{m} \sum_{k=1}^{k} \left[y_{k}^{(i)} \log \left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}\right)\right] J(Θ)=−m1i=1∑mk=1∑k[yk(i)log(hΘ(x(i)))k+(1−yk(i))log(1−(hΘ(x(i)))k)]
呃,上面这个公式很复杂,复杂到我看着它都觉得累。而实际上,还有正规化(Regularization)部分没有加入。不过我们先不要在意这些细节,继续往下挖挖。
所谓反向传播,是和正向传播相对的。我们从输入值 X 一步步计算到输出值 y 的过程,就是正向传播的过程;反向反过来,就是反向传播。只是反向传播的是误差,不是输入值。
我们以一个四层神经网络为例,如下图所示。其中a1是输入层,a2/a3是两个隐藏层,a4是输出层。
a1 a2 a3 a4+-+a21+-+ +-+a31+-+ +-+a41| | | | |
a11+-+ |--a22--| |--a32--| |--a42| | | | |
a12+-+-+--a23--+---+--a33--+---+--a43| | | | |
a13+-+ |--a24--| |--a34--| +-+a44| | | | +-+a25+-+ +-+a35+-+
+-+a25+-+
随机初始化 Θ \Theta Θ,通过正向传播,我们可以求出预测的结果和实际值之间的误差,也即
δ ( 4 ) = a ( 4 ) − y \delta^{(4)} = a^{(4)} - y δ(4)=a(4)−y
然后利用这个误差值来计算前一层的误差:
δ ( 3 ) = ( Θ ( 3 ) ) T δ ( 4 ) ∗ g ′ ( z ( 3 ) ) \delta^{(3)} = \left(\Theta^{(3)}\right)^T \delta^{(4)} ∗ g′(z(3)) δ(3)=(Θ(3))Tδ(4)∗g′(z(3))
其中, ( Θ ( 3 ) ) T δ ( 4 ) (\Theta^{(3)})^T\delta^{(4)} (Θ(3))Tδ(4) 是权重导致的误差的和。类似的,我们可以继续计算前一层误差
δ ( 2 ) = ( Θ ( 2 ) ) T δ ( 2 ) ∗ g ′ ( z ( 2 ) ) \delta^{(2)} = (\Theta^{(2)})^T \delta^{(2)} ∗ g′(z^{(2)}) δ(2)=(Θ(2))Tδ(2)∗g′(z(2))
由此,我们就可以由后面一层的误差,传递到前面一层。
有了所有的误差的表达式后,便可以计算代价函数的偏导数了
∂ ∂ Θ i j ( l ) = a j ( l ) δ i l + 1 \frac{\partial}{\partial \Theta_{ij}^{(l)}} = a_j^{(l)}\delta_i^{l+1} ∂Θij(l)∂=aj(l)δil+1
有了偏导数,我们就可以用梯度下降的方法,逐步逼近求解出合适的 Θ ( i ) \Theta^{(i)} Θ(i) 了。
Θ ( i + 1 ) = Θ ( i ) − α i ∑ k = 1 N ∂ J k ∂ Θ k ( i ) \Theta^{(i+1)} = \Theta^{(i)} - \alpha_i \sum_{k=1}^N \frac{\partial J_k}{\partial \Theta_k^{(i)}} Θ(i+1)=Θ(i)−αik=1∑N∂Θk(i)∂Jk
有了权重,针对新的输入 X,我们就可以计算出相应的预测结果 y 了。
3. 实现
相对之前聊的线性回归和逻辑回归,神经网络是一种更为复杂的算法。向前传播求解、向后传播误差求参数是其核心思想。具体数学细节没有办法在一篇文章里面讲清楚,而且对于绝大多数人来说,也没有必要完全实现其背后的公式推导。对数学原理感兴趣的朋友可以参考文献 [2] ,里面有详细的公式推导和数学原理讲解。
另外,上面举例是用的分类算法,实际上神经网络也可以输出连续值。这种情况下输出单元就只有一个,最后一步采用回归即可。逻辑和原理与分类算法一样。
在实际应用中,除非为了练习,我们无需自己编写代码实现神经网络。现在已经有很成熟的软件包可以用。我们以 scikit learning 为例。
import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_splitdata = 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. 参考文献
- G. James, D. Witten, T. Hastie R. Tibshirani, An introduction to statistical learning: with applications in R. New York: Springer, 2013.
- T. Hastie, R. Tibshirani, J. H. Friedman, The elements of statistical learning: data mining, inference, and prediction, 2nd ed. New York, NY: Springer, 2009.
- W. Härdle, L. Simar, Applied multivariate statistical analysis, 3rd ed. Heidelberg ; New York: Springer, 2012.
这篇关于大火的神经网络到底是什么 | 机器学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!