干货 | 算法工程师入门第一期——罗恒讲深度学习
本篇文章4302字,读完约11分钟
雷锋。(公开号码:雷锋。出版社:这是在牛大演讲厅开设的第一门算法工程师入门课程。地平线高级算法工程师、穆和黄将分别带来深度学习、增强学习和目标检测等相关课程。本期,Horizon的高级算法研究员罗恒将为您简要介绍深度学习,包括神经网络历史回顾和神经网络训练。
ψ1
整个神经网络可以搞清楚历史上的许多事情,比如它是如何变化的。我认为神经网络正变得越来越简单易用。现在,神经网络中常用的东西是如此固定,以至于你不用添加任何东西就可以使用它们。但有时你认为这东西应该有用,但它不起作用。在这种情况下我该怎么办?因此,虽然现在很多事情都是纯粹标准化的,但是了解这些事情对于你发现问题和错误仍然是非常重要的。所以这次我主要讲两件事,优化和正则化。在大多数情况下,正则化不是问题,我们只关心优化,当您发现需要正则化时,它主要是一个数据问题。
神经网络经历了三次研究热潮。第一次是在20世纪60年代,当感知器问世时,许多人认为它非常接近人工智能。但是马上有人写了一本书叫《感知器》,说它不能解决异或问题,这时大家突然都失去了兴趣。20世纪80年代,bp算法问世并再次成为热点。但当时人们认为多层神经网络的优化是困难的,对它失去了信心。直到许多年后,深层信念网于2006年问世。学术界开始对神经网络感兴趣。在神经网络在语音识别和目标识别方面取得突破后,第三次神经网络热潮重新开始并持续至今。
感知器具有现代神经网络的原型,输入特征与参数W相连,然后经过加权累加后进入神经元,通过激活函数输出。与当前网络有两个主要区别。首先,数据应该手工编码以形成特征;第二,网络的输出是离散二进制的。前者导致相当长的时间。人们认为什么是好的特征应该由专家来设计,然后有了好的特征就可以解决分类问题。从这个角度来看,支持向量机只是一个特殊的感知器。
关于第二点,输出是离散的,这带来了一个问题,即从输入到输出不是连续和平滑的,这实际上是限制梯度优化网络使用的最大障碍。
不久,明斯基和帕皮特的感知器证明上述感知器不能解决一大类问题,如异或问题,这引起了神经网络研究的第一次低潮。有趣的是,事实上,在感知器中,作者指出如果一些额外的类似感知器的单元可以被添加到网络中,那些无法解决的问题就可以被解决。
这种神经元后来被韩丁称为隐藏单位。在传统的感知器中,输出神经元是可见的。根据训练数据,我们知道输出单元应该是什么状态,但是隐藏单元的状态是未知的。如前所述,如果隐藏单元的输出是离散的,根据输入特性,需要考虑隐藏单元的各种可能状态,以获得相应的输出,这是一个组合优化问题,很难解决。
20世纪80年代,bp算法成功的主要原因是将激活函数转化为光滑连续的函数(可导)。因此,对于具有隐藏单元的神经网络,从输入x到输入y也是关于所有连接参数w的平滑连续函数。然后,我们可以通过使用链式规则推导来获得网络的所有参数的梯度,也就是说,我们现在知道根据梯度方向调整参数w可以使给定的输入数据x改变网络的输出大小,并且不断地修正它,使得网络的行为能够适合训练数据。此后,bp算法获得了巨大成功,神经网络迎来了第二次研究热潮。
从20世纪80年代到90年代,大量研究者使用bp算法训练神经网络,但是我们发现优化非常困难,最常见的失败是无论如何调整参数,训练的损失都不会下降。由于神经网络是一个非线性优化函数,这意味着在理论上存在一个局部最小值。因此,每当损失没有下降时,每个人自然都认为这是一个局部最小值。同时,理论上,神经网络层数越多,非线性越强,局部极小值越多。现实观察还表明,更深层次的网络往往会得到更差的结果,因此大量研究者对神经网络失去信心,神经网络进入第二次低潮。20世纪90年代末,与支持向量机相关的研究和后来对凸优化的痴迷也发生在这种背景下。
进入2000年后,辛顿发现使用一些无监督的方法来初始化多层神经网络,然后使用bp算法可以成功地训练并得到更好的结果。后来发现,直接使用bp算法进行监督训练,可以在很多问题上取得很好的效果。那么,为什么它在20世纪90年代没有成功呢?一是当时训练数据相对较少,机器当时训练速度较慢;二是当时的训练优化方法不先进,所以训练过程中有时会出现梯度问题。
上图显示了在mnist上训练的具有四个隐藏层的神经网络(激活函数为tanh)。如您所见,顶层神经元的激活值在训练开始时会迅速降低,这意味着从该层传输的梯度也会迅速降低。同时,可以观察到损耗将基本保持不变(最后一层的激活函数接近于0,因此无论该层之后的输入是什么样的,自然不可能正确地分类和减少损耗)。
然而,随着训练的进行,顶层的激活从0逐渐增加,而损耗最终又开始下降。也就是说,当优化时,它被认为是陷入了某个坑(局部最小值),并且无论你如何改变W,你的损失都不会下降。但事实是,你在一个非常平坦的高原上,你向四面八方走去,损失是相似的。现在我们知道,使用适当的参数初始化、使用不饱和的激活函数(如relu)、使用批处理规范化以及使用一些自适应学习速率方法(如adam、rmsprop)可以缓解上述情况。当然,更重要的一点是使用图形处理器。
完成历史后,让我们谈谈算法工程师在日常工作中面临的问题。我有很多类似质量的数据。我想用这些数据来训练一个模型,以便投入使用。至于培训模式,我们的工具现在已经非常完善了。在整理完数据后,我们将整理出命令,机器将运行并得到结果。但是通常情况下,我们会发现结果并不好,并且有两种情况下结果并不好。一是该模型在训练集中表现不佳,这对应于我们要讨论的第一个问题,即优化问题。也就是说,当你得到一条数据时,你要做的第一件事不是考虑测试集,而是考虑训练集。我希望我的模型在训练中足够好,所以这实际上是一个优化问题。通常,我们的大部分困难都在于这个问题。
这个问题解决后,第二个问题可能会再次出现。也就是说,我在训练集中做得很好,但在验证集中做得不好。这太合适了。在很多情况下都是过分的。例如,从学术上讲,训练数据包含一些噪声。在我们的日常生活中,当你发现你的损失很低,但是你的验证集的结果不好时,通常你的训练集和你的测试集是不同的。造成这种差异的原因可能有很多,比如采集时间的不同,数据采集策略的改变等等。这时,首先要做的是通过可视化直观地了解数据的分布,并解决数据本身的问题。最简单的可视化方法,例如,如果你是第二个分类,你现在将浏览所有的数据,并且第二个分类只有一个输出,并且每个训练数据将被分配一个数字。如果您将这个数字从大到小排序,验证集也可以得到一个数字,并将其从大到小排序。
然后你会从大到小随机抽取一些样本,你会发现你的数据哪里错了。继续这样做,不断改进新的数据集,这将是你最大的好处。也就是说,如果你改变你的数据来扩展你的数据集,使你的数据覆盖更多的种类,收入可能是几十个百分点,而调整你的优化策略可能只有几个百分点,而正则化方法可能只有一千位数的收入。
因此,最重要的是了解神经网络和数据背后的优化过程。具体的可视化和数据采样方法通常需要结合问题本身进行创新。训练和验证数据满足要求后,下一步是训练网络,减少训练集的损失。如今,有大量的开源工具。对于一些主流任务,通常很容易找到合适的网络结构和相应的超参数。
只要你结合你自己的计算资源的限制,你可以适当地切断这些网络,所以我们不会在这里扩展它们。以下是培训过程中的一些常见情况以及如何调整它们。训练中常见的困难是损失不会下降。通常,当输入数据从下向上传输时,某一层的表示完全相同(例如,某一层的激活函数为0),因此学习自然是不可能的。
因此,在训练中检查激活功能的相关统计信息是一个好习惯。常见的情况,例如,连接矩阵w到softmax迅速变小,这可能是由数据类别的不平衡分布引起的。此时,取样和适当改变小批量的大小可能会减轻。除了考虑数据样本的平衡,这一层连接矩阵的参数初始化也可以适当改变。当网络中间一层的激活函数总是输出0时,损耗的下降也将停止。
此时,可以考虑几个方面。首先,在此激活功能之前是否有批处理规范化,如果没有,最好尝试一下(对于当前的前向网络,最好确保在激活功能之前有bn,softmax除外)。如果有bn,您可以进一步检查eps是否设置得太大,并且您可以尝试适当地降低它;其次,你也可以检查它是否是由relu引起的。这时,你也可以尝试改变偏置和bnβ在这一层的初始化(初始化为正数,如+1);第三,如果改变了原有的网络结构,最好避免表示的瓶颈(这一层的隐藏单元数不应比前一层少很多)。
如果从输入开始第一层被激活为0,则有必要检查数据的预处理和相应参数的初始化。一个非常简单的方法是让输入数据首先通过一个批处理规范化层,然后连接到下面的w。在训练集上的损失可以正常下降后,有必要查看验证集上的性能。如果我们免费获得验证集的性能,就像yann lecun建议的那样,首先,我们应该增加网络的规模,使其看起来过拟合(训练集的损失越来越低,但验证集的损失不变,甚至在减少到一定程度后开始增加)。
说到这里,我想插一句。神经网络是一种非常灵活和强大的模型,这意味着只要模型的规模足够大,它就应该能够完美地拟合训练数据。如果您发现没有办法完美地拟合训练集,并且如果优化过程中没有问题,则很可能在训练数据中存在矛盾的数据,例如,相同的图片在训练集中出现几次,并且每次标签都不同。对于语言模型来说,很难完美地适应训练集。同样的原因是不同的单词有相同(或非常相似)的上下文。提高验证集效果最直接、最有效的方法是在训练集中添加更多不同类型的数据和验证集。
这听起来像胡说八道。这里要强调的是,我希望每个人都永远记得什么时候条件允许,这应该永远是第一个考虑的方向;其次,根据不同的关注点,各种数据增强往往会给结果带来很大的改善。除了以上两种方法,接下来可以考虑各种正则化方法。首先,我们将讨论两种容易被忽略的正则化。
首先,在每一轮训练中尽可能彻底地对训练数据进行洗牌,这将带来一定的正则化效果(特别是在到处都是批量归一化的网络中,充分的洗牌可以避免一些数据总是出现在同一个小批量中)。其次,在训练效率和问题本身允许的范围内,尝试一个较小的小批量。小批量生产会使sgd过程产生大量噪声,有利于模型的推广。此外,还应尝试压差和配重,其参数可适当调整。这些调整通常仅限于改进验证集的结果。
最后,对于那些离散的长尾输入数据(例如一些与语言相关的输入),l1正则化也可以考虑输入层的参数。
-结束-
雷锋的特别贡献。严禁擅自转载。详情请参考转载说明。
标题:干货 | 算法工程师入门第一期——罗恒讲深度学习
地址:http://www.6st8.com/zbxw/5125.html
免责声明:联合早报中文网从世界各个维度报道世界经济新闻,时政新闻,突发新闻等,本篇的部分内容来自于网络,不为其真实性负责,只为传播网络信息为目的,非商业用途,如有异议请及时联系btr2018@163.com,联合早报中文网的小编将予以删除。