神经网络中容易被忽视的基础知识
米乐体育直播

  以下大多笔记大多数来源于 cs231n 和其他深度学习资料和一些我自己的补充,首先 CS231n 一个相当的好的 deep learning 课,值得一看,奉上链接,然后,cs231n 本身是有笔记的-链接,最后,知乎上的一些大神对这个笔记进行了翻译-链接。在这里,我主要是将一些重要的笔记,我认为是非常容易被我们忽视的,加上查阅其他博文,做一个笔记和心得总结!

  下面图表的左边展示了一个生物学的神经元,右边展示了一个常用的数学模型。乍一看还是有点相似的,事实上也是,人工神经网络中的神经元也有受到生物神经元的启发。总结要点:

  在生物的神经元(也就是左图)中,树突将信号传递到细胞体,信号在细胞体中相加。如果最终之和高于某个阈值,那么神经元将会激活,向其轴突输出一个峰值信号,注意这里输出是一个脉冲信号!

  在数学计算模型(也就是右图)中,首先将输入进行加权求和加上偏执,得到待激励值,然后将该值作为输入,输入到激活函数中,最后输出的是一个激励后的值,这里的激活函数能看成对生物中神经元的激活率建模。由于历史原因,激活函数常常选择使用sigmoid 函数 σ并还有很多其他激活函数,下面再仔细聊!

  需要注意:1. 一个神经元可以看成包含两个部分,一个是对输入的加权求和加上偏置,一个是激活函数对求和后的激活或者抑制。2. 注意生物中的神经元要复杂的多,其中一个是生物中的输出是一个脉冲,而现在大多数的数学模型神经输出的就是一个值,当然现在也有一些脉冲人工神经网络,能自行了解!

  比如基础的逻辑回归,结合上面的神经元知识,不难发现,逻辑回归就是激活函数是sigmoid的单层简单神经网络。也就是说,只要在神经元的输出端有一个合适的损失函数,就能让单个神经元变成一个线性分类器。因此说,那些线性的分类器本身就是一个单层神经网络。

  但注意,对于非线性的模型:SVM 和神经网络走了两条不同的道路:神经网络通过多个隐层的方法来实现非线性的函数,有一些理论支持(比如说带隐层的神经网络可以模拟任何函数),但是目前而言还不是非常完备;SVM 则采用了 kernel trick 的方法,这个在理论上面比较完备(RKHS,简单地说就是一个泛函的线性空间)。两者各有好坏,神经网络最近的好处是网络设计可以很灵活,有很多的 trick&tip,很多理论都不清不楚的;SVM 的理论的确漂亮,但是 kernel 设计不是那么容易,所以最近也就没那么热了。

  “肥胖” 网络的隐藏层数较少,如上左图。虽然有研究表明,浅而肥的网络也可以拟合任何的函数,但它需要非常的 “肥胖”,可能一层就要成千上万个神经元。而这直接引发的后果是参数的数量增加到很多很多。

  也有实验表明,也就是上图的实验,我们大家可以清楚的看出,当准确率差不多的时候,参数的数量却相差数倍。这也说明我们一般用深层的神经网络而不是浅层 “肥胖” 的网络。

  注意:说神经网络多少层数的时候一般不包括输入层。 在神经网络中的激活主要讲的是梯度的更新的激活。

  上图可看做普通的线性分类器,也就是线性回归方程。这个比较基础,效果如右图。当然有时候我们得知这样的线性分类器不符合我们要求时,我们很自然的想到那我们就加多一层,这样做才能够拟合更为复杂的函数,如下图 a:

  但同时当我们动笔算下, 就会发现, 这样一个神经网络组合起来, 输出的时候无论如何都还是一个线性方程。如上图 b 右边,就只能这样分类。(那也太蠢了吧)。下图表示一层加如激活函数的情况!

  一层很多时候是远远不足的,前面讲过,简单的线性分类器就可以看成是一层的神经网络,比如上图,激活函数是 signmoid,那就可以看成是二分类的逻辑回归!

  图 1 是一个简单的 MLP(全链接神经网络),图 2 的右边课简单表示左图的可视化,那么对比之前的无激活函数的图,很明显是更加的非线性,拟合能力也会更强,同时能想到,当层数更多,其能力也会慢慢的强!

  简单来说:就是使得神经网络具有的拟合非线性函数的能力,使得其具有强大的表达能力!

  简单扩展,神经网络的万能近似定理: 一个前馈神经网络如果具有线性层和至少一层具有 挤压 性质的激活函数(如 signmoid 等),给定网络足够数量的隐藏单元,它可以以任意精度来近似任何从一个有限维空间到另一个有限维空间的 borel 可测函数。

  要相符上面的定理,也就是想拟合任意函数,一个必须点是 “要有带有 “挤压” 性质的激活函数”。这里的 “挤压” 性质是因为早期对神经网络的研究用的是sigmoid类函数,所以对其数学性质的研究也主要基于这一类性质:将输入数值范围挤压到一定的输出数值范围。(后来发现,其他性质的激活函数也可以使得网络具有普适近似器的性质,如 ReLU 。

  缺点:1.Sigmoid 函数饱和使梯度消失。sigmoid 神经元有一个不好的特性,就是当神经元的激活在接近 0 或 1 处时会饱和:在这些区域,梯度几乎为 0。2.输出不是零中心的,这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数,那么关于 w 的梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数,这样梯度下降权重更新时出现 z 字型的下降。这样收敛会变得异常的慢。(这也是怎么回事要一直保持为数据的 0 中心化)—–但这样的一个问题比较小。3.exp()在深度神经网络时候相比其他运算就比较慢。

  优点:它的输出是零中心的。因此,在真实的操作中,tanh 非线性函数比 sigmoid 非线性函数更受欢迎。

  优点:1.ReLU 对于随机梯度下降的收敛有巨大的加速作用( Krizhevsky 等的论文 alexnet 指出有 6 倍之多)。据称这是由它的线性,非饱和的公式导致的;2.注意:现在大部分的 DNN 用的激活函数就是 ReLu

  缺点:当 x 是小于 0 的时候,那么从此所以流过这个神经元的梯度将都变成 0;这样一个时间段这个 ReLU 单元在训练中将死亡(也就是参数无法更新),这也导致了数据多样化的丢失(因为数据一旦使得梯度为 0,也就说明这一些数据已不起作用)。

  缺点:1. 有些研究者的论文指出这个激活函数表现很不错,但是其效果并不是很稳定

  Kaiming He 等人在 2015 年发布的论文 Delving Deep into Rectifiers 中介绍了一种新方法 PReLU,把负区间上的斜率当做每个神经元中的一个参数。然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。

  优点:拥有 ReLU 单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的 ReLU 单元)。

  缺点 :每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。难训练, 容易过拟合。

  “那么该用那种呢?”用 ReLU 非线性函数。注意设置好学习率,(如果学习率设置得太高,可能会发现网络中 40% 的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这样的一种情况的发生概率会降低。),解决方案:或许可以监控你的网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试 Leaky ReLU 或者 Maxout,不要再用 sigmoid 了。也能试试 tanh,但是其效果应该不如 ReLU 或者 Maxout。

  注意这里的阈值, 它度量了神经元产生正 (负) 激励的难易程度。也就是说,在上文的模型中,阈值越大, 产生正激励的难度越大。

  同时对于偏置必须要格外注意的点是:偏置是不需要正则化的,并且正则化偏置的话会导致欠拟合。我们从意义上去理解话,若对偏置正则化(惩罚),会导致激活变得更简单,偏差就会上升,学习的能力就会下降!

  我们前面说过:线性分类器逻辑回归模型可以算作为一个简单的单层神经网络。为了更好的说明问题,假设一个场景,在十类分类的数字手写识别中,我们将本来二分类的逻辑回归推到多分类的softmax,也就是说,神经元的激活函数是 softmax。也就是下图,然后分析:

  输入层(不算是一层):28×28=784 个输入单元。也就是 n=784

  它由两组参数组成:W和 b, 前者是一个 10×784 维的权值矩阵, 后者是长度为 10 的 bias 列向量. 现在我们假设把它们全部初始化为 0:

  由于 w 值已经变得不相同了,这样一个时间段前向传播和后向传播也就会正常的进行, 后面的训练显然也可以顺利进行。

  如果有隐层呢? 假如还是用sigmoid 激活函数呢。来个更简单 MLP,

  第一次正向计算过程中, 简单算出,输出层的所有输出为神经元 4,5,6 输出的值(初始化 w,b 为 0, 激活函数是sigmoid)都是一样的,都是 0.5

  然后第二次正向时,算出神经元 4,5 的输出一样(因为 4,5 都是接受 1,2,3 神经元的输入,且权重相同),但和神经元 6 的输出不一样。

  然后第二次反向时,根据公式,得出神经元 4,5 永远一样。原因主要在于计算用的是一样的输出,这个也可以从公式得出!

  最后结论,一直循环,发现学习得到的模型中, 所有的隐单元都是相同的(在这里就是神经元 4,5 永远一样). 学习失败。

  对于隐层使用了其他函数比如 ReLU:f(net)=max(0,net)其结果是相同的: 除了输入层的输出值为x本身, 不为 0, 其余的所有层的输出都为 0. BP 时所有梯度也都为 0, 包括输出层. 这在某种程度上预示着所有的非输入神经元都是无意义的. 学习失败.对于卷积神经网络,循环神经网络是相同的,故一般会用其他初始化方式。

  最后最后的结论是,一般只在训练 SLP / 逻辑回归模型时才使用 0 初始化所有参数., 更实用的结论是, 深度模型都不会使用 0 初始化所有参数.

  一个很常见的,很美的成本函数是 “交叉熵”(cross-entropy)。交叉熵产生于信息论里面的信息压缩编码技术,但是它后来演变成为从博弈论到机器学习等其他领域里的重要技术方法。它的定义如下:

  1. 交叉熵是正的,2. 当所有输入 x 的输出都能接近期望输出 y 的话,交叉熵的值将会接近 0。这两个特征在直觉上我们都会觉得它适合做代价函数。事实上,我们的均方代价函数也同时满足这两个特征。然而....

  a 是 神经元的输出,其中 a = σ(z), z = wx + b,可知,偏导数受激活函数的导数影响,假设这里是传统的sigmoid 激活函数(在之前很多时候都是)。那么 sigmoid 的导数在输出接近 0 和 1 的时候 是非常小的,这会导致一些实例在刚开始训练时学习得非常慢!

  由以上公式可知,权重学习的速度受到 σ(z) − y 影响,更大的误差,就有更快的学习速度,还避免了二次代价函数方程中因 σ′(z) 导致的学习缓慢。

  但是现在也有很多其他的激活函数并不可能会产生饱和状态,那么均方差也有其存在价值。