数据为王
模型训练的第一步并不是一上来就开始写训练代码,而是先观察数据。要花费足够多的时间,查看上千帧图像来了解样本的分布并寻找它们存在的模式;查看样本是否存在不均衡和偏差。注意自己在观察样本时的是如何区分不同样本,它可能启示我们采用什么样的网络架构。
- 样本的变化有多大,它是以什么形式变化的,比如相对位置、遮挡截断、颜色、姿态
- 是否需要全局信息还是说局部信息就足够了
- 空间位置是否重要,是否可以使用池化操作
- 细节是否重要,最多能将图像下采样到多大
- 标签的噪声有多大
Tick & Trick
当已经对数据有了一个定性的认识后,最佳实践是通过代码以任务自己能想到的维度(标签的类别、标注的大小或个数)来搜索、过滤、排序训练样本,可视化他们的分布,并找到异常点。异常点基本能揭示数据处理或标注的错误。 对标注数据标注两次,一个作为预测、一个作为真实值,即可以评测标注质量,也能查看的标注误差在哪里? 另外,模型可以当作是对数据的压缩和编译,可能观察模型的输出以及它们可能是由于什么样的数据导致的,如果不能解释,可以推断模型的训练哪里还有问题。 搭建端到端的训练、测试框架,得到基线 当对我们的数据有了一定了解以后,我们是不是就可以开始训练 Multi-scale ASPP FPN ResNet 网络呢?并不是。而且那肯定是一条痛苦的路。接下来,我们要做的是搭建一个端到端的训练、测试框架,并通过一系统的实验验证它的正确性。 我们要训练模型的过程中,可视化损失、准确度、模型预测,并开展一系列 ablation 实验。
- 固定随机种子。使用一个固定的随机种子,保证结果能够复现,这样能去除调试时因数据引起的变化。
- 简单化。在前期不要加入不必要的功能。举例来说,当前阶段应该关掉数据增强。
- 验证初始化损失。
- 更好地初始化。
- 在一个batch上过拟合。在一个小的batch 上(比如只有size为2)过拟合一个模型,查看损失是否达到最小,同时可视化预测和真实的label在此时是否一致了。
- 判定模型大小。起初使用一个小网络,对于数据可能是欠拟合的,当增加模型能力时,查看损失是否变得更小了。
- 可视化。可视化输入网络的数据、标注、中间结果等等。
- 动态可视化。对一个固定的测试集 batch,在整个训练过程中对其预测可视化。预测的变化可以让自己对训练的走向有一个更清晰的认识;从抖动的变化量上可以对学习率是否偏大或偏小有一定判断。
- 使用梯度可视化依赖关系。梯度给出了网络中什么依赖什么的关系,可以帮助调试。举个例子,可以将batch中某个输入对应的损失设置为0,经梯度回传后,该index对应的梯度也应该为0,从而检测在预测过程中是否有batch的错误使用。
- 测试规模化。我们要在整个评测集上确认测试损失,而不是在中间过程中对几个batch进行损失计算,因为这不能反应真实的模型能力变化情况;为了保证正确性,牺牲一定的时间也是合适的。
- 从具体到泛化。如果要写一个非常复杂的函数先从最简单的方式写起,保证正确性,之后再不断优化每个步骤,尤其是向量化代码,比较抽象的时候。
过拟合
目前为止,我们对数据有了一定了解,建立了一个端到端的训练和评测框架,对于任何模型我们能够得到并复现一个可靠的结果,并且现在有了基础的baseline,人类标注可以达到的性能有一定了解。这个阶段就是迭代一个好的模型。 如果没有时间限制可以先选择一个大模型能够在训练集上过拟合,之后再进行合适的正则化。
- 选择合适的、经典的网络
- adam 比较安全
- 每次只加入一个feature
- 对学习率的默认设置保持警惕
正则约束
- 更多的数据
参考链接: http://karpathy.github.io/2019/04/25/recipe/