写在前面:
本文原载于how-to-start-a-deep-learning-project,并且在机器之心上有翻译(如何从零开始构建深度学习项目?这里有一份详细的教程)。
忽略中英文的标题,因为这并非是一个入门的详细教程,而是在深度学习应用中各个步骤阶段上经验汇总,写的很不错,在这里推荐一下。
文章具体的应用的是采用生成对抗网络,给日本漫画上色。虽然领域小众,但内容上还是有很多通用意义的。下面开始应用经验的给出:
实践经验:
- 深度学习模型查找 bug 的过程非常艰难。因此要从简单的地方着手,循序渐进,例如模型的优化(如正则化)始终可以在代码调试完成后进行。
- 我们还需要经常可视化预测结果和模型度量标准,并且我们首先需要令模型先跑起来,这样就有一个可以后退的基线。我们最好不要陷在一个很大的模型,并尝试将所有的模块都弄好。
- 项目研究阶段:先对现有产品进行研究,以探索它们的弱点。
- 站在巨人的肩膀上。阅读研究论文可能会很痛苦,但非常有意义。
- 对数据的质量要重视起来:类别均衡,数据充足,数据和标记中有高质量信息,数据和标记错误非常小,与你的问题相关。
- 与学术数据集相比,小型项目收集的样本很少,在适当情况下可以应用迁移学习。
- 避免随机改进:首先分析自己模型的弱点,而不是随意地改进。
- 建立深度学习并不是简单的把网络层堆在一起。增加好的限制(constraints)能使得学习更为有效,或者更智能。例如,应用注意机制,能让网络知道注意哪里,在变分自编码器中,我们训练隐藏因子使其服从正态分布。
- 许多预训练模型可用于解决深度学习难题。(这一点深有体会,在NLP上如此,在看到的图像处理、机器翻译领域亦是如此。)
- L1 正则化和 L2 正则化都很常见,但 L2 正则化在深度学习中更受欢迎。L1 正则化可以产生更加稀疏的参数,然而,L2 正则化仍然更受欢迎,因为解可能更稳定。
- 梯度下降:始终密切监视梯度是否消失或爆炸,梯度下降问题有许多可能的原因,这些原因难以证实。不要跳至学习速率调整或使模型设计改变太快。
- 缩放输入特征。我们通常将特征缩放为以零为均值在特定范围内,如 [-1, 1]。特征的不适当缩放是梯度爆炸或降低的一个最常见的原因。有时我们从训练数据中计算均值和方差,以使数据更接近正态分布。如果缩放验证或测试数据,要再次利用训练数据的均值和方差。(其实还可以通过分布,来check训练样本和真实样本分布diff)
- 批量归一化也有助于解决梯度下降问题,因此它逐渐取代了 Dropout。结合 Dropout 和 L2 正则化的好处是领域特定的。通常,我们可以在调优过程中测试 dropout,并收集经验数据来证明其益处。
- 激活函数:在 DL 中,ReLU 是最常用的非线性激活函数。如果学习速率太高,则许多节点的激活值可能会处于零值。如果改变学习速率没有帮助,我们可以尝试 leaky ReLU 或 PReLU。在 leaky ReLU 中,当 x < 0 时,它不输出 0,而是具有小的预定义向下斜率(如 0.01 或由超参数设置)。参数 ReLU(PReLU)往前推动一步。每个节点将具有可训练斜率。
- 确保样本在每个数据集和每批训练样本中被充分打乱。
- 用小量的训练数据使模型过拟合是 debug 深度学习的最好方式。如果在数千次迭代内,损失值不下降,进一步 debgug 代码。准确率超越瞎猜的概念,你就获得了第一个里程碑。然后对模型做后续的修改:增加网络层和自定义;开始用完整训练数据做训练;通过监控训练和验证数据集之间的准确率差别,来增加正则化控制过拟合。
- 前期的问题主要来自于 bug,而不是模型设计和精调问题。(赞)
- 把权重全部初始化到 0 是最常见的错误,深度网络也学不到任何东西。权重要按照高斯分布做初始化。
- 检查和测试损失函数的准确性。模型的损失值一定要比随机猜测的值低。例如,在 10 类别分类问题中,随机猜测的的交叉熵损失是-ln(1/10)。
- 避免使用多个数据损失函数。每个损失函数的权重可能有不同的数量级,也需要一些精力去调整。如果我们只有一个损失函数,就可以只在意学习率了。
- 数据增强:收集有标签的数据是一件昂贵的工作。对于图片来说,我们可以使用数据增强方法如旋转、随机剪裁、移位等方式来对已有数据进行修改,生成更多的数据。颜色失真则包括色调、饱和度和曝光偏移。(在NLP领域中应用到少些。)
- Mini-batch 尺寸:通常的批尺寸是 8、16、32 或 64。如果批尺寸太小,则梯度下降不会很顺畅,模型学习的速度慢,损失可能会振荡。如果批尺寸太大,则完成一次训练迭代(一轮更新)的时间太长,得到的返回结果较小。在我们的项目中,我们降低批尺寸,因为每次训练迭代时间太长。我们密切监控整个学习速度和损失。如果损失振荡剧烈,则我们会知道批尺寸降低的幅度太大了。批尺寸影响正则化因子等超参数。一旦我们确定好批尺寸,我们通常就锁定了值。
- 学习率和正则化因子高度相关,有时需要一起调。不要太早进行精细调整,有可能浪费时间。设计改变的话这些努力就白费了。
- Dropout 率通常在 20% 到 50% 之间。我们先从 20% 开始。如果模型出现过拟合,则提高值。
- 网格搜索的计算量很大。对于较小的项目,它们会被零星使用。我们开始用较少的迭代来调整粗粒度参数。在后期的细调阶段,我们会使用更长的迭代,并将数值调至 3(或更低)。
- kaggle是一个很棒的学习,讨论的地方。毕竟纸上得来终觉浅,须知此事要躬行。