引言
在本文中,我将介绍我在作为深度学习工程师的10年经验中收集到的一系列模式和反模式。深度学习工程是关于试验的。最初的最小可行产品往往非常快速。相比之下,深度学习项目生命周期的大部分时间都用于改进代码和度量标准/得分的迭代。往往在广泛的实验中,通过大量边际改进发现的路径能够推进得分。在我的实践中,只有5次实验中的1次甚至10次实验中的1次改善了得分。特别是在团队合作中,优化实验过程至关重要。
首先,让我们明确使用的术语。在接下来的材料中,我考虑最大化单一度量,进一步称为“度量”。通过基准,我指的是没有考虑任何变化的代码状态和度量值。通过回归,我指的是度量的减少,即不希望的结果。相反地,通过进步,我指的是度量的增加,即期望的结果。
模式和反模式
#1 结果的可靠性
反模式:
运行基准和一个实验一次,并基于比较得出结论。假设结果具有显著的方差,例如由于选择了较高的学习率或过拟合导致的训练收敛不良。那么,您可能会得出错误的结论,无论您观察到进步还是回归。
模式:
运行多个训练周期以估计结果的方差。运行多个深度学习训练周期可能会消耗资源和时间,但对于了解结果的方差和进一步可靠的进展非常重要。如果需要,使用双边或单边学生T检验分析测量结果。
#2 痴心妄想
反模式:
假设某种变化肯定会改善度量,并继续合并它。无论是软件还是算法的变化都可能引入回归,无论是显而易见的还是微妙的。
模式:
在任何变化之后,重新运行训练以确保没有回归。显而易见的回归,如训练崩溃,即使在训练的早期迭代中也很容易发现。微妙的回归只能在训练周期结束时才能发现。
#3 回归掩盖
反模式:
将多个改变打包在一起,根据研究人员的观点,所有这些改变都会改善度量。回归掩盖可能会发生,即变化A会导致轻微的回归,而变化B会带来显著的进步。两者的组合可能会显示出度量的改善。通过这种方式,轻微的回归将被显著的改善掩盖。然而,您只希望保留能够带来改进的变化,而放弃降低度量的变化。
模式:
独立测量变化。如果您脑海中有两个潜在的改进方案,请分别运行它们:
- 方案 A 的改变
- 方案 B 的改变
- 方案 A 和 B 的改变
这样可以避免回归阴影。
#4 附带条件
反模式:
从Git工作副本启动训练。在这种情况下,将来将无法重复实验或分析实验之间的精确差异。
模式:
必须提交所有的更改,包括临时性更改,以使Git工作副本保持干净。必须为提交打上标签。作为标签的替代方案,实验成果必须存储运行代码的提交哈希。
#5 快速循环
反模式:
始终启动训练的繁重(最终)版本。由于繁重版本的速度较慢,获取实验结果需要很长时间,并可能阻碍对微小改变的研究。
模式:
保持一个快速版本的训练循环。快速版本必须是原版本的2到10倍速,并能够反映评估中的变化效果。通常,快速版本的训练迭代次数较少,并且具有更快、缩小尺寸的神经网络。快速版本可以作为集成测试,也可以快速评估变化的前景。
#6 无分支
反模式:
不使用分支来分离功能,并将所有修改保存在主分支中。
模式:
为每个变化保留一个单独的分支。将变化保存在不同的分支中将使我们避免合并显示回归的代码,以防止代码中充满选项、模式和if-else块。有时,需要花费一些心思来删除支持实验的大量代码,尽管不幸的是,这些实验没有取得进展。
#7 编码习惯
反模式:
不使用软件工程实践来开发代码。经常听到的辩论是“我们不是软件工程团队/项目”和“在研究中,事情的处理方式不同”。然而,当争夺高分时,由于典型的软件错误导致连小数点的失误都可能是致命的。
模式:
编写架构良好、不包含代码重复、所有“魔法数字”都有命名的代码,并具有单元测试和集成测试。对于快速推进的应用研究项目来说,广泛的测试和代码覆盖率可能是不可承受的成本。然而,对于紧凑且算法密集的函数(如特征编码器-解码器),单元测试在可能存在缺陷的实验、错误结论甚至误导的研究人员直觉方面提供了重要的好处。
#8 非侵入式
反模式:
进行“侵入性”更改并进行合并。所谓的侵入性更改是指改变其他操作模式行为的变化,即使它改进了目标模式。考虑以下示例。代码支持训练两种神经网络骨干:骨干X和骨干Y。在每个骨干上训练是两种单独的模式。您想要更改骨干X的学习速率以改进其指标。您更改了两种模式的学习速率,对骨干X进行实验,并观察指标的改进。原样合并代码是一个反模式,因为骨干Y的学习速率被改变了,而骨干Y并没有运行实验,一旦运行,可能会导致回归。
模式:
进行非侵入性更改,不改变所有其他操作模式的代码行为。编写非侵入性更改可能会很繁琐且耗费时间。为了更快地进行实验,可以考虑首先进行侵入性更改,运行实验,只有在显示出有希望的结果时,重新编写代码以使之非侵入性。需要注意的是,在准备好非侵入性更改后,必须重新运行实验。此步骤将有助于避免由于将代码合并到主分支时出现的错误导致潜在回归。
#9 重新运行基准
反模式:
使用旧的历史基准指标值并将其与新的实验结果进行比较。
模式:
偶尔重新运行基准(来自主分支),可以每周一次在周末进行,甚至可以与每个实验一起进行。尽管基准代码可能会更改,但外部因素可能会影响基准。这样的外部因素可能包括:
- 在不同的机器上运行实验
- 软件更新:CUDA工具包、conda软件包
- 基准和实验的运行者不同,他们可能有不同的未记录的启动实验的方式。
#10 指标版本控制
反模式
更改验证数据/流程/指标并将新的实验指标与历史指标值进行比较是一种反模式。例如,如果验证数据与训练数据一起进行了清理,人们可能会认为数据清理总是有所改进。总体上可能是这样,但是指标变化了,与历史结果不再可比。
模式
在更改如何计算指标后,重新运行基准以得出新指标的值。
结论
通过避免这十个反模式并遵循这十个模式,您将能够将深度学习实验推向更高水平。