最基础的神经网络与反向传播

算法原理

概述:
算法通过构建多层网络解决单层感知机的非线性可分无法分割问题,通过梯度下降法更新网络中的各个权值向量,使得全局的损失函数极小化,从而实现对任意复杂的函数的拟合,这在分类问题中表现为它能将任意复杂的数据划分开,在回归问题中表现为它能拟合任意复杂的回归函数
其中梯度下降的核心是误差反向传播算法,这个算法大大减少了梯度下降法的计算量,是多层神经网络得以复苏的功臣,它使得当前层的梯度项能往后一层传播,从而快速求得后一层的梯度

问题1:神经网络是如何解决非线性可分无法分割问题的?
pla模型可以看做是神经网络的一个神经元,我们知道,pla能对数据空间划分一个超平面,简单的实现分类任务。但是pla这种只会切一刀的模型无法解决异或问题。
而神经网路可以通过增加一个2节点的隐藏层,就相当于是放置了两个pla,这两个pla互相独立,各自能在数据空间划分一个超平面,对于异或问题,它们将二维空间划分为3到4个平面(图2的A、B、C、D四个平面),然后隐藏层到输出层再对这些平面做一次分割将其分成两类(图3的橙色与蓝色),从而解决了非线性可分的异或问题

问题2:如何理解神经网络强大的拟合能力?
说真的,我觉得神经网络比决策树抽象太多了,不容易理解,下面只是我的一些肤浅的认识
对于分类问题,用空间切割的思想进行理解,通过上述异或问题的例子我们看到,通过增加节点数,神经网络能将输入数据的空间划分成任意多的子空间,从而能对任意复杂的数据划分开,例如下图1可以经过划分将不同标签划分开(图2)

对于回归问题,用数据空间变换的思想进行理解

  • 权值向量对输入数据的空间的不同维度执行了放大缩小的操作
  • 其偏置值对数据空间进行了平移
  • 求和函数与不同层的节点数差异对空间进行了降维与升维
  • 非线性激活函数对空间进行扭曲
    通过这些操作的不同组合,就能将变换后的数据拟合标签值y,因为这些操作的组合就能任意变换数据空间,也就能拟合任意复杂的函数了

问题3:反向传播算法如何进行?
考虑下图所示的一个简单的神经网络,其中的权值向量等符号也在图中定义,这里先不考虑偏置

神经网络示例

现在计算该模型在 这个训练样本上的损失以及对应上图蓝色线和红色线的反向传播更新的梯度和
我们定义对这个样本的损失是模型预测值与原来的的均方误差,因此很明显这个误差就是我们在这个样本上想要极小化的损失函数

重复一下,我们想要更新的是两个权值(w和h),因此根据梯度下降法我们需要求这两个权值对上述的损失函数的梯度,然后根据求得的梯度对权值本身进行更新

  • 损失函数对w_j求偏导,需要运用到链式求导的定律
    从中定义一个g

  • 损失函数对v_ih求偏导,同样需要运用到链式求导的定律
    由于sigmoid函数导数的有这样的性质
    根据上述①②两式,可得结果如下,这里的g就是上一层求导产生的g
    基于上述的求偏导,就能对权值进行更新,注意这里只对权值的一维进行演示,我们对权值的每一维执行上述计算就可以得到梯度,然后更新,这样一轮结束

关键代码截图(带注释)

image.png

思考题

1. 尝试说明下其他激活函数的优缺点?

  • tanh函数
  1. (优点)在0附近的时候其梯度更大,最大值是sigmoid函数的4倍,因此当数据已经预处理成在0附近的时候使用tanh的话梯度能下降更快,下图是sigmoid和tanh的导数函数对比图


    tanh
  2. (优点)其输出是0均值的,这个我不是很懂,看了很多博客都没具体展开,最终找到一篇论文专门讨论了tanh函数的优点,由于时间有限这次没法认真研究,罗列在此,以供日后钻研--- Efficient Backprop by LeCun
  3. (缺点)它虽然比sigmoid函数好,但是有一个sigmoid的缺点它还是存在,就是饱和区太大(或说非饱和区太小),从上面的图也可以看到,当|x|大于2的时候,就基本上等于0了。这会导致很多问题,例如数据需要精心预处理才不会一下子进入饱和区,又例如深层网络中的梯度消失问题
  • ReLU函数
  1. (优点)可以用于解决深层网络中的梯度消失问题(这在第3个问题中解释)
  2. (优点)导数或0或1,不需要复杂的求导过程,极大减少了运算量
  3. (缺点)由于ReLu会使得一部分神经元不可逆的“死亡”,可能会导致网络能学到的知识减少(注:这个点我不是很懂为什么节点死亡就一定不好)
  4. 为了解决ReLu的不可逆“死亡”的问题,提出一种激活函数为Leaky ReLU,它在x<0 时,给出一个很小的负数梯度值,这样使得该节点还能有机会“复活”,理论上我觉得Leaky ReLU是会优于ReLU的

2. 有什么方法可以实现传递过程中不激活所有节点?
答:使用reLu函数会使得有些节点直接死掉,死掉的节点输出0梯度也0,梯度0就无法更新因此死掉的节点是不可逆的,也就永远不激活了

3. 梯度消失和梯度爆炸是什么?可以怎么解决?

答:

当神经网络层数增加的时候,离输入层越近的层它的梯度将是它之前的层的激活函数导数和权值的积的连乘

关于梯度消失和梯度爆炸,很多博客(例如这篇),都是使用下图这个简单的深层神经网络为例子,这里同样使用这个网络进行分析,这里的C是网络的输出

根据反向传播算法在计算梯度时的链式求导法则,很容易求得

可以看到,是各个层的的连乘,这就很容易导致问题

  1. 如果小于1的话,那么连乘的数量越多的时候,乘积将会一直一直的减少,甚至导致乘积直接变成0,这也就是梯度消失了
  2. 如果大于1的话,那么连乘的数量越多的时候,乘积将会一直一直的增大,而且是指数增大,这也就是梯度爆炸了

对于sigmoid函数作为激活函数的网络而言,由于sigmoid函数导数自身的性质(见下)以及w与之间的相互关系(见下),使得大多数情况是梯度消失

  1. 最大值是0.25,而且在饱和区几乎是0
  2. 小的时候较大,当大的时候又接近于0

解决方法:

  • 对于梯度消失的问题,更多的是改用relu作为激活函数,因为它在x>0的时候导数是一直为1的,能一定程度解决梯度消失
  • 对于梯度爆炸问题,可以采用设置梯度阈值的方法,当梯度大于这个阈值的时候就直接将梯度设置成阈值

你可能感兴趣的:(最基础的神经网络与反向传播)