神经网络

1.非线性假设

当我们使用线型回归或者逻辑回归的时候,有这样一个缺点,当特征太多的时候,计算的负荷会非常大。

下面是一个例子:

1541684546191

当我们使用 x1, x2的多次项式进行预测时,我们可以应用的很好。 使用非线性的多项式项,能够帮助我们建立更好的分类模型。假设我们有非常多的特征,例如大于100个变量,我们希望用这100个特征来构建一个非线性的多项式模型,结果将是数量非常惊人的特征组合,即便我们只采用两两特征的组合(x1x2 + x1x3 + x1x4 + …. + x99x100),,我们也会有接近5000个组合而成的特征。这对于一般的逻辑回归来说需要计算的特征太多了。

假设我们希望训练一个模型来识别视觉对象(例如识别一张图片上是否是一辆汽车),我们怎样才能这么做呢?一
种方法是我们利用很多汽车的图片和很多非汽车的图片,然后利用这些图片上一个个像素的值(饱和度或亮度)来
作为特征。
假如我们只选用灰度图片,每个像素则只有一个值(而非 RGB值),作为假设,我们可以选取图片上的两个不同位置上的两
个像素,然后训练一个逻辑回归算法利用这两个像素的值来判断图片上是否是汽车, 如下图所示:

1541684864817

假使我们采用的都是50x50像素的小图片,并且我们将所有的像素视为特征,则会有 2500个特征,如果我们要进一步将两两特征组合构成一个多项式模型,则会有约3百万个特征。普通的逻辑回归模型,不能有效地处理这么多的特征,这时候我们需要神经网络。

2.神经元和大脑介绍2

神经网络是一种很古老的算法,它最初产生的目的是制造能模拟大脑的机器。

神经网络逐渐兴起于二十世纪八九十年代,应用得非常广泛。但由于各种原因,在90年代的后期应用减少了。但是最近,神经网络又东山再起了。其中一个原因是:神经网络是计算量有些偏大的算法。然而大概由于近些年计算机的运行速度变快,才足以真正运行起大规模的神经网络。正是由于这个原因和其他一些我们后面会讨论到的技术因素,如今的神经网络对于许多应用来说是最先进的技术。当你想模拟大脑时,是指想制造出与人类大脑作用效果相同的机器。大脑可以学会去以看而不是听的方式处理图像,学会处理我们的触觉。我们能学习数学,学着做微积分,而且大脑能处理各种不同的令人惊奇的事情。似乎如果你想要模仿它,你得写很多不同的软件来模拟所有这些五花八门的奇妙的事情。不过能不能假设大脑做所有这些,不同事情的方法,不需要用上千个不同的程序去实现。相反的,大脑处理的方法,只需要一个单一的学习算法就可以了?尽管这只是一个假设,不过让我和你分享,一些这方面的证据。

1541685328783

大脑的这一部分这一小片红色区域是你的听觉皮层,你现在正在理解我的话,这靠的是耳朵。耳朵接收到声音信号,并把声音信号传递给你的听觉皮层,正因如此,你才能明白我的话。神经系统科学家做了下面这个有趣的实验,把耳朵到听觉皮层的神经切断。在这种情况下,将其重新接到一个动物的大脑上,这样从眼睛到视神经的信号最终将传到听觉皮层。如果这样做了。那么结果表明听觉皮层将会学会“看”。这里的“看”代表了我们所知道的每层含义。所以,如果你对动物这样做,那么动物就可以完成视觉辨别任务,它们可以看图像,并根据图像做出适当的决定。它们正是通过脑组织中的这个部分完成的。

下面再举另一个例子,这块红色的脑组织是你的躯体感觉皮层,这是你用来处理触觉的,如果你做一个和刚才类似的重接实验,那么躯体感觉皮层也能学会“看”。这个实验和其它一些类似的实验,被称为神经重接实验,从这个意义上说,如果人体有同一块脑组织可以处理光、声或触觉信号,那么也许存在一种学习算法,可以同时处理视觉、听觉和触觉,而不是需要运行上千个不同的程序,或者上千个不同的算法来做这些大脑所完成的成千上万的美好事情。也许我们需要做的就是找出一些近似的或实际的大脑学习算法,然后实现它大脑通过自学掌握如何处理这些不同类型的数据。在很大的程度上,可以猜想如果我们把几乎任何一种传感器接入到大脑的几乎任何一个部位的话,大脑就会学会处理它。
举几个例子:

1541685350471

这张图是用舌头学会“看”的一个例子。它的原理是:这实际上是一个名为BrainPort的系统,它现在正在FDA (美国食品和药物管理局)的临床试验阶段,它能帮助失明人士看见事物。它的原理是,你在前额上带一个灰度摄像头,面朝前,它就能获取你面前事物的低分辨率的灰度图像。你连一根线到舌头上安装的电极阵列上,那么每个像素都被映射到你舌头的某个位置上,可能电压值高的点对应一个暗像素电压值低的点。对应于亮像素,即使依靠它现在的功能,使用这种系统就能让你我在几十分钟里就学会用我们的舌头“看”东西。

第二个例子:

1541685371888

关于人体回声定位或者说人体声纳。你有两种方法可以实现:你可以弹响指,或者咂舌头。不过现在有失明人士,确实在学校里接受这样的培训,并学会解读从环境反弹回来的声波模式—这就是声纳。如果你搜索YouTube之后,就会发现有些视频讲述了一个令人称奇的孩子,他因为癌症眼球惨遭移除,虽然失去了眼球,但是通过打响指,他可以四处走动而不撞到任何东西,他能滑滑板,他可以将篮球投入篮框中。注意这是一个没有
眼球的孩子。

3.模型表示

神经网络模型表示

为了构建神经网络模型,我们需要首先思考大脑中的神经网络是怎样的?

每一个神经元都可以被认为是一个处理单元/神经核(processing unit/Nucleus),它含有许多输入/树突,并且有一个输出/轴突。神经网络是大量神经元相互链接并通过电脉冲来交流的一个网络。

下面是一组神经元的示意图,神经元利用微弱的电流进行沟通。这些弱电流也称作动作电位,其实就是一些微弱的电流。所以如果神经元想要传递一个消息,它就会就通过它的轴突,发送一段微弱电流给其他神经元,这就是轴突。

1541685477041

轴突是一条连接到输入神经,或者连接另一个神经元树突的神经,接下来这个神经元接收这条消息,做一些计算,它有可能会反过来将在轴突上的自己的消息传给其他神经元。这就是所有人类思考的模型:我们的神经元把自己的收到的消息进行计算,并向其他神经元传递消息。这也是我们的感觉和肌肉运转的原理。如果你想活动一块肌肉,就会触发一个神经元给你的肌肉发送脉冲,并引起你的肌肉收缩。如果一些感官:比如说眼睛想要给大脑传递一个消息,那么它就像这样发送电脉冲给大脑的。

1541685576582

神经网络模型建立在很多神经元之上,每一个神经元又是一个个学习模型。这些神经元(也叫激活单元,activation unit)采纳一些特征作为输出,并且根据本身的模型提供一个输出。下图是一个以逻辑回归模型作为自身学习模型的神经元示例,在神经网络中,参数又可被成为权重(weight)。

逻辑回归学习模型的神经元:

1541686908794

单个神经元的效果和逻辑回归的效果没有区别,但是神经网络会组成有神经元组成的网络。

一个简单的神经网络

1541687140133

其中 x1, x2, x3是输入单元(input units),我们将原始数据输入给它们。 a1, a2, a3是中间单元,代表三个神经元,它们负责将数据进行处理,然后呈递到下一层。 最后是输出单元,它负责计算 hθ(x)。
神经网络模型是许多逻辑单元按照不同层级组织起来的网络,每一层的输出变量都是下一层的输入变量。下图为一个3层的神经网络,第一层成为输入层(Input Layer),最后一层称为输出层(Output Layer),中间一层成为隐藏层(Hidden Layers)。我们为每一层都增加一个偏差单位(bias unit):

1541688086117

下面引入一些标记法来帮助描述模型: $a_i^{(j)}$代表第 j 层的第 i 个激活单元(神经元)。 $\theta^{(j)}$代表从第 j 层映射到第 j+1 层时的权重的矩阵,例如 $\theta^{(1)}$ 代表从第一层映射到第二层的权重的矩阵。其尺寸为:以第 j + 1 层的激活单元数量为行数,以第 j 层的激活单元数加一为列数的矩阵。例如:上图所示的神经网络中 $\theta^{(1)}$ 的尺寸为 3*4。

注: 每层权重矩阵的列数为 ( 神经元数 + 1 ), 行数为 ( 上一层神经元数 + 1 )

对于上图所示的模型,激活单元和输出分别表达为:

1541688405565

上面进行的讨论中只是将特征矩阵中的一行(一个训练实例)喂给了神经网络,我们需要将整个训练集都喂给我们的神经网络算法来学习模型

我们可以知道:每一个 a 的输出都是由上一层所有的 x 和每一个 x 所对应的 θ 决定的(我们把这样从左到右的算法称为前向传播算法( FORWARD PROPAGATION ))把 x , θ, a分别用矩阵表示:

1541689201260

神经网络模型向量化

( FORWARD PROPAGATION ) 相对于使用循环来编码,利用向量化的方法会使得计算更为简便。以上面的神经网络为例,试着计算第二层的值:

1541689568821

1541689589734

为了更好了了解Neuron Networks的工作原理,我们先把左半部分遮住:

1541689986501

右半部分其实就是以a0, a1, a2, a3 , 按照Logistic Regression的方式输出 hθ(x):

1541690041021

其实神经网络就像是logistic regression,只不过我们把logistic regression中的输入向量 [x1 - x3] 变成了中间层的 [ $a_1^{(2)}$ - $a_3^{(2)}$] ,我们可以把a0, a1, a2, a3看成更为高级的特征值,也就是x0, x1, x2, x3 的进化体,并且它们是由 x 与 θ 决定的,因为是梯度下降的,所以 a 是变化的,并且变得越来越厉害,所以这些更高级的特征值远比仅仅将 x 次方厉害,也能更好的预测新数据。 这就是神经网络相比于逻辑回归和线性回归的优势。

4. 特征的直观理解

从本质上讲,神经网络能够通过学习得出其自身的一系列特征。在普通的逻辑回归中,我们被限制为使用数据中的原始特征,我们虽然可以使用一些二项式项来组合这些特征,但是我们仍然受到这些原始特征的限制。在神经网络中,原始特征只是输入层,在我们上面三层的神经网络例子中,第三层也就是输出层做出的预测利用的是第二层的特征,而非输入层中的原始特征,我们可以认为第二层中的特征是神经网络通过学习后自己得出的一系列用于预测输出变量的新特征。

神经网络中,单层神经元(无中间层)的计算可用来表示逻辑运算,比如逻辑与(AND)、逻辑或(OR)。
举例说明:

逻辑与(AND):下图中左半部分是神经网络的设计与output层表达式,右边上部分是sigmod函数,下半部分是真值表。

其中 θ0 = -30, θ1 = 20, θ2 = 20 我们的输出函数hθ(x) 即为:hθ(x) = g(-30 + 20x1 + 20x2), g(x) 的图像是:

15416903999991541690413531

1541690578952

所以我们有:hθ(x) ≈ x1 AND x2

逻辑或(OR): 下图是神经网络的设计与output层表达式和真值表。

1541690859375

逻辑非(NOT):

1541690992427

异或(XNOR):

1541691150027

5.多分类神经网络

当我们有不止两种分类时(也就是 y = 1, 2, 3, … ),比如以下这种情况,该怎么办?

如果我们要训练一个神经网络算法来识别路人、汽车、摩托车和卡车,在输出层我们应该有4个值。例如,第一个值为1或0用于预测是否是行人,第二个值用于判断是否为汽车。
假如输入向量 x 有三个维度,两个中间层,输出层4个神经元分别用来表示4类,也就是每一个数据在输出层都会出现 [a b c d] ^T, 且a, b, c, d 中仅有一个为1,表示当前类。下面是该神经网络的可能结构示例:

1541691440767

6. 神经网络常用的激活函数

什么是激活函数

在神经网络中,我们经常可以看到对于某一个隐藏层的节点,该节点的激活值计算一般分为两步
  (1)输入该节点的值为 x1,x2时,在进入这个隐藏节点后,会先进行一个线性变换,计算出值 $z^{[1]}=w_1x_1+w_2x_2+b^{[1]}=W^{[1]}x+b^{[1]}$,上标 1表示第 1 层隐藏层。
  (2)再进行一个非线性变换,也就是经过非线性激活函数,计算出该节点的输出值(激活值) $a^{(1)}=g(z^{(1)})$ ,其中 g(z)为非线性函数。

1541914303454

常用的激活函数

在深度学习中,常用的激活函数主要有:sigmoid函数,tanh函数,ReLU函数

1.sigmoid函数

在逻辑回归中我们介绍过sigmoid函数,该函数是将取值为 (−∞,+∞)(−∞,+∞) 的数映射到 (0,1)(0,1) 之间。sigmoid函数的公式以及图形如下:

1541916961661

sigmoid激活函数缺点

(1)当 z 值非常大或者非常小时,通过上图我们可以看到,sigmoid函数的导数 g′(z) 将接近 0 。这会导致权重 W 的梯度将接近 0 ,使得梯度更新十分缓慢,即梯度消失

(2)函数的输出不是以0为均值,将不便于下层的计算。sigmoid函数可用在网络最后一层,作为输出层进行二分类,尽量不要使用在隐藏层。

(3) 指数计算消耗资源

2.tanh函数

 tanh函数相较于sigmoid函数要常见一些,该函数是将取值为 (−∞,+∞)(−∞,+∞) 的数映射到 (−1,1)(−1,1)之间,其公式与图形为:

1541917618607

tanh函数的优点

(1) tanh解决了sigmoid的输出非“零为中心”的问题。

tanh函数的缺点

(1)同sigmoid函数的第一个缺点一样,当 z 很大或很小时,g′(z) 接近于 0 ,会导致梯度很小,权重更新非常缓慢,即梯度消失问题

(2) 依旧是指数计算

3.ReLU函数

ReLU函数又称为修正线性单元(Rectified Linear Unit),是一种分段线性函数,其弥补了sigmoid函数以及tanh函数的梯度消失问题。ReLU函数的公式以及图形如下:

1541917904036

ReLU函数的优点
(1)在输入为正数的时候(对于大多数输入 zz 空间来说),不存在梯度消失问题。
(2) 计算速度要快很多。ReLU函数只有线性关系,不管是前向传播还是反向传播,都比sigmod和tanh要快很多。(sigmod和tanh要计算指数,计算速度会比较慢)
ReLU函数的缺点

(1)当输入为负时,梯度为0,会产生梯度消失问题。

4.Leaky ReLU 函数

这是一种对ReLU函数改进的函数,又称为PReLU函数,但其并不常用。其公式与图形如下:

1541918305822

Leaky ReLU函数解决了ReLU函数在输入为负的情况下产生的梯度消失问题

优点:

1.神经元不会出现死亡的情况。

2.对于所有的输入,不管是大于等于0还是小于0,神经元不会饱和。

3.由于Leaky ReLU线性、非饱和的形式,在SGD中能够快速收敛。

4.计算速度要快很多。Leaky ReLU函数只有线性关系,不需要指数计算,不管在前向传播还是反向传播,计算速度都比sigmoid和tanh快。

7.神经网络代价函数

假设神经网络的训练样本有 m 个,每个包含一组输入x 和一组输出信号 y ,L 表示神经网络层数,Si 表示每层的
neuron个数( Sl表示输出层神经元个数),SL 代表最后一层中处理单元的个数。

将神经网络的分类定义为两种情况:二类分类和多类分类,

二类分类: SL = 1, y = 0 or 1 表示哪一类;

K类分类: SL = k, yi = 1 表示分到第i类; (k > 2)

1542509643821

1542510435521

这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出 K 个预测,基本上我们可以利用循环,对每一行特征都预测 K 个不同结果,然后在利用循环在 K 个预测中选择可能性最高的一个,将其与 y 中的实际数据进行比较。
正则化的那一项只是排除了每一层 θ0 后,每一层的 θ 矩阵的和。最里层的循环 j 循环所有的行(由 sl +1 层的激活单元数决定),循环 i 则循环所有的列,由该层( sl 层)的激活单元数所决定。即:hθ(x) 与真实值之间的距离为每个样本-每个类输出的加和,对参数进行regularizationbias项处理所有参数的平方和。

8.反向传播算法

反向传播算法介绍

在计算神经网络预测结果的时候采用了正向传播的算法,即从第一层开始向正向一层的神经元一层一层进行计算,知道最后一层的hθ(x).

为了计算代价函数的偏导数${\delta\over\delta\theta_{ij}^{(i)}} J(\theta)$ , 现在需要用到反向传播算法,以极具是首先计算最后一层的误差,然后再一层一层的反向求出各层的误差,直到倒数第二层。下面举例说明反向传播算法:

假设我们的训练集只有一个实例(x^(1), y^(1)), 我们的神经网络是一个四层的神经网络,其中: K = 4, SL = 4, L = 4

其前向传播算法为:

1542511793330

反向传播算法推导过程

1542512354542

即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。

1542519045241

9. 模型构建常用技巧

1.梯度检验

1542520879656

2. 随机初始化

任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非0的数,结果也是一样的, 会导致梯度消失的情况。我们通常初始参数为正负ε之间的随机值,假设我们要随机初始一个尺寸为10×11的参数矩阵,代码如下:
Theta1 = rand(10, 11) * (2*eps) – ep

10. 梯度小时和梯度爆照

(1)简介梯度消失与梯度爆炸

层数比较多的神经网络模型在训练的时候会出现梯度消失(gradient vanishing problem)和梯度爆炸(gradient exploding problem)问题。梯度消失问题和梯度爆炸问题一般会随着网络层数的增加变得越来越明显。

例如,对于图1所示的含有3个隐藏层的神经网络,梯度消失问题发生时,靠近输出层的hidden layer 3的权值更新相对正常,但是靠近输入层的hidden layer1的权值更新会变得很慢,导致靠近输入层的隐藏层权值几乎不变,扔接近于初始化的权值。这就导致hidden layer 1 相当于只是一个映射层,对所有的输入做了一个函数映射,这时此深度神经网络的学习就等价于只有后几层的隐藏层网络在学习。梯度爆炸的情况是:当初始的权值过大,靠近输入层的hidden layer 1的权值变化比靠近输出层的hidden layer 3的权值变化更快,就会引起梯度爆炸的问题。

1542521622023

(2)梯度不稳定问题

在深度神经网络中的梯度是不稳定的,在靠近输入层的隐藏层中或会消失,或会爆炸。这种不稳定性才是深度神经网络中基于梯度学习的根本问题。

梯度不稳定的原因:前面层上的梯度是来自后面层上梯度的乘积。当存在过多的层时,就会出现梯度不稳定场景,比如梯度消失和梯度爆炸。

(3)产生梯度消失的根本原因

我们以图2的反向传播为例,假设每一层只有一个神经元且对于每一层都可以用公式1表示,其中σ为sigmoid函数,C表示的是代价函数,前一层的输出和后一层的输入关系如公式1所示。我们可以推导出公式2。

1542521637136

图2:简单的深度神经网络

1542521714489

而sigmoid函数的导数σ’(x)如图3所示。

1542521735544

图3:sigmoid函数导数图像

可见,σ’(x)的最大值为 1/4,而我们一般会使用标准方法来初始化网络权重,即使用一个均值为0标准差为1的高斯分布。因此,初始化的网络权值通常都小于1,从而有 |σ’(z)w <= 1/4|。对于2式的链式求导,层数越多,求导结果越小,最终导致梯度消失的情况出现。

1542521829814

(4)产生梯度爆炸的根本原因

1542521870103,也就是w比较大的情况。则前面的网络层比后面的网络层梯度变化更快,引起了梯度爆炸的问题。

(5)如何解决梯度消失和梯度爆炸

梯度消失和梯度爆炸问题都是因为网络太深,网络权值更新不稳定造成的,本质上是因为梯度反向传播中的连乘效应。对于更普遍的梯度消失问题,可以考虑以下三种方案解决:

  1. 用ReLU、Leaky ReLU、PReLU、RReLU、Maxout等替代sigmoid函数。
  2. 用Batch Normalization。
  3. LSTM的结构设计也可以改善RNN中的梯度消失问题。

11.构建神经网络的综合步骤

网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。
第一层的单元数即我们训练集的特征数量。
最后一层的单元数是我们训练集的结果的类的数量。
如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。
我们真正要决定的是隐藏层的层数和每个中间层的单元数。
训练神经网络:

  1. 参数的随机初始化

  2. 利用正向传播方法计算所有的hθ(x)

  3. 编写计算代价函数 J 的代码

  4. 利用反向传播方法计算所有偏导数

  5. 利用数值检验方法检验这些偏导数

  6. 使用优化算法来最小化代价函数

一句话总结神经网络

我认为神经网络就是通过各层神经元将变量的重新计算, 导致特征的维度被大大放大, 总之经过神经网络瞎搞之后,特征已不是简单的特征,而原理从根本还是逻辑回归,当特征数量较多,而且模型不能满足线型要求, 可以考虑使用神经网络

刘小恺(Kyle) wechat
如有疑问可联系博主