干货 | 算法工程师入门第一期――罗恒讲深度学习互联网+

雷锋网 2017-07-14 20:55
分享到:
导读

大量的研究人员使用BP算法训练神经网络,由于神经网络是优化一个非线性函数,但当时人们认为多层神经网络优化困难。

雷锋网(公众号:雷锋网)按:本文为大牛讲堂算法工程师入门课程第一篇。地平线资深算法工程师罗恒、穆黎森、黄李超将分别带来深度学习、增强学习、物体检测的相关课程。本期地平线资深算法研究员罗恒将为大家带来深度学习简介,包括神经网络历史回顾和神

  雷锋网(公众号:雷锋网)按:本文为大牛讲堂算法工程师入门课程第一篇。地平线资深算法工程师罗恒、穆黎森、黄李超将分别带来深度学习、增强学习、物体检测的相关课程。本期地平线资深算法研究员罗恒将为大家带来深度学习简介,包括神经网络历史回顾和神经网络训练等内容。

  �

  整个神经网络,从历史上就可以把很多东西搞清楚,比如它是怎么变过来的。我认为神经网络其实是变得越来越简单,越来越好用的。现在神经网络常用的东西已经很固定了,你不用再加任何东西就能用。但有些时候你觉得这个东西应该work,但它不work,这种情况该怎么办。所以尽管现在很多东西已经纯标准化,但了解这些对于你找问题找错误,还是很重要。所以这次主要讲两个东西,优化和正则化。绝大多数情况,正则化不是问题,我们只关心优化问题,往往你发现需要做正则化的时候多半是数据问题。

  神经网络经历了三次研究热潮。第一次是60年代,感知器出来后很多人认为离人工智能已经很近了。但马上有人写了本书叫《感知器》,说它不能解决异或问题,这个时候大家一下子又不感兴趣了。到80年代,BP算法出来,又开始变得火热起来。但当时人们认为多层神经网络优化困难,又对它失去了信心。直到很多年后,2006年出来了Deep Belief Nets。学术界又开始慢慢对神经网络有兴趣,等到神经网络在语音识别和物体识别上取得突破后,神经网络的第三次热潮又开始了,一直持续到现在。

  感知器已经有了现代神经网络的原型,输入特征与参数w连接,加权累加之后进入神经元,通过激活函数输出。与现在的网络的区别主要有两点,第一是数据要经过人工编码形成特征;第二是网络的输出是离散的二值。前者导致了相当一段时间,人们认为什么是好的特征应该由专家来设计,有了好的特征之后再解决分类问题,从这个角度上看,SVM也只是个特殊的感知器。

  关于第二点,输出的离散的,这个带来一个问题,就是从输入到输出不是一个连续的光滑的,这个其实是限制使用梯度优化网络的最大障碍。

  很快,Minsky和Papert的《感知器》里面证明了上面的感知器不能解决异或等一大类问题,这本书因此也造成了神经网络研究的第一次低潮。有趣的是,其实也就是在《感知器》里面,作者指出如果在网络中能够增加一些额外的类似感知器的单元,那么就能解决那些不能解决的问题。

  这类神经元后来被Hinton称之为隐藏单元(Hidden Units),在传统的感知器中,输出神经元是可见的,根据训练数据,我们知道输出单元应当是什么样的状态,而隐藏单元的状态则不可知。就像之前提到的,如果隐藏单元的输出是离散的,那么根据输入特征,得到对应的输出就需要考虑隐藏单元的各种可能状态,那么就是一个组合优化问题,求解困难。

  80年代,BP算法的成功的主要原因,就是改变激活函数为光滑连续的函数(可导),这样一来,对于一个含有隐藏单元的神经网络,从输入x到输入y也是一个关于所有连接参数w的光滑连续的函数。那么使用链式法则求导,我们就可以得到网络所有参数的梯度,也就是说我们现在知道按梯度方向调整参数w就可以使得给定输入数据x改变网络的输出大小,不断地修正,就可以使得网络的行为去拟合训练数据。之后,BP算法大获成功,神经网络迎来了第二次的研究热潮。

  80年代到90年代,大量的研究人员使用BP算法训练神经网络,但是大家发现优化十分困难,最常见的失败就是无论怎么调整参数,训练的loss就是不降。由于神经网络是优化一个非线性函数,那么意味着理论上存在局部极小点,因此,每当loss不降,大家都是自然而然地认为这是遇到了局部极小点,同时理论上层数越多的神经网络非线性越强会有更多的局部极小,现实的观察也发现更深的网络往往结果更差,从而大量的研究者对神经网络失去信心,神经网络进入第二次低潮。90年代末开始的SVM相关研究以及后来对凸优化的痴迷,也都是在这个大背景下发生的。

  进入2000年之后,Hinton发现使用一些非监督方法对多层神经网络做初始化之后再使用BP算法,能够成功地训练并得到更好的结果。再后来,发现直接使用BP算法进行监督训练就能在很多很多问题上得到非常好的结果。那么为什么90年代的时候没有成功呢?一个是当时训练数据相对很少,而且当时的机器训练起来很慢;另外一个是当时训练优化方法不太先进,所以有时在训练的时候梯度会出一些问题。

  上面的图是一个四隐藏层的神经网络训练在MNIST上面(激活函数是tanh),大家可以看到训练一开始,最顶层的神经元的激活值迅速减小,那么意味着从这一层往后传递的梯度也会迅速减小,同时也可以观察到loss会基本保持不变(最后一层的激活函数接近0,那么无论什么样的输入到这一层之后都差不多,自然也就无法正确分类降低loss)。

  但是随着训练的进行,顶层的激活又从0开始慢慢变大,loss最后又开始降。也就是在优化的时候,本来以为是掉到某一个坑里(局部极小),无论把w怎么改变,你的loss都没办法降下来。但实际情况是你在一个很平的高原上,你沿各个方向走,这个loss都差不多。现在我们知道使用适当的参数初始化、使用没有饱和的激活函数(如ReLU)、使用Batch Normalization都可以、使用一些自适应学习率方法(如Adam,RMSProp)都可以缓解上面这种情况,当然更重要的一点是使用GPU。

  历史讲完了,接下来讲讲算法工程师日常工作面临的问题。我有一堆数据,质量差不多,我要拿到这些数据去训练一个模型,让这个模型能够投入使用。至于训练模型,我们现在工具已经很完备了,数据整理好之后梳理好命令,机器去跑,拿到一个结果,就最好了。但通常呢,会发现结果不好,结果不好有两种情况,一种是我刚才说的,模型在训练集上表现不好,也就是对应我们要讲的第一个问题,优化问题。也就是你拿到一个数据,你第一件事情你不要考虑测试集,你就考虑训练集,我要让我这个模型在训练上能做的足够好,所以这个实际上是一个优化问题。通常我们绝大多数困难都在这个问题。

  当这个问题解决之后,可能又开始第二个问题。就是我在训练集上做的很好,但是在验证集上做的不好,这个就是overfitting,overfitting有很多种情况,从学术上讲比如说训练数据中包含一些噪声。我们日常中当你发现你的loss很低,但是在你的验证集结果不好,通常是你的训练集和你的测试集不一样。这个不一样可能有很多种原因,比如是不同的时间采集的,采集数据的策略发生了变化等等。这时首先需要做的是通过可视化对数据的分布有直觉上的认识,解决数据本身的问题。最简单的一种可视化办法,比如说你是一个二分类,你现在数据你就把它全部过一遍,二分类只有一个输出,每个训练的数据给它分一个数,你把这个数从大到小排一遍,验证集也可以得到一个数,也从大到小排一遍。

网络 神经 训练 数据 问题
分享到:

1.TMT观察网遵循行业规范,任何转载的稿件都会明确标注作者和来源;
2.TMT观察网的原创文章,请转载时务必注明文章作者和"来源:TMT观察网",不尊重原创的行为TMT观察网或将追究责任;
3.作者投稿可能会经TMT观察网编辑修改或补充。


观点约架