这篇文章简要谈谈实际项目中的一些策略,这些策略有助于找出项目中出现的问题以及准确快速地找出解决问题的方法。
为什么需要机器学习策略
如果想提高一个深度学习系统的准确率,有很多方法:
- 收集更多数据
- 使训练集的数据更多样化
- 训练更长时间
- 尝试不同的优化算法
- 尝试更大的神经网络
- 尝试更小的神经网络
- 使用正则化
- 改变神经网络的结构
- ...
如果一一尝试这些方法,不仅会话费大量时间,有时得到的效果也非常微小,因此我们需要对具体情况进行仔细分析,从上述方法中找出最关键的方法。
正交化
一些非常有经验的深度学习研究人员非常清楚哪些超参数应该调整,哪些不该调整,这里“该不该”的标准就是,如果一个超参数调整后只会影响系统某一方面的性能,那么这个超参数就是应该调整的。比如,之前的文章讲过,数据集应该被分成训练集、开发集合测试集,那么也许你会发现系统在训练集上和开发集上表现良好,而在测试集上表现很差,那么我们就希望能通过调整几个超参数来提高系统在测试集上的表现,而不影响其在训练集和开发集上的表现。这种调整一个或几个超参数以达到只影响某一方面的性能的特性就叫做正交化。
这里有一些可能出现的问题以及具有正交化这种特点的处理办法:
- 如果训练集的准确率较低,你可以尝试使用更大的神经网络、其他的优化算法;
- 如果开发集的准确率较低,你可以尝试使用正则化、更大的训练集;
- 如果测试集的准确率较低,你可以尝试使用更大的开发集;
- 如果你的系统在测试集的表现没有问题,却在实际应用中表现不理想,你可以尝试改变开发集中的数据,或是换一个损失函数。
单一的量化评估指标
无论你在尝试调整超参数,或是选择不同的机器学习算法,亦或是在构建机器学习系统时尝试不同的配置项,你都会发现如果你有一个单一的量化评估指标,这会让你很轻松地知道新的方法比上一次的方法是更好还是更糟,这会让整个进程加快很多,让我们来看一个例子。
你构建了一个猫分类器 A,然后调整了一些超参数或别的配置项,又得到了一个猫分类器 B,这时如果你想知道两个分类器哪个更好,你可以考察两个分类器的精确率和召回率。所谓精确率就是一个分类器认为是猫的图片中真正是猫的比例,而召回率是指对于所有是猫的图片,你的分类器识别出来了多少张。你可能会发现分类器 A 的精确率很高,而召回率很低,分类器 B 的精确率很低,而召回率很高,这就让你十分苦恼,究竟应该选择哪个分类器才好呢?
出现这种尴尬局面的原因就在于你使用了两个评估指标,因此,与其使用两个指标,倒不如只使用一个,而这个新的指标可以兼顾精确率和召回率,在机器学习中,一种方法是使用 F1 Score,你可以把它理解为是精确率和召回率的平均值,它的计算公式为
其中 P 是精确率,R 是召回率,实际上这计算的二者的调和平均值,但你仍然可以理解为这是一种平均计算。
那么在这个例子中,你只需要考察两个分类器中哪个的 F1 分数更高,那么选择这个更高的就可以了。
满足与优化指标(Satisficing Matrics and Optimizing Matrics)
虽然单一的评估指标看上去很不错,但想找到这种单一的指标并不是很容易,比如:
你很难决定到底应该如何把 F1 分数和运行时间适当的结合起来,如果只是求平均值的话,这样看起来似乎有些过于刻意了,而且当指标很多时,如果把他们结合起来的方法不当,那么即使你得到了一个单一评估指标,这个指标的作用可能也不见得有多好。
怎么办呢?这里还有一些方法,即满足指标与优化指标,什么意思呢,我们仍然沿用上图中的例子。
假设你希望得到的分类器的运行时间必须小于 100 毫秒,在满足这个条件下,F1 分数越高越好,那么你就可以轻松选择分类器 B,而不用再纠结如何把 F1 分数和运行时间结合起来。这个例子中,运行时间就是我们所说的满足指标,意味着它必须要满足一个最低的值,如果低于了这个值,那我们就不予考虑,比如这里的分类器 C,它的运行时间远远超过了 100 毫秒,即使它的的 F1 分数还不错,我们也不会考虑它。这里的 F1 分数就是优化指标,意味着在满足了满足指标的条件下,它越高越好。
可能你一共有 N 个关心的指标,那么你可以只选择其中的一个作为优化指标,剩下的 N-1 个作为满足指标,那么你只需要找到那个满足了所有 N-1 个满足指标的分类器中,优化指标最高的那个分类器就可以了。
当然了,这些指标一般是用在你的训练集/开发集/测试集中的,因此你必须要把你数据集构建成这三部分,下面我们就谈谈如何进行这样的构建。
训练集/开发集/测试集分布
你构建训练集、开发集、测试集的方法将会对构建系统的进展情况产生巨大的影响,这里我们先重点谈谈如何设置开发集和测试集。
开发集有时也被称为交叉验证集,它和测试集有什么作用呢?比如你在训练集上训练了很多不同模型,那么你就可以用开发集来评估这些模型的表现情况,然后就可以选择一个最好的模型,再使用测试集来评估这个模型。
举一个更加具体的例子。你正在构建一个猫分类器,你想在一下国家和地区推广你的分类器:
- 美国
- 英国
- 欧洲其他地区
- 南美
- 印度
- 中国
- 亚洲其他地区
- 澳大利亚
那么如何设置你的开发集和测试集呢?有一种想法是,你可已选择前四个国家和地区中的猫片作为开发集,后四个国家和地区中的猫片作为测试集。事实证明,这是一个非常糟糕的想法 :) 因为在这个例子中,你的开发集和测试集中的数据来自于不同的分布。如果把这个过程比作瞄准——射击的话,就好比你或你的团队花了数月的时间瞄准一个目标,最后射击的时候却打向了另外一个目标,很难想象你们的结果会好到哪里去。
合适的做法是,把你们收集到的所有地区的数据混合起来并随机打乱,再分成开发集和测试集,这样开发集和测试集就都拥有了上述八个国家和地区的数据,即开发集和测试集中的数据具有了相同的分布。
这里还有一个问题,即如何选择开发集和测试集的大小呢,我们下面讨论这个问题。
开发集和测试集的大小
建立开发集和测试集的方式随着深度学习时代的到来而发生着变化。机器学习中有一条经验法则:将你拥有的所有数据 按照 7 : 3 的比例分割成训练集和测试集,如果也需要建立开发集,则可以将 60% 的数据作为训练集,20% 作为开发集,20% 作为测试集。
在早期的机器学习时代,这曾经是非常合理的做法,尤其是在数据规模不大的时候。比如如果你总共只有几百个或几千个甚至几万个样例,使用 70/30 或 60/20/20 的经验法则是非常合理的。但是在现代机器学习中,我们往往需要处理更大量的数据。假如你有 100 万个训练样例,一种合理的做法其实是,使用 98% 的数据作为训练集,1% 作为开发集,1% 作为测试集。
这样做的原因其实很简单,假如你有一百万个样例,那么其中的 1% 就已经有 1 万个样例了,这对于开发集或测试集来说已经足够了。
测试集的作用是在系统开发完成后,帮我们最终评估系统性能的,所以测试集的大小只要能保证对系统的评估结构的高置信度即可,因此除非你需要对系统最终的性能有十分精确的测量,你并不需要你的测试集拥有上百万个数据。
有时候你可能并不需要对最终的系统评估有很高的置信度,那么在在这种情况下没有测试集也是可以的。
不过我觉得还是有一个测试集要安心一些,防止数据在开发集上过拟合得太厉害。
原文地址:Deep Road