从头开始做深度学习项目,应该注意哪些问题?

李亚洲54052926

在学习了有关深度学习的理论课程之后,很多人都会有兴趣尝试构建一个属于自己的项目。但对初学者来说,学习前辈的经验,能够让自己避免很多坑。这里机器之心整理了国外工程师Jonathan Hui上手漫画上色项目时写的经验。


  • 第一部分:启动一个深度学习项目

  • 第二部分:创建一个深度学习数据集

  • 第三部分:设计深度模型

  • 第四部分:深度学习网络中的调试

第一部分:启动一个深度学习项目

很多人工智能项目其实并没有那么严肃,做起来还很有趣。在寻找项目时,不要局限于增量性改进,去做一款适销对路的产品,或者创建一种学习速度更快、质量更高的新模型。

训练深度学习模型需要数百万次的迭代,因此查找 bug 的过程非常艰难,而且容易崩坏。因此我们要从简单的地方着手,循序渐进,例如模型的优化(如正则化)始终可以在代码调试完成后进行。此外,我们还需要经常可视化预测结果和模型度量标准,并且我们首先需要令模型跑起来,这样就有一个可以后退的基线。我们最好不要陷在一个很大的模型,并尝试将所有的模块都弄好。

宏伟的项目计划可能带惨烈的失败。多数个人项目的第一个版本会持续两到四个月,这个时间非常短暂,因为研究、调试和实验都需要花费大量的时间。一般我们安排这些复杂的实验,使其通宵运行,到第二天清晨时,我们希望得到足够的信息来采取下一步行动。在早期阶段,这些实验不应超过 12 小时,这是一条良好的经验法则。

在成本考虑上,必须使用 GPU 来训练实际模型。它比 CPU 快 20 到 100 倍。价格最低的亚马逊 GPU p2.xlarge 站点实例要价 7.5 美元/天,而 8 核 GPU 的价格则高达 75 美元/天。

第二部分:创建一个深度学习数据集

深度学习项目的成功取决于数据集的质量。在本文的第 2 部分中,我们将探讨创建优质训练数据集的核心问题。

公开及学术数据集

对于研究项目,可以搜索已建立的公开数据集。这些数据集可以提供更整齐的样本和基线模型性能。如果你有多个可用的公开数据集,请选择与你的问题最相关且质量最好的样本。

自定义数据集

对于实际问题,我们需要来自问题领域的样本。首先尝试查找公共数据集。关于创建高质量自定义数据集的研究还有所欠缺。如果没有可用的资料,请搜寻你可以抓取数据的位置。该位置通常有很多参考,但数据质量通常较低,还需要投入大量精力进行整理。在抓取样本之前,要专门抽出时间评估所有选项并选择最相关的选项。

高质量数据集应该包括以下特征:

  • 类别均衡

  • 数据充足

  • 数据和标记中有高质量信息

  • 数据和标记错误非常小

  • 与你的问题相关

注意,不要一次爬取所有数据。我们经常借助标签和分类来抓取网站样本,从而获取与我们的问题相关的数据。最好的爬取方法是在你的模型中训练、测试少量样本,并根据得到的经验教训改善抓取方法。

清理你抓取的数据非常重要

,否则,即使最好的模型设计也达不到与人类水平相当的表现。

模型训练和视觉评估都提供了进一步的信息来细化我们的标签选择。随着迭代的继续,我们将学到更多,并逐渐进行样本积累。我们还需要使用分类器进一步过滤与问题无关的样本,如清除所有人物过小的图像等。与学术数据集相比,小型项目收集的样本很少,在适当情况下可以应用迁移学习。

总结来说,也就是:

  • 尽可能使用公共数据集;

  • 寻找可以获取高质量、多样化样本的最佳网站;

  • 分析错误并过滤掉与实际问题无关的样本;

  • 迭代地创建你的样本;

  • 平衡每个类别的样本数;

  • 训练之前先整理样本;

  • 收集足够的样本。如果样本不够,应用迁移学习。

第三部分:深度学习设计

第三部分介绍了一些高层次的深度学习策略,接下来我们将详细介绍最常见的设计选择,这可能需要一些基本的 DL 背景。

简单灵活

设计初始要简单、小巧。在学习阶段,人们脑海中会充斥大量很酷的观念。我们倾向于一次性把所有细节都编码进来。但这是不现实的,最开始就想要超越顶尖的结果并不实际。从较少网络层和自定义开始设计,后面再做一些必要的超参数精调方案。这些都需要查证损失函数一直在降低,不要一开始就在较大的模型上浪费时间。

在简短的 Debug 之后,我们的模型经过 5000 次迭代产生了简单的结果。但至少该模型所上的颜色开始限制在固定区域内,且肤色也有些显露出来。

优先性以及增量设计

首先为了创造简单的设计,我们需要选出优先项。把复杂问题分解成小问题,一步一步解决。做深度学习的正确策略是快速的执行学到的东西。相比于做个要不断改变的长期计划,还不如以优先性驱动的计划。使用更短、更小的设计迭代,从而保证项目可管理性。

避免随机改进

首先分析自己模型的弱点,而不是随意地改进,例如用双向 LSTM 或者 PReLU。我们需要根据可视化模型误差(表现极差的场景)以及性能参数来确定模型问题。随意做改进反而适得其反,会成比例的增加训练成本,而回报极小。

限制

我们把限制应用到网络设计,从而保证训练更高效。建立深度学习并不是简单的把网络层堆在一起。增加好的限制(constraints)能使得学习更为有效,或者更智能。例如,应用注意机制,能让网络知道注意哪里,在变分自编码器中,我们训练隐藏因子使其服从正态分布。

以下是对深度学习项目的主要步骤的简单总结:

第四部分:调试深度学习网络

深度学习的问题解决步骤

在前期开发中,我们会同时遇到多个问题。就像前面提到的,深度学习训练由数百万次迭代组成。找到 bug 非常难,且容易崩溃。从简单开始,渐渐做一些改变。正则化这样的模型优化可以在代码 degug 后做。以功能优先的方式检查模型:

  • 把正则化因子设置为 0;

  • 不要其他正则化(包括 dropouts);

  • 使用默认设置的 Adam 优化器;

  • 使用 ReLU;

  • 不要数据增强;

  • 更少的深度网络层;

  • 扩大输入数据,但不要非必要预处理;

  • 不要在长时间训练迭代或者大 batch size 上浪费时间。

用小量的训练数据使模型过拟合是 debug 深度学习的最好方式。如果在数千次迭代内,损失值不下降,进一步 debgug 代码。准确率超越瞎猜的概念,你就获得了第一个里程碑。然后对模型做后续的修改:增加网络层和自定义;开始用完整训练数据做训练;通过监控训练和验证数据集之间的准确率差别,来增加正则化控制过拟合。

如果卡住了,去掉所有东西,从更小的问题开始上手。

检查列表

数据:

  • 可视化并检查输入数据(在数据预处理之后,馈送到模型之前);

  • 检查输入标签的准确率(在数据扰动之后);

  • 不要一遍又一遍的馈送同一 batch 的数据;

  • 适当的缩放输入数据(一般可缩放到区间 (-1, 1) 之间,且具有零均值);

  • 检查输出的范围(如,在区间 (-1, 1) 之间);

  • 总是使用训练集的平均值/方差来重新调节验证/测试集;

  • 模型所有的输入数据有同样的维度;

  • 获取数据集的整体质量(是否有太多异常值或者坏样本)。

模型:

  • 模型参数准确的初始化,权重不要全部设定为 0;

  • 对激活或者梯度消失/爆炸的网络层做 debug(从最右边到最左边);

  • 对权重大部分是 0 或者权重太大的网络层做 debug;

  • 检查并测试损失函数;

  • 对预训练模型,输入数据范围要匹配模型中使用的范围;

  • 推理和测试中的 Dropout 应该总是关掉。


分享到:


相關文章: