Karpathy的33个神经网络「炼丹」技巧学习笔记

参考文档:李飞飞高徒、特斯拉AI主管 Karpathy的33个神经网络「炼丹」技巧

Karpathy的33个神经网络「炼丹」技巧学习笔记

1.梳理数据

Karpathy的33个神经网络「炼丹」技巧学习笔记

 1.1标签噪声:

深度学习中噪声标签的影响和识别

图像分类】 标签噪声对分类性能会有什么样的影响

几种噪声标签识别算法简介

1.2写一些简单的代码来搜索/过滤/排序标签类型、标注规模、标注数量等,并沿任意轴可视化其分布和异常值??

此处如何实践?

2. 配置端到端训练/评估架构、获取基线结果

Karpathy的33个神经网络「炼丹」技巧学习笔记

 

2.1固定随机seed

可以避免一些变化因素,例如可以保证多次运行相同代码得到相同结果。

2.2简化:确保禁用不必要的技巧 

前期不使用数据增强,后期作为正则化策略使用数据增强

2.3使用多数据、少次数的验证评估

在绘制测试损失时,考察尽量大的数据集的效果。避免使用Tensorboard去平滑处理多个批量数据的验证评估结果。

2.4在初始化中验证损失

初始化时,我们要验证损失函数能够得到合理的损失值。

初始化时,L2回归和Huber函数等需要由相同的默认值。

回归损失函数:Huber Loss

2.5优秀的初始化:正确地初始化最终层。

这个比较玄学,需要在实战中多总结。

如何理解深度学习源码里经常出现的logits?

例如,如果你正在对均值为 50 的一些数据做回归处理,那么初始化的最终偏置项就应该为 50。如果你有一个非平衡数据集(两类样本数 1:10),那么就需要在 logits 上设置偏置项,令模型在初始化时预测概率为 0.1。正确配置这些偏置项将加快收敛速度,因为网络在前面几次迭代中基本上只在学习偏置。

2.6人类的基线结果

准确度、损失值等度量指标,人类能够解释并检查。这样就可以与构建的模型作比对,分析训练效果。

或者对测试数据进行两次标注:一次预测值,另一次为标注值。

2.7独立于输入的基线结果

a.所有输入为0得到一个结果res1;b.实际输入得到一个结果res2;res2应该比res1好。

2.8在批数据上过拟合:在单个批数据上使得过拟合(两个或多个样本)

为此,我们需要增加模型拟合能力,并验证我们能达到的最低损失值(即0)。在同一张图中显示标签和预测值,确保损失值一旦达到最小,他们就能保持一致(标签和预测值)了。

2.9验证损失值下降

开始模型尽量简单,它在数据集上表现为欠拟合,然后尝试增加一点模型的拟合能力,在验证损失值是否有下降。

2.10在输入网络前可视化

我们需要可视化输入到网络的具体数据,可是化原始张量的数据和标签。这样可以节省大量时间,并能够揭示数据预处理和数据增强过程中的错误。

2.11可视化预测过程

对一个固定的测试批数据进行模型预测可视化。如果网络以某种方式小幅度波动,那么模型可能在拟合数据,这也展示了一些不稳定性。

如果抖动量太大,说明学习率太高或太低?

2.12使用反向传播绘制依赖性

你的深度学习代码通常包括复杂的、矢量化的、Boardcast 操作。一个常见的 bug 是,人们会无意间使用 view 而不是 transpose/permute,从而混合了批量数据中的维度信息。然而,你的网络仍然可以正常训练,只不过它们学会忽略了其它样本中的数据。一种 debug 的方法是将某些样本 i 的损失设置为 1.0,然后运行反向传播一直到输入,并确保第 i 个样本的梯度不为零。更一般的,梯度为我们提供了网络中的依赖性关系,它们在 debug 中非常有用。

深度学习(七)——Broadcast自动扩展

PyTorch 高维矩阵转置 Transpose 和 Permute

2.13一般化特殊案例

我喜欢直接写非常具体的函数,它只包含我现在需要做的事情。我会先让这个函数能 work,然后再一般化好函数,并确保能取得相同的结果。通常这个过程会体现在向量化代码中,我会先用循环编写某个过程,然后再一次一个循环地将它们转化为向量化化代码。

3.过拟合

经过步骤1梳理数据和步骤2配置端到端训练/评估架构,我们为迭代一个好的模型做好了准备。

寻找一个好的模型需要经历两个阶段:1.首先获得足够大的模型,这样它能够过拟合(即关注训练损失);2.对模型进行适当的正则化(丢弃一些训练损失以改进验证损失)。

如果我们用任何模型都不能获得较低的误差率,则说明前面的步骤中有一些问题、bug和配置错误。

Karpathy的33个神经网络「炼丹」技巧学习笔记

3.1选择模型:为数据选择一个合适的架构

挑选模型时不要好高骛远,不要一开始就堆叠一些新的模块或创造性用语各种异质架构。应当找最相关的论文,并直接利用它们的简单架构,从而获得良好的性能。然后再基于这个简单的架构进行修改和改进,并将我们的想法加进去。

3.2adam是一般选择

在配置基线模型的早期阶段,我喜欢使用adam算法(学习率3e-4)。因为,经验证明,adam对超参数的容忍度更高,不太好的学习率也能获得一般的效果。对于卷积网络来说,一般经过仔细调整的SGD会比adam好一些,但适用于SGD的最佳学习率范围会窄很多。

3.3一次复杂化一个

如果有多个特性加入分类器,那么一次只插入一个特性,以确保能够获得期待的性能提升。不要在一开始就全加上,这样你会弄不清楚性能提升到底是哪个特性带来的。还有其他增加复杂性的方法,例如你可以先尝试插入较小的图像,然后再慢慢变大。

3.4别相信默认的学习率衰减 

不同的问题,使用的学习率衰减策略会有所不同,而且如果epoch数量不同,衰减过程也会不一样。例如数据集的大小datasize,会影响epoch的数量,而很多学习率衰减直接与epoch相关。在我的工作中,经常关闭整个学习率衰减,使用常数学习率。

所以,当你修改来自其他领域的代码,应该小心使用学习率衰减方法。

4正则化

4.1更多数据

4.2数据增强

4.3创造性增强

5.精调

6.最后的压榨