>
Home

登龙(DLonng)

选择大于努力

从 0 开始机器学习 - 深入浅出神经网络基础


版权声明:本文为 DLonng 原创文章,可以随意转载,但必须在明确位置注明出处!

今天跟大家分享下我学习神经网络的一些个人总结,希望能通过这篇博客帮助新手直接搞懂神经网络!

一、神经网络解决什么问题?

之前跟大家分享过多项式回归预测房价逻辑回归分类数据的例子,在这两个问题中我们假设问题的输入特征很少:

  • 预测房价的输入特征:卧室数量、房屋面积、房屋楼层
  • 逻辑回归分类数据的输入特征:2 类数据,即 2 分类问题

在预测房价的例子中,我们的假设函数有 3 个输入特征:

\[h_\theta(x) = \theta_0x_0 + \theta_1x_1 + \theta_2x_2 +\theta_3x_3\]

可是在实际的机器学习应用中,要解决的问题通常有很多很多特征(比如图像有上百万个像素点作为输入特征),这时假设函数就变为非常复杂的非线性函数:

\[h_\theta(x) = \theta_0x_0 + \theta_1x_1 + \theta_2x_2 + \theta_3x_1x_2 + \theta_4x_1x_3 + ... \theta_nx_1x_n + ...\]

这种类型的非线性假设函数组合的特征会非常多,以至于用普通的线性回归和逻辑回归算法计算会很慢,效率低下,所以为了解决复杂的非线性问题,科学家们设计出了神经网络。

神经网络的作用就是在在保证计算效率的前提下解决复杂的、有非常多输入特征的非线性问题,这包括分类问题和回归问题,比如预测一个图像中动物的类别是猫还是狗,对于人来说很容易,可是要让机器像人一样识别猫狗可不容易,而神经网络就具备这种识别能力,是不是很神奇呢?

下面就来正式学习神经网络的基础,登龙带你由浅入深一步一步推导,非常容易,千万不要被网络结构图吓到哈 = =!

二、神经元模型

2.1 大脑中的神经元

在学习神经网络之前,先来看看单个神经元是如何工作的。在生物课上,我们知道人类的大脑中含有处理信息的神经网络,而神经网络又是由非常多单个神经元连接而成,每个神经元可以看做是一个单独的处理单元,单个神经元结构图如下:

那么既然是处理单元,肯定有输入和输出,所以科学家们给神经元结构做了如下定义:

  • 树突(数据输入):每个神经元通过树突来接收一个或多个其他神经元的轴突输出
  • 轴突(数据输出):每个神经元的轴突能输出信息,来作为另一个神经元的树突输入

在神经元之间数据的传递是通过微弱的电流,术语叫「动作电位」来传递的,这里就不展开解释了,关于单个神经元了解这些足够了,接着来看下机器学习中的神经元是怎样定义的。

2.2 人工神经元模型(感知器)

科学家们通过模拟人脑中的神经元结构,设计出了能在计算机中表示的单个人工神经元,结构如下:

我来解释下这个结构:

  • $x_1 … x_3$ :神经元的输入,类似人脑神经元的树突
  • $x_0 = 1$:人为加上的偏置单元,值是常数,以后会介绍它的作用
  • $w_0 … w_3$:偏置单元和输入单元的权重值,可以理解为人脑神经元之间「动作电位」传递对当前神经元的影响大小
  • $sum$:对输入值和权重做加权求和,可以理解为人脑神经元对所有的树突传来的信息做加权处理
  • $g(x)$:激活函数,用来确定该神经元的输出,相当于人脑神经元的细胞核来决定产生什么信息输出到轴突上

可以看出人工设计的神经元基本就是模仿了人脑神经元的结构,只不过多了一个偏置单元 $x_0$,为了简化表示,我们通常把 $sum$ 和 $g(x)$ 这两步放在一起处理,逻辑不变,只是改变了结构图,方便画图表示:

结构定义好了之后,就要用程序来把这个神经元写出来,如果把这些变量和权重挨个定义一遍再做运算,那会非常麻烦,因为你的输入参数可能会非常多,导致运算速度也会降低,所以科学家们把上面的神经元用向量表示出来,方便计算机运算:

  • $w$ 定义为行向量:$w = [w_1 \ w_2 \ w_3]$
  • $x$ 定义为列向量:$x = [x_1 \ x_2 \ x_3]^T$

这样 $w * x$ 就可以等价于加权求和了:

注意这里没有把偏置单元 $x_0 = 1$ 加上,因为它不作为输入特征,我们单独加上 $x_0w_0 = 1 * w_0$,这样就跟单独计算等价了:

\[wx + 1 * w_0 = x_0w_0 + x_1w_1 + x_2w_2 + x_3w_3\]

然后再作为激活函数 $g$ 的输入,得到输出 $z$:

\[z = g(wx + 1 * w_0)\]

这样就用向量表示了单个神经元的计算,是不是很容易呀,要时刻注意 $x_0 = 1$ 哦!

三、两层神经网络

3.1 大脑中的两层神经网络

这是大脑中 2 个神经元的连接图:

可以看到:

  • 上面神经元的轴突(输出)连接到下面神经元的树突(输入)
  • 一个神经元可以有多个树突接收不同输入
  • 一个神经元也可以有多个轴突产生输出

根据这个生物连接,科学家设计出了经典的 2 层神经网络。

3.2 两层人工神经网络

这是 2 层神经网络从下到上的结构:

还有一种从左到右的结构:

我更习惯用从左到右的结构:

  • 输入层:最左边的一层,相当于多个树突
  • 中间层(隐藏层):产生更高级的特征,传递到下一层
  • 输出层:最右边的一层相当于轴突,实际上可以有多个输出
  • 偏置单元:除了最后的输出层,前面的每一层都加一个偏置单元($x_0$ 和 $a_0^{(2)}$)

同样我们也需要用向量化公式计算这个网络的输出,不过因为这个网络变量较多,所以我们先来定义以下符号的表示:

  • $a_i^{(j)}$:代表第 $j$ 层的第 $i$ 个激活单元,比如 $a_2^{(2)}$ 为第二层第二个激活单元
  • $W^{(j)}$:表示第 $j$ 层传递到下一层即 $j + 1$ 层的权重矩阵,行数为 $j + 1$ 层激活单元(不包含偏置)数量,列数为第 $j$ 层激活单元(包含偏置)数量,比如 $W^{(1)}$ 大小为 3($a_1^{(2)} -> a_3^{(2)}$) X 4($x_0 -> x_3$)
  • $W_{ij}^{(j)}$:权重矩阵的单个元素,比如 $W_{10}^{(1)}$ 表示第 1 层到第二层的权重矩阵中第一个元素,这个矩阵后面会带着大家写出来

符号定好之后,就可以按照单个神经元的加权求和的方法写出中间层每个单元的计算公式,我们直接在中间层的节点上写出当前神经元的输出 $a_i^{(2)}$,注意 $a_0^{(2)}$ 是偏置单元,不连接上一层的输出:

\[a_1^{(2)} = g(W_{10}^{(1)}x_0 + W_{11}^{(1)}x_1 + W_{12}^{(1)}x_2 + W_{13}^{(1)}x_3)\]

\[a_2^{(2)} = g(W_{20}^{(1)}x_0 + W_{21}^{(1)}x_1 + W_{22}^{(1)}x_2 + W_{23}^{(1)}x_3)\]

\[a_3^{(2)} = g(W_{30}^{(1)}x_0 + W_{31}^{(1)}x_1 + W_{32}^{(1)}x_2 + W_{33}^{(1)}x_3)\]

我们来用向量把上面的公式组合起来方便算法计算:

通过向量化表示,最后用一个向量公式就可以计算所有中间节点的输出:

\[a^{(2)} = g(W^{(1)}x)\]

这个公式可以解释两层之间的数据传递:

  • $x$:表示上一层所有神经元的输出(轴突)作为当前层的输入(树突)
  • $W^{(1)}$:表示上一层连接到当前层的权重矩阵(类似细胞核要传递的信息)
  • $a^{(2)}$:表示当前层所有神经元的输出(类似轴突)

可以看到第二层的每个神经元的值都与第一层所有神经元输出有关。相应地输出层计算公式也类似,要注意输出层只有一个节点哦,所以 $W^{(2)}$ 是 1 X 3 大小:

\[h_\theta(x) = g(W_{10}^{(2)}a_0^{(2)} + W_{11}^{(2)}a_1^{(2)} + W_{12}^{(2)}a_2^{(2)} + W_{13}^{(2)}a_3^{(2)})\]

建议你也手动计算下:

把权重标在网络上帮助你更好的理解:

明白了的童鞋扣个 6,以上的过程建议自己在草稿纸上推导一遍,加深理解。

四、多层神经网络 - 深度学习

你肯定听过深度学习这 4 个字,自从阿尔法狗之后突然火热起来,其实深度学习本质上就是很多层的神经网络,通过增加网络层数来增加网络的表示能力,以此完成很多类似人脑的功能,比如图像领域的目标检测,语义分割等。

以下是一个目标检测的深度网络,本质上还是神经网络,多层神经网络每层的节点数设计原则如下:

  • 输入层节点数:固定为输入特征数量
  • 中间的每个隐藏层节点数:根据经验确定
  • 输出层节点数:根据问题的输出确定

其他的原理就不详细介绍了,以后会学习的:

五、神经网络如何处理多分类问题?

前面的 2 层神经网络的输出层只有一个节点,所以只能输出 2 分类问题(0 代表 猫,1 代表狗),其实神经网络也可以处理多分类问题,只需要在网络的输出层增加节点即可,就像大脑神经元也可以有多个轴突输出一样。

输出层有多个节点的网络结构如下:

其中每个节点都可以代表一种类型,比如:猫、狗、老虎、狮子,这样就实现了多分类功能,是不是很巧妙,简直完美。

六、如何理解神经网络?

5.1 转换高级特征

如果我们把 2 层神经网络的输入层去掉,如下图:

会发现网络的输出就是逻辑回归的计算方法:

\[h_\theta(x) = g(W_{10}^{(2)}a_0^{(2)} + W_{11}^{(2)}a_1^{(2)} + W_{12}^{(2)}a_2^{(2)} + W_{13}^{(2)}a_3^{(2)})\]

只不过把逻辑回归的输入由输入特征 $x_i$ 换为中间层的 $a_i$,这些 $a_i$ 可以理解为比输入特征 $x_i$ 更加高级的特征,如果后面还有网络层那么输出的就是更加高级的特征,这样层层递进,最后网络对这些高级的特征进行分类处理,输出最后的结构,典型的应用就是图像的目标检测。

5.2 神经网络的本质

通过上面的学习我们已经知道了神经网络的结构和单个神经元的计算方法,可是你有没有疑惑?我们到底在计算什么东西,这些节点的值有没有实际的意义呢?为什么这个神经网络可以模拟我们的大脑?

这里我谈下我的理解,多层神经网络的本质就是用来拟合非常复杂的函数,函数复杂到可以有成千上万个 $x$,上面的 2 层神经网络就可以无限逼近任意的连续函数,因为我们设计人工神经网络是为了模拟人脑,可是计算机只能做数学运算,因此我们要把人脑神经元的思考过程转化为计算机算法中的函数,这个转换的函数可能简单可能复杂,要根据实际的问题类型。

对于复杂的问题,比如识别图像中的小猫小狗,这个转换的函数就难以描述,而我们的神经网络是受到人脑生物神经元的启发设计的,它的结构就可以从理论上模拟任意连续的复杂函数,以解决复杂的机器学习问题。

别看上面的神经网络很多节点,其实这些节点并不重要,重要的是连接每层节点的权重 $W$,我们训练神经网络的过程就是调整这些连接权重,把这些权重调层最优,最后的网络输出效果就会好(识别猫狗的正确率高)。

记住:训练神经网络或者深度网络就是训练节点之间的连接权值!

这次就分享这些,有任何问题都可以关注下面的公众号给我留言,大家下期再见(^▽^)!

本文原创首发于微信公号「登龙」,分享机器学习、算法编程、Python、机器人技术等原创文章,扫码即可关注

DLonng at 05/06/20