导读

机器学习的“难”通常不在于数学,因为机器学习本身不需要很高强度的数学计算,而在于 debugging 难的问题。机器学习 debug 要比普通计算机程序难得多:出现问题的情形多,而且调试周期长。本文深入讨论了这个难题,提出了在 debug 时需要注意的要点。

在过去的几年里,机器学习便捷化方面的技术已经取得了显著的发展:出现了很多相关的网络在线课程、精编书籍和架构理论。这些精编课程对前沿科技研究分析,分解成通俗易懂的语言。而架构理论方面则将普通问题抽象化,与构建机器学习系统相结合形成理论系统。这些发展某种程度上能够使人们打破已有的认知图示,加强对算法工作原理和计算代码的理解。

1.png

机器学习之难在于debug

尽管如此,机器学习仍是一个相对“难”的问题。毫无疑问,提高机器学习算法是一项艰难的科研课题,需要不断的创新、反复的试验、不懈的韧性。而将现有算法和模式与机器学习贯通运用则更难,这也解释了为什么机器学习方面的专业工程师的工资相比普通软件工程师要高出很多的原因。

这里的难通常不在于数学计算,机器学习应用本身不需要高强度的数学计算,而在于前面提到的构建系统,包括如何为工具建立图式以解决实际应用中的问题,这就要对现有算法和模式,两者权衡以及使用限制充分熟悉。机器学习技术是通过对不同类型的模式(比如课程、课本和论文等)进行应用的过程中,对这些模式进行检测。当然,这种知识构建形式存在于计算机科学的所有领域,而不仅仅是机器学习领域。一般的软件工程项目都需要对其他的框架、工具、技术以及设计决策几方面进行权衡。

机器学习的难点在于根本性的调试(debug)难题。机器学习的调试一般发生在以下两种情况:1)算法无法运行,或者2)算法运行不太完美。机器学习“难”的独特性在于,当运行效果不如预期时,想要检测出哪里出了问题极其困难。如果这两种困难同时发生,那么应用修复、升级以及结果显示方面的调试周期将会延长。很少会发生计算运行从一开始直到最后,占用大部分时间去做构建算法的情况。

机器学相比传统软件,调试困难增加了两个维度 

标准的软件工程中,遇到问题解决方案效果不如预期的情况时,一般有两种可能:算法问题和实施问题。举一个简单的递归算法的例子。

5.png

通过这种方法,列举出运行效果不好的故障分析图,如下:

2.png

横轴列出的是算法设计上可能会出现的问题,纵轴是在算法应用上可能会出现的问题。两个维度上都有可能出现问题(如多重应用bug),只有保证算法和应用两方面都精确无误,才能制定出正确的调试解决方案。

调试过程中,需要凭借直觉,结合不同的bug(如编译错误提示,程序输出结果等)信息,去准确判断问题所在。这些信息和启发式方法能帮助缩短锁定范围,快速处理问题。

机器学习有两个方面的常见bug:实际模式和数据。最简单的例子,就如用随机梯度下降算法训练逻辑回归。这里,算法准确包含梯度下降更新方程式,应用准确包括对特性和参数更新的精确计算。数据方面的bug包括嘈杂标签(noisylabels)、预处理过程中由于缺乏监控信号或数据不足导致的错误。模式bug包括建模能力的实际限制。比如,下图展示了在非线性决策边界中使用线性分类器。

3.png

调试过程从2D网格到4D超立方体(这里只显示了三个维度),第四个数据维度,我们可以想象成是这些立方体的序列(注意这里只有一个小立方体是正确的解决方案)。

4.png

机器学习极其“难”的原因在于,如果在一个维度上有 n 种错误的可能,2D维度中的错误就有 n*n 种可能,4D维度中的错误就有 n*n*n*n 种可能。这种情况下,依据现有信息,建立直觉去发现bug就显得尤为重要。

幸运的是,机器学习算法中,有更多的信号可以用于判断哪里出了bug,比较重要的有:训练集和测试集的功能缺失图(plots)、开发数据集中算法的实际输出结果,以及算法的中间计算汇总统计。

如何解决延迟的调试周期

另一个导致机器学习调试非常困难的因素是调试周期长。通常,从运行潜在修复功能到得出结果是否可行,需要花上几个小时甚至几天的时间。网页开发中,具备自动更新功能的开发模式可以极大地提高开发效率,因为这意味着可以最大限度地减少开发流程中出现的bug事件。而在机器学习中这很难实现,因为在数据集中训练算法需要花上几个小时甚至几天的时间。而深度学习模式更有可能导致调试周期延长,这就必须要进行“并行”试验范式。对于机器学习开发人员来说,同时运行多个试验,是因为算法训练是开发中的主要难点,通过多程序同时运行以开发指令流水(对于程序开发者而不是应用者)。强制性地多程序同时运行的主要缺点在于顺序调试和试验过程中,不能运用累积经验。

机器学习通常被归结为一种直觉开发的艺术,有了这种直觉,在很多维度都可能出现bug(或可以提高)时,可以判断出了bug(或需要提高)的地方在哪。这是构建机器学习项目的一个重要技巧,即当调试范围内呈现出的信号,你会开始利用这个信号尝试判断问题出在哪。我工作过程中经常会出现类似的情况。

举例来说,我最早遇到这样的问题是在训练神经网络时,总是出现周期性的训练功能损失。这些功能损失在经过某些数据时会发生延迟,但很快便返回到一个很高的数值。经过很多的试验和错误之后,我意识到这通常是因为训练集没有被正确地随机化(这看似是一个数据问题,但实际上是一个应用问题),还有一个问题就是,在使用随机梯度算法时,只处理小部分的数据。

总的来说,快速高效的调试是一个非常需要的技巧,可以应用到现在的机器学习流水线中。

来源:ai.stanford.edu 作者:S. Zayd Enam 原文链接:http://ai.stanford.edu/~zayd/why-is-machine-learning-hard.html?


更多内容请关注我们的官方微信公众号“生信圈”,微信ID:bioinfor-club
生信圈二维码.jpg长按二维码关注