手记

30分钟讲清楚深度神经网络

这两年神经网络各种火。但对很多人而言,只是听着觉得各种高大上,究其本质,还是听不懂。下面我们花三十分钟把这个事情讲清楚。

神经网络算法是最早来源于某神经生理学家和某数学家联合发表的一篇论文,他们对人类神经运行规律的提出了一个猜想,并尝试给出一个建模来模拟人类神经元的运行规律。

神经网络一开始由于求解问题的不稳定,以及范围有限被抛弃。后面又在各个大神的努力下,对遇到的问题一个个解决,加上因为游戏带来的计算能力的提升获得了一个爆发式的增长。

下面我们讲讲神经网络是啥以及遇到的问题和探索出来的解决方案,最终我们给出一个深度神经网络的默认的最优配置项。

神经网络是啥

建立M个隐藏层,按顺序建立输入层跟隐藏层的联结,最后建立隐藏层跟输出层的联结。为每个隐藏层的每个节点选择激活函数。求解每个联结的权重和每个节点自带的bias值。参见下图。

nn示例.png

所谓激活函数就是对各个路径的输入求和之后进一步增强的函数
典型的有如下几个:

简单激活2.png

神经网络训练的本质

一题道出本质

下面这个图里面,是已知的各个联结线的权值,求y1, y2

nn题目.png

这个练习可以测试对神经网络的理解。

答案是 y1 = 46,   y2 = 0

其实就是权值乘以输入值加上偏差值之后,再通过激活函数对结果进行一次处理,得出的输出就是该节点最终的结果。

所以,Layer 1中的Neuron 1的值为 n1 = max(3 * 1 + 4 * (-1) + 9, 0) = 8。

Neuron 2的值为 n2 = max(3 * 2 + 4 * 0 + (-3), 0) = 3。

Layer 2中的Neuron 3 值为 n3 = max(n1 * 4 + n2 * 3 + 5, 0) = 46。

Neuron 4的值为 n4 = max(n1 * (-2) + n2 * 1 + 0, 0) = 0。

所谓神经网络问题的训练本质,就是已知 y1,y2....yn, 已知x1, x2....xm,求解每个连接的权值和每个神经元上的偏差值。对单层的激活函数为RELU的神经网络而言就是, y = max(sum(w * x)+b, 0),已知y和x,求解w和b。

训练的方法

对于以上求解w和b的值,科学家们发现可以通过反向传播和梯度下降相结合来求解。就是一开始用随机数初始化我们每个联结的权值,然后通过神经网络计算出来的y值跟真实的y值做比对。如果这个值相差比较大,则修改当前层的联结的权重。当发现这个值相差不大时,则修改更低一层的权重。这个步骤一直重复,逐步传递到第一层的权值

神经网络求解遇到的问题

三大问题:

  • 神经网络的原生问题:求解时会遇到梯度消失或者梯度爆炸

  • 性能,训练太慢

  • 过拟合

针对这三个问题,大拿们开始了一场探索之旅。

梯度消失或爆炸的解决方案

神经网络的求解是通过反向传播的技术来解决的。通过梯度下降法。问题是,反向传播从输出层开始一步一步传到Layer 1时,越到低层,联结的权值变化越小,直到没变化。这种叫梯度消失。还有一些呢?则是越到第一层,变化越来越大。这种叫梯度爆炸。常见于RNN。

解决方案探索如下:

  1. 联结权重的初始化放弃完全随机的方式,而是要使用特定的标准差。有He initialization和Xavier initialization

  2. 使用ReLU作为激活函数。后面发现ReLU里面某些神经元会变成0(Dying ReLU的问题),这个时候又演化出 LReLU,RReLU和PReLU以及ELU这些变种。一般来说,激活函数的选择优先顺序有 ELU > leaky ReLu(包括LReLU,RReLU,PReLU) > ReLU > tanh > sigmoid

  3. Batch Normalization。就是在每层都对输入的X进行转化,变成以0为中心的分布。最终求解同时要求出每层用来scale的参数应该是多少。

  4. Gradient Clipping。就是在反向传播的过程中限制梯度不超过某个阈值。如果超过就减去相应的阈值。

目前来说,通常用1+2 多于 3 多于 4。就是现在一般使用He initialization跟ReLU的演进版本作为作为激活函数来解决梯度消失和爆炸的问题,其次才使用Batch Normalization,最后使用Gradient Clipping。

性能问题的解决方案

通常来说,我们很难获得足够的标记好的训练数据。常用解决方案如下:

  1. 复用已有的训练好的网络。通常可以找到已经训练好的模型的地方有 tensorflow的github  caffe的github

  2. unsupervised pretraining。对无标签的训练数据,直接运行类似于autoencoders之类的算法。这种算法类似于聚类,可以提取出输入数据里面较为核心的特征出来。通过这样一步一步生成每一个隐藏层。最后再用有标签的数据来训练最终的网络。

对于大规模数据的训练,很多时候速度很慢。除了解决梯度消失或爆炸的问题之外,还有使用AdamOptimizer替代GradientDescentOptimizer会大大加快收敛速度

过拟合的解决方案

  1. early stopping。一旦发现在验证集合上性能下降,立即停止训练

  2. 在cost function上添加L1 L2 Regularization。所谓L1 L2的Regularization就是添加对模型复杂度的惩罚项。模型用到的联结线权值越大,惩罚越大。这样模型的优化目标就不仅仅是要预测偏差尽量小,同时还要预测所使用的模型尽量简单。

  3. 使用Dropout。就是每次随机选择一些神经元不参与训练,只有在预测的时候这些神经元才生效。这个神经元的输出结果要乘以一个概率值。降低贡献。其实这种就有点类似于降低了神经元之间的依赖性。原来是每个联结的神经元都参与计算的。现在是随机失效了。这种技术竟然可以稳定的为神经网络的能力提升2%!

  4. max-norm regularization。就是限制每个神经元的联结的weight的 l2 Regularization在一个阈值内。

  5. 数据补充。其实就是对已有的训练数据做一定的变换,用来做训练。提升模型泛化能力

一个神经网络的默认最优配置

InitializationActivation functionNormalizationRegularizationOptimizer
He InitializationELUBatch NormalizationDropoutAdamOptimizer

我们后面会教大家用tensorflow构造出一个神经网络并求解。



作者:墨家钜子
链接:https://www.jianshu.com/p/daf5b4f0238c


0人推荐
随时随地看视频
慕课网APP