听说好的学习方法是带着问题去学,单纯的阅读和灌输没有太多的意义,所以这篇文章我们用提问的方式去写 。欢迎大家一起讨论
1. Deep learning 看起来简单 为什么实际训练难以达到预期效果 ?
2.在训练前如何对你的数据作分析?
3.如何设计一个好的baseline,他应该保持哪些结构?
4.怎么让模型overfitting ?
5.又如何对他进行正则化?
6.如何修剪模型 ?
回答以上6个问题,也欢迎大家一起提问题一起讨论 。
第一个问题:为什么有时候deeplearning 会看起来简答实际上达不到你的效果 。
或许你会发现xgb很多时候优于深度学习 ,你的loss一直不下降,或者你编写的算法达不到论文的效果 。 因为细节决定了神经网路的成败 。 而我们只关注了他的框架,而忽视了细节 。
1.1 反向传播 + SGD 不会让你的工作那么容易生效
1.2 批规范化不会让你的网络快速收敛
1.3 很多时候他是不会告诉你你错了
一般情况下深度学习都会去训练但是不会抛出异常,比如你设置错误了学习率、正则化强度、神经元个数、层数,或者二分类的时候选择了mse ,没有对数据进行归一化和预处理 他几乎不会报错。但是你确实错误了,作为程序员我们都知道,没有反馈的实验才是最可怕的。 解决这个问题的方法是关注细节 。
每一步我们都对将要发生的事情做出具体的假设,然后用实验来验证它们,或者进行google 看看前人们的经验 ,直到我们发现一些问题。
举例而言,笔者在做vade这个无监督算法的时候,有两个参数没有加入训练,但是网络依旧能够收敛,只是没有实际效果好 。
2.在训练前如何对你的数据作分析?
要解决上面的问题的第一个方式是关心你的数据。
想训练好神经网络,第一步要做的是了解你的数据 , 这一步至关重要 ,需要花费很大啊精力去看数据 ,理解他们的分布 并寻找是否有共用的模式 。
可以注意的,是否有大量的重复的样例,是否有异常的样本 ,看数据是否不平衡 。
要理解自己对数据分类的过程 ,比如1年的行为数据重要,还是2个月的行为数据重要,局部的数据重要,还是全局的数据重要 。空间位置是否重要 。
举例而言,对于推荐和营销场景短期的特征更加重要,对于风控这类场景用户的长期的数据会更好。
此外,关注你的数据预测的结果 ,如果和你理解的结果不一致,那么肯定存在问题 。 比如你觉得一些样本很好预测对,但是预测错了。这里的前提是你有假设某些样本容易预测对。
这是告诉你,需要对模型预测错误的进行一定的分析,而不是盲目的调参,或者觉得这个模型不适合当前场景 。
这是为什么一定大佬们一直强调数据直觉的原因,一旦你有了这些直觉,你就可以用简单的方法 搜索,排序,过滤去验证你的想法。这个时候一般你总能发现一些bug。
如何设计评估框架 Baseline ?
当我们理解我们的数据和场景以后 ,接下来我们要做的就是做简单的baseline。 核心是有完整流程的 反馈 ,目的是 快速定位问题。 所以他要有完整的训练流程和评估 ,从简单的你最熟悉且适用于当前场景的网络结构开始。在此过程中,进行你带有目的和假设性结果的实验 。
一些技巧 :
1. fix random seed
2. 取消不必要的步骤,类似数据扩充,刚开始不要那些花架子,只会干扰你的判断 。
3. 验证你的损失 。验证最后一层就好
4. 较好的初始化 。 依旧是最后一层的偏差,在网络刚开始学习的几层中 ,基本学习到的是偏差 ,所以初始化好的偏差,将会加快训练的速度 ,举例而言如果你做的是回归任务,那么初始偏差可以设为label的均值,如果你有样本不平衡问题 (1:10),那么 初始偏差可以 设置为(0.1) ;类似这样
def make_model(metrics = METRICS, output_bias=None):
if output_bias is not None:
output_bias = tf.keras.initializers.Constant(output_bias)
model = keras.Sequential([
keras.layers.Dense(
16, activation='relu',
input_shape=(train_features.shape[-1],)),
keras.layers.Dropout(0.5),
keras.layers.Dense(1, activation='sigmoid',
bias_initializer=output_bias),
])
initial_bias = np.log([pos/neg])
model = make_model(output_bias = initial_bias)
具体可以参考 tensorflow unbalance classification
去训练一个训练集最优模型
这个 阶段你已经有了一个完整的训练过程 和 Evaluation Pipeline。
那么这个时候我们可以去训练一个 更好地模型 。方法有两个,第一个,让模型足够复杂 ,然后 不断地去修剪它(增加train loss , 较小validatio loss)
1. 网络结构 : 见过太多人喜欢复杂的东西,可能觉得那样显示他们技术很高。喜欢用最新的技术,最新的网络结构。在项目的早期阶段要抵制这种虚拟的技术诱惑,找到最相关的并且简单的先看看效果 。 比如你做图片分类的时候就选择resnet50 就好 。 你做推荐的时候可以先试试 FM 。 而不是直接到了dien,din这种 。 因为他们的复杂是因为特定的情景。我们肯定知道一点,简单的东西更通用,复杂的东西更需要结合场景,大道至简。
2. 优化器选adam: Adam对于学习率的选择容忍度更好 。如果你是高手可能sgd更合适 ,但是在早期阶段建议使用Adam。
3.一次只对比一个 : 比如你有多种数据 ,类似有用户行为序列,用户社交关系,用户画像特征,建议每次只放入其中一种,然后慢慢插入其他特征,进行对比。其他的操作也是这样。
4.不要使用学习率衰减的默认值 : 在我的实验中,我一般使用恒定的学习率值,后期才会调整 。
去解决正则化
当模型在训练集上已经足够好的时候 ,现在需要做的就是正则化 。
1. 首先是数据 , 给与更多的数据 ,一个常见的错误是 花费大量的时间 研究技巧在小数据量上 。
2. 还是和数据相关,对数据进行扩展 。
3 .还是数据 创造数据 ,类似gan。
4. 预训练 ,不论你有或者没有更多数据,你都可以用预训练 。这个时候迁移学习也是可以的。
5. 能用有监督就用有监督 : 不论无监督多么天花乱坠 。 目前最有效的还是有监督 。
6. 减少的维度
7 可以用 pool layer 代替 dense layer 全连接
8.较少batch size ,代表着较大的正则化
9.dropout
10.weight decay
11.early stopping
总结:
1 . 这是个数据的时代,绝不是算法的时代 。不要本末倒置,一味追求算法先进。试着将自己放到数据里面去,而不是天天刷着论文看着公式写着代码。
2. 一定要有自己的判断 ,然后去验证 。
3. 我渴望一个赞,哈哈。
留下几个问题 ?
- 如何修剪模型,用grid search 好么?
- 较小的batch size 为什么代表较大的正则化 ?
- 为什么反向传播 + SGD 不会让你的工作那么容易生效?
最重要的是这个文章的大部分观点来自于特斯拉的人工智能和自动驾驶视觉总监 Andrej Karpathy,大家可以关注他的推特 ;我只是结合自己的理解写了一点。
剩下的文章都在这
evan.wang:小熊猫数据挖掘目录篇zhuanlan.zhihu.com