Deep Learning Note: 3-3 比较人类水平

1. 与人类水平做比较的原因

  最近几年,将机器学习系统的性能与人类水平进行比较越来越流行,一个原因是随着深度学习的发展,机器学习算法的性能有了大幅的提升,在很多领域,机器学习算法的性能已经可以与人类相比。另一个原因是在一些人类也可以解决的问题上,更容易设计和搭建机器学习系统来解决这些问题。

  对于很多机器学习任务,随着时间的推进,在算法的性能到达人类水平之前,进展会比较快;而当算法性能超过人类水平后,算法性能的提升速度就会降低,其错误率最终会无限接近于贝叶斯错误率(Bayes Error Rate),贝叶斯错误率是可能达到的最佳错误率。例如对于语音识别,可能有一些语音非常不清晰,根本无法识别说的是什么,所以识别率无法达到 100%。

  算法性能超过人类水平后,性能提升速度变慢的原因主要有两点。首先,对于很多任务,人类的水平和贝叶斯错误差距不大,例如人类非常善于语音识别。对于这些任务,当算法超过人类水平时,就已经离贝叶斯错误不远了,提升空间十分有限。其次,当算法性能低于人类水平时,更容易通过一些手段来提升性能。对于人类非常擅长的领域,当机器学习算法的性能低于人类水平时,可以:

  • 通过人类获取标记数据,即让人来标记数据,这样算法就可以有更多的数据用于训练。
  • 通过手工错误分析,理解算法与人类的差距,如让人来分析算法预测错误的样本,尝试找出算法预测错误的原因。
  • 可以更好地分析偏差和方差问题。

  当算法性能低于人类水平时,通过将算法性能与人类水平进行比较,可以更容易地找出提升算法性能的方法,这也是机器学习特别擅长解决人类也能解决的问题,并迅速达到甚至略微超越人类水平的原因。而当算法性能超过人类水平后,就难以通过以上方法来提升算法的性能了。

2. 可以避免的偏差

  在训练过程中,我们希望算法能在训练集上获得很好性能的同时,又要避免在训练集上的性能过好,以至于发生过拟合。通过与人类水平进行比较,我们可以知道算法到底要在训练集上达到什么样的性能才是最佳的。

  假设对于某个任务,人类和某个分类器的错误率如下:

  • 人类错误率: 1%
  • 训练集错误率:8%
  • 开发集错误率:10%

  从上面的数据可见,训练集错误率和人类错误率之间有较大的差距,说明算法没有很好地拟合训练集,需要集中精力降低偏差。

  假设对于另一个任务,人类和某个分类器的错误率如下:

  • 人类错误率: 7.5%
  • 训练集错误率:8%
  • 开发集错误率:10%

  从上面的数据可见,训练集错误率和人类错误率差不多,提升空间不大;而开发集错误率和训练集错误率之间有较大的差距,说明算法不能很好地泛化,需要集中精力降低方差。

  这里使用人类错误率作为贝叶斯错误率的估计,准确来说,人类错误率要高于贝叶斯错误率,但通常人类的错误率与贝叶斯错误率很接近,尤其是在计算机视觉领域。

  从上面的两个例子可以看出,虽然两个例子中的训练集错误率和开发集错误率都相同,但通过比较人类在具体任务和场景中的水平(或者说是贝叶斯错误率),我们可以对算法应该达到的性能做出估计,据此采取不同的手段来提升算法的性能。

  训练集错误率和贝叶斯错误率之间的差距称为可以避免的偏差(Avoidable Bias),我们希望提高算法性能以接近贝叶斯错误率,但不可能超过贝叶斯错误率,除非发生过拟合。测试集错误率和训练集错误率之间的差距是偏差(Variance),通过比较可避免的偏差和方差,有助于定位偏差和方差的相关问题,从而选择合适的方向去进行优化。

3. 理解人类水平

  前面使用人类水平的错误率作为贝叶斯错误率的估计,那么要如何定义人类水平呢?

  例如对于某个识别 X 光片的任务,人类存在不同的错误率:

  • 普通人的错误率:3%
  • 普通医生的错误率:1%
  • 有经验的医生的错误率:0.7%
  • 一群有经验的医生进行会诊的错误率:0.5%

  虽然不同的人具有不同的错误率,但可以知道人类所能达到的最低错误率为 0.5%,使用 0.5% 作为人类水平的错误率,即贝叶斯错误率的估计。不排除人类可能通过其他手段(如邀请更多的医生会诊)获得更低的错误率,但从上面已知的数据可知,贝叶斯错误率一定不会高于 0.5%。

  从发表论文或部署机器学习系统的角度,对人类水平可能会有不同的定义。如选择普通医生的错误率 1% 作为人类水平,因为只要算法或系统的性能能够超过普通医生,这个算法或系统就能够产生实际的意义和效用,有进一步研究或部署的价值。

  综上所述,对于不同的目的和场景,可以选择不同的人类水平。对于这个识别 X 光片的任务,如果目的是估计贝叶斯错误,那么就选择最低的 0.5% 作为人类水平;如果目的是评价一个机器学习系统是否有部署的价值,那么使用普通医生的水平作为人类水平是合理的选择。

  仍以上面识别 X 光片的任务为例,可选的人类水平有 1%、0.7%、0.5% 三种情况,假设对于某个模型:

  • 训练集错误率:5%
  • 开发集错误率:6%

  对于此种情况,无论人类错误率选择 1% 还是 0.7% 还是 0.5%,训练集错误率和人类错误率之间的差距(即可避免的偏差)都不小于 4%;而开发集错误率和训练集错误率之间的差距(即方差)只有 1%。无论选择何种人类错误率,都可以判断模型存在高偏差问题。

  假设另一个模型的情况如下:

  • 训练集错误率:1%
  • 开发集错误率:5%

  对于此种情况,训练集错误率和人类错误率之间的差距都小于 0.5%;而开发集错误率和训练集错误率之间的差距为 4%。此时无论选择何种人类错误率,都可以判断模型存在高方差问题。

  而对于下面的情况:

  • 训练集错误率:0.7%
  • 开发集错误率:0.8%

  对于此种情况,算法已经达到了有经验的医生(0.7%)的水平,应当使用 0.5% 作为人类水平,训练集错误率和人类错误率之间的差距为 0.7% – 0.5% = 0.2%,开发集错误率和训练集错误率之间的差距为 0.1%,二者差距不大,但偏差的问题较大。此时如果使用 0.7% 作为人类水平,就会得到训练集错误率和人类错误率之间的差距为 0,从而误判模型存在高方差问题,而实际上人类能够达到更好的水平(0.5%),模型存在更多的可避免的偏差。

  上面的例子也展示了当算法性能达到人类水平后,算法性能提升变得更加困难的原因。当算法达到了有经验的医生的水平(0.7%),如果对贝叶斯错误率估计不准,例如不知道医生会诊可以达到更低的 0.5% 的错误率,就无法准确知道算法性能与贝叶斯错误率的差距有多大,对模型存在的问题发生误判,影响其性能的进一步提升。而在算法性能与人类水平存在较大差距时,更容易判断模型存在的问题,从而采取合适的手段有效地提升性能。

4. 超越人类水平

  上面提到,在算法性能与人类水平存在较大差距时,更容易判断模型存在的问题。例如对于某个任务,人类水平和某个算法的错误率如下:

  • 一组人的错误率:0.5%
  • 一个人的错误率:1%
  • 训练集错误率:0.6%
  • 开发集错误率:0.8%

  对于上面的情况,使用一组人的错误率 0.5% 作为人类水平,此时训练集错误率和人类错误率的差距为 0.1%,开发集错误率和训练集错误率的差距为 0.2%,高方差的问题较大。

  而当算法性能达到人类水平后,算法性能提升变得更加困难,如下面的情况:

  • 一组人的错误率:0.5%
  • 一个人的错误率:1%
  • 训练集错误率:0.3%
  • 开发集错误率:0.4%

  此时训练集错误率 0.3% 小于人类所能达到的最低错误率 0.5%,一种情况是模型发生了过拟合,另一种情况是实际的贝叶斯错误率更低(如 0.1%)。但从已知的信息中,我们无法做出判断,不知道应该着力降低偏差还是降低方差,由此也降低了算法性能提升的速度。另外,当模型性能超过了一群人合力的水平,就更难依靠人类的直觉来找出算法的缺点。对于上面的例子,在算法错误率低于 0.5% 后,虽然仍可能继续提升算法性能,但所能依赖的工具变得更少,前进的方向也变得不明确起来。

  在一些领域中,机器学习算法的性能大幅超过了人类水平,例如在线广告中预测用户点击广告的概率,进行商品推荐、预测交通/物流耗时、贷款审批等。在这四个领域中,算法都是从海量的结构化的数据中进行学习(如记录用户点击过的广告的数据库),算法所看过的数据量远远大于任何人类,计算机更擅长从海量数据中提取统计上的特定模式,其性能更容易超过人类水平。而对于自然感知上的问题,如计算机视觉、语音识别、自然语言处理等,这是人类非常擅长的领域,计算机要在这些领域超越人类往往更加困难。虽然让计算机在自然感知的问题上超过人类水平并不容易,但随着深度学习的发展,对于某些单一的监督学习问题,如语音识别和某些图像识别的领域,计算机的水平已经可以超过单个人类。

5. 提高模型性能

  监督学习算法的训练过程相当于努力完成以下两个目标:

  1. 可以非常好地拟合训练集,相当于可避免的偏差很低。
  2. 算法在训练集上的性能可以泛化到开发集和测试集,相当于方差很低。

  通过比较训练集错误率和人类水平(即贝叶斯错误率的估计),可以得知可避免的偏差的大小,即在训练集上的性能还有多大的提升空间;通过比较开发集错误和训练集错误率,可以得知方差的大小,即在泛化能力上还有多大的提升空间。

  应用正交化的思想,我们可以独立地解决高偏差和高方差的问题。解决高偏差问题的方法有:

  • 训练更大的模型
  • 训练更长时间 / 使用更好的优化算法(如使用动量、RMSprop、Adam 等)
  • 调整神经网络结构(如调整网络层数、激活函数,使用 CNN、RNN 等)/ 进行超参数搜索

  解决高方差问题的方法有:

  • 获取更多数据
  • 正则化(如 L2 正则化、Dropout 等)
  • 调整神经网络结构 / 进行超参数搜索