文章发布于公号【数智物语】 (ID:decision_engine),关注公号不错过每一篇干货。
来源 | AI公园(id:AI_Paradise)
作者 | George Seif
编译 | ronghuaiyang
前戏
这又是一篇介绍深度学习的技巧的文章,不过和之前的那篇文章侧重点有所不同,这篇文章更加注重于如何在实际的项目的数据集中训练出好的模型出来,与其说是深度学习的技巧,不如说是深度学习项目的技巧。对于使用深度学习来做实际项目的同学来说,很有启发,一起来看看吧!
深度学习已经成为解决许多具有挑战性的现实问题的首选方法。它是目前为止在物体检测、语音识别和语言翻译等方面表现最好的方法。许多人认为深度神经网络(DNNs)是一个神奇的黑盒子,我们把一堆数据塞进去,然后拿出我们的解决方案!实际上,事情变得更加复杂……
在设计和应用DNN来解决特定问题时可能会遇到很多挑战。为了达到实际应用所需的性能指标,pipeline中所有阶段的正确设计和执行是至关重要的,包括数据准备、网络设计、训练和推理。在这里,我将和你分享7个实用的技巧,让你充分利用你的深层神经网络。
01
数据,数据,数据
这不是什么大秘密。一直运转良好的深度学习机器需要燃料——大量的燃料,这里燃料就是数据。我们拥有的标注的数据越多,我们的模型的性能就越好。谷歌甚至在3亿张图像的数据集中大规模地探索了更多数据带来更好性能这个想法!
在实际应用程序中部署深度学习模型时,你应该不断地为其提供更多的数据,并进行微调以继续改进其性能。Feed the beast:如果你想提高你的模型的性能,那就去获取更多的数据吧!
不断增加数据可以获得更好的性能
02
你应该使用什么优化器?
近年来,许多梯度下降优化算法得到了发展,每种算法都有其优缺点,其中最受欢迎的有:
1. 具有动量的随机梯度下降(SGD)
2. Adam
3. RMSprop
4. Adadelta
RMSprop、Adadelta和Adam被认为是自适应优化算法,因为它们自动更新学习率。使用SGD,你必须手动选择学习速率和动量参数,通常会随着时间的推移而衰减学习速率。
在实际应用中,自适应优化算法收敛速度快于SGD算法,然而,他们的最终表现通常稍差一些。SGD通常可以达到更好的最小值,从而获得更好的最终精度,但它可能比某些优化器花费的时间要长得多。它还更加依赖于健壮的初始化和学习率衰减策略,这在实践中是非常具有挑战性的。
因此,如果你需要一些快速的结果,或者只是想测试一种新技术,请使用自适应优化器。我发现Adam很容易使用,因为它对你选择完美的学习速度不是很敏感。如果你想获得绝对最好的最终性能,那么使用SGD + 动量,并使用学习率、衰减和动量值来最大化性能。
两全其美的方法
最近有研究表明,通过从Adam切换到SGD,你可以同时获得两个世界的最佳效果:高速训练,表现一流(https://arxiv.org/pdf/1712.07628.pdf)!其思想是,训练的早期阶段实际上是SGD对参数调优和初始化非常敏感的时候。因此,我们可以从使用Adam开始我们的培训,这将使你在不必担心初始化和参数优化的情况下走得很远。然后,一旦Adam让我们开始,我们可以切换到SGD +动量优化,以达到最佳性能!
Adam vs SGD的表现。Adam由于具有鲁棒性和自适应学习率,在开始时表现较好,而SGD最终达到了较好的全局最小值。
03
如何处理不均衡数据
在许多情况下,你将处理不平衡的数据,特别是在实际应用程序中。举一个简单但真实的例子:你正在训练你的深层网络,出于安全原因,预测视频中的某人是否持有致命武器。但是在你的训练数据中,你只有50个持有武器的人的视频,1000个没有武器的人的视频!如果你直接使用这些数据来训练你的网络,那么你的模型肯定会偏向于预测没有人拥有武器!
你可以做一些事情来解决这个问题:
在loss函数中使用class weights。本质上,未充分表示的类在loss函数中获得更高的权重,因此对特定类的任何分类错误都会导致loss函数中出现非常高的错误。
1. 样本过采样:重复一些包含代表性不足的类的训练示例,有助于平衡分布。如果可用数据很小,那么这种方法最有效。
2. 样本欠采样:你可以简单地跳过一些包含过度表示类的训练示例。如果可用数据非常大,那么这种方法最有效。
3. 数据增强:对于少数类,你可以为代表性不足的类综合创建更多的训练样本!例如,在上一个检测致命武器的例子中,你可以更改属于拥有致命武器类的视频的一些颜色和灯光。
04
迁移学习
正如我们在第一个技巧中看到的,深度网络需要大量数据。不幸的是,对于许多新应用来说,获取这些数据可能非常困难,而且代价高昂。如果我们希望我们的模型表现良好,我们可能需要成千上万个新的训练样本来进行训练。如果数据集不可用,则必须手动收集并标注。
这就是转移学习发挥作用的地方。使用迁移学习,我们不需要很多数据!我们的想法是,从一个网络开始,这个网络以前训练过数百万张图像,比如ResNet在ImageNet上预先训练过。然后我们将对ResNet模型进行微调,只对最后几层进行再训练,而不对其他层进行训练。通过这种方式,我们将ResNet从数百万张图像中学到的信息(图像特征)进行微调,以便将其应用于不同的任务。这是可能的,因为跨域图像的特征信息通常非常相似,但是对这些特征的分析可能因应用的不同而不同。
一个基本的迁移学习的pipeline
05
快速简单的数据增强提升性能
我们已经说过几次了:更多的数据=更好的性能。除了转移学习之外,另一种快速和简单的提高模型性能的方法是数据增强。数据增强包括在使用原始类标签的同时,通过修改数据集中的一些原始图像来生成合成的训练示例。例如,常用的图像数据增强方法有:
1. 水平和垂直旋转和/或翻转图像
2. 改变图像的亮度和颜色
3. 随机模糊图像
4. 从图像中进行随机裁剪
基本上,你可以执行任何更改来更改图像的外观,但不能更改整个内容!你可以把一只狗画成蓝色,但你仍然可以清楚地看到它是一只狗。
数据增强
06
使用集成方法来提升你的模型
在机器学习中,可以集成训练多个模型,然后将它们组合在一起以获得更高的性能。因此,我们的想法是在相同的数据集上,针对相同的任务训练多个深度网络模型,然后通过投票的方案将模型的结果组合起来。得票最多的类别获胜。
为了确保所有模型都是不同的,可以使用随机权重初始化和随机数据增强。众所周知,由于使用了多个模型,因此从不同的角度处理任务,集成通常比单个模型要精确得多。在现实世界的应用中,特别是在比赛中,几乎所有顶级模型都使用集成。
模型集成
07
通过剪枝来加速
我们知道模型的精度随着深度的增加而增加,但是速度呢?更多的层意味着更多的参数,更多的参数意味着更多的计算、更多的内存消耗和更慢的速度。理想情况下,我们希望在提高速度的同时保持较高的准确性。我们可以通过剪枝来做到这一点。
深度神经网络剪枝的步骤
其思想是,在网络中的许多参数中,有些是冗余的,对输出的贡献不大。如果可以根据神经元的贡献大小对网络中的神经元进行排序,那么就可以将排名靠后的神经元从网络中移除,从而形成一个更小更快的网络。排序可以根据神经元权重的L1/L2均值、神经元的平均激活度、某个验证集上神经元不为零的次数等方法进行。更快/更小的网络对于在移动设备上运行深度学习网络非常重要。
剪枝网络最基本的方法就是删除某些卷积滤波器。在这篇最近的论文(https://arxiv.org/abs/1611.06440)中,这项工作做得相当成功。这项工作中的神经元排序相当简单:它是每个滤波器权重的L1范数。在每次修剪迭代中,他们对所有的滤波器进行排序,在所有层中删除所有级别最低的m个过滤器,然后重新训练和重复。
另一篇最近的论文(https://arxiv.org/abs/1605.06431)分析了残差网络的结构,提出了剪枝滤波器的关键观点。作者表明,在删除层时,具有残差快捷连接的网络(如ResNets)在保持良好准确性方面要比不使用任何快捷连接的网络(如VGG或AlexNet)健壮得多。这个有趣的发现具有非常重要的实际意义,因为它告诉我们,在为部署和应用进行网络剪枝时,网络设计非常重要(请使用ResNets!)所以使用最新最好的方法总是好的!
星标我,每天多一点智慧