高效构建机器学习系统

高效构建机器学习系统

介绍——机器学习策略是什么?

1. 构建机器学习系统

训练效果不好的时候:

  • 获得更多数据
  • 数据集多样性不够
  • 训练更长时间
  • 使用Adam而非梯度下降
  • 尝试更大的网络
  • 尝试更小的网络
  • 尝试Dropout
  • 添加L2正则化
  • 添加其他网络结构
    • 激活函数
    • 隐藏单元
    • ……


使用正确的方法,很重要,哪些值得尝试,哪些可以直接放弃。

2. 正交化(Orthogonalization)

挑战之一是,可以尝试的方向太多了,如需要调整的超参数;高效的机器学习人员都非常清楚需要调整什么,这一过程称为:正交化(Orthogonalization)。
image.png
想象一个电视机,可以通过按钮进行调整画面,如果一个按钮可以同时调整多个功能(宽、高、梯形畸变等),则正确调整画面到正中央几乎是不可能的。所以在进行设计的时候,确保每个旋钮只能进行一个参数的调整,使得画面更容易调整到正中央,这就是正交化(Orthogonalization)。另一个例子是汽车的例子:image.png
在这里,正交化指两个变量(速度和角度)能够独立完成控制,而不是一个操纵杆可以同时控制油门和方向。
这和机器学习系统有什么联系呢?机器学习系统也需要通过调整系统旋钮,保证四件事准确无误。

  • 第一,通常确保至少训练组运行良好(为此需要进行一些可行性评估,这取决于应用,需要与人类的一些性能比较)——建立一套旋钮(Bigger network、Adam等)
  • 第二,开发组运行良好——再建立一套旋钮(Regularization、Bigger Training set等)
  • 第三,测试组运行良好——再建立一套旋钮(Bigger dev set等)
  • 第四,在实际情况中运行良好——再建立一套旋钮(Change sev set or cost function等)
  • 一般不用early stopping,它同时影响了一和二。

目标——如何诊断机器学习系统的问题?

1. 单一评估指标(Single number evaluation metric)

无论你是选择超参调优,或是选择不同的机器学习算法,还是在构建机器学习系统时,尝试不同的配置项,你都会发现:如果你有单一的量化评估指标,可以让你知道新的方法比上一次是更好还是更糟,那么整个进程会加快很多。所以当团队在启动一个机器学习项目时 我常常建议,设置一个单一的量化评估指标。
应用机器学习有一个非常经典的流程:我们通常是先有一个想法,用代码实现它,再实验验证它的效果。然后通过验证的结果来改进之前的想法,不断的在这个循环中改进你的算法。让我们举个例子,你构建了某个分类器A,通过调整超参和训练集或者其他什么方法 ,你训练得到了一个新的分类器B,这时一个合理的评估你分类器好坏的方法,就是去看它的精确率和召回率
image.png
问题就在于把他们作为评估指标时,如果分类器A的召回率比较好,而分类器B的精准率更好些,你就不能确定究竟哪个分类器更好了。所以这个时候可以引入一个单一评估指标(Single number evaluation metric),F1 Score。
image.png
另一个例子是使用不同的算法在不同的地区进行评估时,这时,我们可以取平均值,作为单一评估指标,以更好更快的判断出算法的好坏,以及更快地对机器学习算法进行迭代。
如何效率的设置评估指标?除了单一评估指标外,我将和你分享如何设置优化和满意度矩阵。

2. 满足和优化指标(Satisficing and Optimizing metric)

比如,你决定关注猫分类器的分类准确率(accuracy),它可以是F1分数(F1 score)或者别的什么精确度度量。但是假设,除了准确率之外你还关心运行时间,也就是对一个图像分类需要多少时间。
image.png
在这个例子中我们说准确率是优化指标,因为你想要最大化准确率。你希望准确率尽可能的高,但是运行时间是我们我们所说的满足指标,意味着它必须足够好。必须<100毫秒,一旦超出即不予考虑,至少不大考虑,所以用这种方式对准确率和运行时间,进行权衡或者说通盘考虑,相当合理。(比如Wakewords,Trigger words,如Hey Siri,等,就需要在保证速度的前提优化准确度)

通过定义优化指标和满足指标,你就有了挑选"最优"分类器的明确方向。

总而言之,如果你同时关心多项指标,你可以将其中的一样设为优化指标,使其表现尽可能的好,将另外的一项或多项设为满足指标,确保其表现满足要求。大多数情况下他们都会优于最低标准,这样一来你就有了一个几乎自动的,快速评价模型和选择"最佳"模型的方法。
现在这些评价指标必须在训练集/开发集/测试集上评估计算,那么另一件你需要做的事情就是建立训练集/开发集/测试集,我将与你分享一些如何建立训练集/开发集/测试集的指导原则。

3. 训练集/开发集/测试集分布(Train/dev/test distributions)

同样的团队,甚至是大公司的团队,设置数据的方式确实会减缓,而不是加快团队的进展。

3.1 开发集和测试集

记住一个重要的地方,设定开发集和你的评估方法时,就像放置一个目标然后告诉你的团队你们的目标是什么。因为你一旦确定了开发集和评估方法,团队就可以很快尝试各种不同的方法并进行实验,很快利用开发集和评估方法来评估选择器并选取最好的一个。所以机器学习团队通常很擅长多线执行,通过各种尝试越来越接近目标,在这种评估方法和开发集上做得更好。
image.png
我们在设置左侧的开发集和测试集要注意的问题是,你的团队可能用了数个月靠拢开发集,当你最后在测试集测试时,这四个上面的国家或地区的数据,可能和你开发集中的数据很不同。所以你可能很惊讶的发现,你们辛辛苦苦在开发集上做的努力,在测试集上表现的并不好(可以用Shuffle打乱数据集)。
image.png

推荐的设置开发集和测试集的方法是:选择的开发集和测试集能够反映出将来预计得到的数据,和你认为重要的数据。特别地,这里的开发和测试集应该来自相同的分布。

所以无论未来你需要预测什么样的数据,一旦你试着获取这样的数据,无论这个数据是什么,把它同时放进你的开发和测试集中。因为这样你就瞄准了实际上你想要瞄准的目标,团队也可以有效的开发,可以在同一目标上表现良好。

3.2 训练集:开发集和测试集的大小

你也许听说过机器学习中的一条经验法则,那就是将你拥有的所有数据,按照70/30的比例分割成训练集和测试集。如果需要建立训练集开发集和测试集,可以将60%的数据作为训练集,20%作为开发集,20%作为测试集。在早期的机器学习时代,这曾经是非常合理的做法。
image.png
假如你有100万个训练样例,那么一种合理的做法是,使用98%的数据作为训练集,1%作为开发集,1%作为测试集。那么其中的1%就已经有1万个样例了,这对开发集或测试集来说已经足够了。
image.png
那么测试集应该多大呢?测试集的作用是在系统开发完成后,帮我们评估最终系统的性能。因此测试集的大小只要足够能保证对系统整体性能评估的高置信度即可。
因此除非你需要对最终系统性能有非常精确的测量,否则你的测试集并不需要上百万个样例。或许你认为1万个样例就可以,提供足够的置信度来评估性能,或者也可能需要10万个或更多才够。这个数目可能远小于总数据量的30%,这取决于你所拥有的总数据量。在某些应用场景中,可能你并不需要对最终系统整体性能的评估具有很高的置信度。也许你只需要训练集和开发集,那么我认为没有测试集也是可以的。**我绝对不是在建议大家在开发系统时舍弃测试集,我觉得有一个单独的测试集会更安心。**你可以在上线前使用测试集,得到对系统性能的无偏估计。但是如果你有一个很大的开发集,你相信不会对开发集过拟合得太厉害,那么只使用训练集和开发集也不是完全不合理,不过我一般不建议这样做。
总的来说,在大数据时代我认为传统的70/30法则已经不再适用了。现在的趋势是使用更多数据作为训练集,使用较少的数据作为开发集和测试集。尤其是当你的数据集很大的时候,**经验法则是确保开发集的大小足以达到其目的。**也就是帮我们评估不同的想法,让我们能更好地从A或B中做出选择。而测试集的目的是对最终的分类器进行评估,你只需要让测试集的大小足以满足这一目的即可。

3.3 调整开发集/测试集和指标

有时候,项目进行到一半,你可能会发现靶子放错了位置,这时候就应该移动你的靶子。重点是,如果你对原有的误差指标不满意,那就不要将就着使用这个你不满意的指标,而是定义一个新的指标 使其能够更好地反应你的偏好,以符合你对更好的算法的定义。
image.png
**
指导方针是,如果在你的指标上以及在当前开发集和测试集的分布上表现得很好,不能对应于在你真正关心的应用场景上也表现得很好,这时就需要修改指标和/或开发集和测试集。

建议是即便你无法定义一个完美的评估指标和开发集,你也应该尽快将它们确定下来,以此来驱动你们团队的迭代速度。如果之后发现选的不好,你有了更好的想法,你完全可以再进行修改。
不建议在没有任何评估指标和开发集的情况下进行长时间的开发。因为这实际上会降低你们团队进行迭代和改善算法的效率。

优化——与人类表现比较

为什么与人类表现比较?
两个主要原因:第一,是随着深度学习的发展,机器学习算法的效果迅速提高,使它应用在很多新领域,算法和人相比也更有竞争力;第二,在某些领域用机器学习系统解决问题的效率,比用人工来解决问题的效率要高。所以,人们自然要比较机器学习和人类表现孰优孰劣。
image.png
这个紫线不管你用多少年,你永远不会超越贝叶斯错误或贝叶斯最优误差。事实证明,进度往往相当快直到你超越人类的表现。你若超越了人类的表现,有时反而慢下来,我认为有两个主要原因:

  • 第一,人类级别的表现在许多任务中都离贝叶斯最优误差不远,人非常擅长看着图像去分辨是否有一只猫,或收听音频并写出字幕。因此,可能算法超越人类级别的表现之后并没有那么大的改善空间。
  • 第二,只要你的表现还不如人类水平,那么实际上你可以用某些工具来提高。而当你超越了人类的水平后,就很难再有工具来提高了。

image.png
只要人类仍表现优于任何算法,你可以让人看看你的算法算错的例子,然后了解为什么人可以做到,但该算法却搞错了,你也可以得到更好的偏差分析和方差。但是只要你的算法仍然是差于人类,你有这些重要策略去优化你的算法。而一旦你的算法做的比人类优异,这三招将变的很难应用。

1. 可回避的偏差(Avoidable bias)

如何使学习算法在训练集上表现良好,但是有时候你并不希望它好过头。如果你知道了人类的水准是什么程度的话,那你就能够知道,对于训练集来说,怎样的表现算是好但没有过头。
image.png
在左边的例子中,8%的训练集错误已经是非常高了,因为只要采取减小偏差的策略,就能把错误降低到1%。而在右边的例子中,如果贝叶斯误差高达7.5%,我们在这里用人类的误差作为代理变量来估算贝叶斯误差,如果你认为贝叶斯误差确实是接近7.5%的话,那你就会知道训练集上的误差降低的空间就不会太多。而你也不希望错误率低于7.5%太多,因为有可能只有过拟合才会达成那种结果。相反,不妨就接受这个数据集上表现一般的事实,把重点放在开发集与训练集的2%的差距上,然后针对它尝试一些消除方差的方法,譬如正则化或者获取更多训练数据。

可回避的误差(Avoidable bias)这个术语就表现出了训练时能达成的误差的下限,也就是贝叶斯误差即7.5%。你大概不希望训练集上的误差比它小,所以与其说在训练集上的误差是8%,也就是说在这个例子中测量出的偏差是8%,不如说可回避的偏差是0.5% 。

2. 理解人类表现(Human-level performance)

当你定义清楚“人类表现”这个词之后,会帮助你更好的驾驭你的机器学习项目。
image.png
那么在上述情况中,什么是“人类水平”错误呢?
**你想要一个贝叶斯误差的替代或估计值,这里有一个专家团队经过讨论和辩论可以达到0.5%的错误率,所以我们知道贝叶斯误应差小于等于0.5%。**因此因为某种情况下一个专家团队可以达到0.5%的错误率,所以直接的根据定义,最佳误差一定是小于等于0.5%的。我们不知道最小误差是多少,也许有一个医生团队人数更多,经验更丰富,错误率可以更低,也许比0.5%更低。但是我们知道最佳误差不可能大于0.5%,所以在这里我就选择0.5%作为贝叶斯误差的估计值 ,所以就可以定义人类水平的表现是0.5%。

在定义人类水平误差时,还需要搞清楚你的目的是什么。如果目的是展示你超过了一个普通人的判断水平,并让他人支持你开发系统,或许这是一个很好的定义。但是如果你的目的是作为贝叶斯误差的代替器,那上面这个定义会更合适。

image.png
对于一个人类可以很好完成的任务如果你有人类水平误差估计值,这时你想搞清楚偏差和方差,你可以使用人类水平的误差作为贝叶斯误差的替代值或者近似值。
你的训练误差和贝叶斯误差的差距告诉你,可以避免的偏差(Avoidable bias)问题有多大,而训练误差和开发集误差的差距告诉你方差(Variance)问题有多大。你的算法是否可以做到更好的泛化,我们这里讨论的和之前把训练集误差和0%比较有很大的不同。

概括一下,人类水平表现的值给你提供了对贝叶斯误差的估计,这让你可以更快速的决定你的算法更应该降低偏差还是方差。这个方法在你超越人类水平表现之前是一直有效的,那是你可能找不到一个好的贝叶斯误差估计了。

3. 超越人类表现(Surpassing human-level performance)

我们接下来要讨论的是,当你想要达到超越人类水平的性能目标时,将会遇到的情况。我们之前已经讨论过 当性能接近或超过人类水平时,机器学习的进展将会越来越慢,我们通过一个例子来看看为什么会这样。
image.png
基于这个例子给出的信息,实际上你并没有足够的信息,来判断应该专注于减少算法的偏差还是方差。所以,你取得进展的效率就降低了。此外,如果你的误差已经比人类团队通过讨论和辩论才能达到的误差还小,那么你就更难以依靠人类的直觉来判断还能从哪些方面来优化算法的性能了。在这个例子里,一旦超过了这个0.5%的阈值,对这个机器学习问题进行优化的 方法和方向就变得不明确了。这并不意味着你无法取得任何进展,你仍然可能取得重大进展,只是用于指明方向的工具不那么好用了。
现在机器学习在很多问题上,已经取得了大大超过人类水平的性能。
image.png
以上都四种情况都是基于结构化数据训练出来的,这些都不是自然感知(Natural Perception)问题,不是计算机视觉
或者语音识别,或自然语言处理的任务。人类非常擅长自然感知的任务,这使得计算机在自然感知领域超过人类水平,虽然是可能的,但是难度更大一点。现在在一些语音识别、计算机视觉(如医学影像等)上,计算机算法已经超越了人类表现。

4. 提升模型表现(Improving your model performance)

我们已经讲过正交化、如何设置开发集和测试集、用人类水平代表贝叶斯误差以及如何估计可避免偏差和方差。让我们把这些结合成一套准则,用于改进你的学习算法。
监督学习的两个基本假设:
image.png
image.png

错误分析——下一步该做什么

1. 开展错误分析

image.png
假设你正在做一个猫分类系统,在验证集上准确率达到90%的或错误率达到10%,假设这比你想象中的结果要差很多。也许你的一个队友,在看一些算法分错了的样本,并且发现它将狗误认为猫了。那么问题来了,如何使算法更好?特别是在狗身上,对吗?**你可以有侧重点,收集更多狗的图片,或设计针对狗特有的特征之类的,为了使猫分类器在狗上表现更好。**所以它不再将狗误判为猫,所以问题是你是否应该继续并且开始一个项目侧重于狗的问题?

  • 假设验证集中分错的100张中有5张是狗,这意味着在这100张图片中特指你分错的这100张,即使完全解决狗的问题,也只在这100张中多分对了5张。换言之,若只有5%的错误是狗照片,如果你在狗的问题上花了大量时间,最好的情况也就是你的错误率从10%下降到9.5%,对吗?这不是一个好的选择。这种情况有时我们把它称为表现上限。
  • 假设验证集中分错的100中中有50张是狗,现在你可以更确定地把时间花在狗的问题上,在这种情况下,如果你真的解决了狗的问题,你的错误率可能将从这10%下降到5%。

有时我们会贬低手动操作或使用太多人工判断,但是如果你在构建应用系统。那么这个简单的计数过程,也就是错误分析,可以节省你很多时间。在决定什么是最重要的,或哪个方向最有希望值得关注。实际上如果你想检查一下错误标记的验证集,也许只需要花5到10分钟,人工浏览100张图片并数出它们中有多少是狗。
image.png
**这个分析的结果不是你必须处理模糊的图像,这不给你一个严格的数学公式告诉你该怎么做。**但它给你一个最好的参考做法,它也告诉你,例如不管你在狗或Instagram的图像上做得有多好,在这示例中,你最多只能提高8%或12%的准确率,而你可以针对大猫图像或模糊图像能有更好的结果。现在这个能提高多少准确率的上限值要高得多,根据你有多少想法,来提高对大猫的判断,来处理模糊图片。你可以选其中一个,如果你队伍中有足够的人手,你可以分成两个不同的团队,一个改善大猫的误判,另一个团队改善模糊图片的误判。

综上所述,要进行错误分析,你应该找到一套在你验证集中错误标识的样本,并按假阳性和假阴性来看,并计算不同类别中的误判个数。在此过程中,可能会促使你提出新的错误类别,就像我们看到的,当你浏览样本的时候,有很多Instagram滤镜或者Snapchat滤镜,他们也搞乱了分类,您可以在过程中创建新类别。但通过对不同类中错误标识的例子计数,通常这将有助于你判断优先级 或给你新方向的灵感。

当你在做错误分析时,有时你会注意到在开发集中有些是错误标签的,那你该怎么办呢?

2. 清理错误标签数据

监督式学习的问题中,数据由输入X和输出的标签Y组成。如果检查数据集,你发现有些输出标签Y错了,(也就是说)你的部分数据,有错误的标签,你值得花费时间去修正这些标签吗?
image.png
错误标记的例子是指:如果在数据集中,不管是训练集、开发集还是测试集,Y的标签,不管人给这个数据贴的标签是什么,实际上是错误的。这个图片实际上是个狗,所以Y实际上应该是0。

  • 深度学习算法对训练集中的随机错误很稳健。只要这些错误不是那么偏离随机分布,而可能只是由标记的人偶然的疏忽造成的,比如随机按下了错误的键(如果这些错误是相当随机的),那么我们基本可以不管(这些错误),不用花费太多的时间去纠正它们。
    • 当然了,仔细检查你的训练集和标签并且纠正它们,肯定是无害的。有时候,这是很值得花费时间去做的, 但你也可以不做,只要总数据量够大, 而且实际错误标记的数据占比不高。
  • 深度学习算法对系统误差不那么稳健。比如说,如果你的标记员一直把白色的狗标记为猫,那就会产生问题,因为你的分类器会学着把所有的白色的狗分类成猫。但是随机错误,或者接近随机的错误,通常对深度学习算法来说,不算太糟糕。

那么,对于开发集和测试集中的数据呢?
如果你担心有影响,这些错误标记的数据(对开发集和测试集)的影响,一个比较推荐的做法是,在错误分析的过程中增加一列,去统计Y的标签错误的数量。
image.png
所以,现在的问题是我们值得花费时间去纠正这6%的错误标记的例子吗?
我的建议是,如果这些错误对你评估算法在开发集上的效果,有很大的影响的话,那就继续做吧,花时间去纠正这些错误标签。但是如果对你用开发集去评估模型没有太大影响,那你的时间最好不要花在这上面。
image.png
如果你决定探究开发集,手动重新检查标签,并且尝试纠正一些标签,这里由一些额外的指南或者说原则供参考。

  • 首先,不管在什么情况下,我都会鼓励你去同时应用开发集和测试集。我们之前谈论过,关于为什么你需要开发集和测试集服从同样的分布。其中开发集是你优化的目标 当你的模型在开发集上表现良好时,你会希望这个良好的性质能推广到测试集。所以当开发集和测试集服从相同分布时,你的团队就能工作得更有效率。因此,如果你要探究并纠正开发集中的一些问题,我会建议将这个过程也应用到测试集,以确保它们依然服从同样的分布。所以我们可以雇人来更仔细地检查这些标签,对你的开发集和测试集,重复这样的工作。
  • 第二,我强烈建议你考虑检查你的算法准确预测和错误预测的例子,去检查你的算法错误预测的例子很简单,只要看那些需要被纠正的。不过有时可能即使你预测对了,但它却是需要被修正的,如果你只纠正那些预测错的样本,那么当你评估算法错误率时,就会有更大的偏差。这给你的算法带来一点不公平的优势,我们只是尽量仔细检查它错的部分,不过对于模型预测对的样本,也要进行检查。因为模型可能仅仅因为运气好而预测对了 此时纠正一些标签的话,就去除运气成分并导致本来(因运气)预测对的变成预测错误。
  • 最后,如果你探究开发集和数据集,去纠正一些标签,你可能应用同样的方法到训练集上,也可能不。记住,实际上纠正训练集中的标签不那么重要。很可能你决定纠正开发集和测试集中的标签,这部分数据更小,比起训练集,你可能不会把额外工作都用来纠正那些在训练集中的标签,实际上这是可以的。

下面我想分享一些想法,并说明错误分析是如何与你要建造的新的机器学习项目配合的。

3. 快速搭建你的第一个系统,然后迭代

如果你在研究一个,全新的机器学习的应用,我常给人们提的一个建议是:你应该迅速构建你的第一个系统,然后进行迭代。
image.png
有这些以及很多其他的事情你可以做,来改善语音识别系统。更普遍地来说,对于几乎所有的机器学习应用,可能有50个不同的方向去研究,每个方向都是合理的,会使你的系统更好,但挑战是如何从中选择需要关注的问题。

我们的建议是如果要构建一个全新的机器学习应用,你要迅速构建第一个系统,然后迭代。即你快速建立一个开发/测试集以及度量指标,这就决定了你的目标在哪儿。如果你发现出错了,你始终可以稍后移动目标,但是至少在某处设立一个目标,然后我建议你快速建立一个初步的、简单的机器学习系统。找到训练集训练它,然后看(结果),开始观察并理解你的系统。当你构建了初步的系统,你就可以用偏差/方差分析和错误分析进行系统分析。

如果你正在将机器学习算法投入到一个新的应用,如果你的主要目标是构建可用的东西,而不是去发明一个新的机器学习算法,这是不同的目标。那么你的主要目标是建造运行得很好的东西,我会建议你建造迅速的早期的东西,用它来进行偏差/反差分析,用它来做误差分析,用这些分析的结果去帮助你辨别接下来做什么。

4. 不匹配的训练集和开发/测试集

深度学习算法都希望有大量的训练数据,要使它运转在最佳状态,训练集中要有足量已标记训练数据。这导致很多团队将能找到的任何数据都塞进训练集,只为有更多的训练数据,即使有些甚至很多这种数据来自于与开发集和测试集不同的分布。因此在深度学习时代,越来越多的团队正在使用的训练数据并非来自与开发集和测试集相同的分布。
针对这种情况,这里有一些需要了解的微妙之处和一些最好的实践方法。
image.png
**Option1:**优点是这样一来你的训练/开发/测试集都来自于同一分布,易于管理。而(巨大的)缺点是你的开发集,它有2,500个样例,但是大部分来自网页图片的分布,而不是你真正关心的来自移动应用图片的分布。请记住设置开发集的目的是告诉你的团队该往哪里瞄准,现在你正在瞄准的目标正在花费大量的时间优化的是网页图片的分布,这不是你想要的,所以不建议采用方案一。(那么2,500个样例中,来自于网页的数量的期望值是2381,这是期望确切的数字将取决于随机混合的结果,但是平均只有119个样例来自于移动应用上传。)
**Option2:**优点是你瞄准的是正确的目标,你在向你的团队表明我的开发集数据来自于移动应用,而这正是你真正关心的图片的分布。让我们来建立一个机器学习系统,它在移动应用图片分布的表现的确很好,当然其缺点就是你的训练集的分布,不同于您的开发和测试集分布,但事实证明这样划分训练/开发/测试集,长期来说性能更好。

4.1 偏差和方差(Bias and Variance with mismatched data distributions)

通过估计学习算法的偏差和方差,能帮你确定下一步工作的优先级。但当你的训练集/开发集/测试集来自不同的分布时,偏差和方差的分析方法也会相应变化。
image.png
这时误差分析要注意,当你从训练集误差转移到开发集误差时,有两件事情变了:

  1. 算法看到的数据只有训练集没有开发集
  2. 开发集和训练集数据分布不同

因为同时存在两个变量,我们很难判断这9%的误差,有多少是因为算法未接触开发集而影响了方差,又有多少是因为开发集的数据分布不同。
所以,为了辨识出这两个影响,我们需要新定义一组数据叫做训练-开发集(training-dev set),这是一个新的数据子集,我们要让它与训练集拥有同样的数据分布,但你不用直接拿它来训练你的网络。
image.png
之前我们已经建立了训练集、开发集和测试集,如图所示。开发集和测试集属于同分布,训练集数据属于不同分布,我们要做的是将训练集随机混淆(shuffle),取出一小块数据作为训练-开发集,如同开发集与测试集分布相同,训练集与训练-开发集也遵循相同分布。
我们可以从中看出,从训练数据到训练-开发数据误差确实上升了很多。训练数据和训练-开发数据的唯一差别在于,神经网络明确地在训练集上训练,但并没有在训练-开发集上直接训练,所以这个例子实际上是高方差(Variance)问题。而右边则为数据不匹配的问题,失配问题(Data mismatch)。
image.png
人类表现和训练误差之间,是可回避偏差(Avoidable Bias);训练误差和训练-开发集误差之间,是方差(Variance)问题有多大;训练-开发集误差和开发及误差之间,是失配问题(Data mismatch);开发集误差和测试集误差之间,是开发集过拟合程度问题(Degree of overfitted to dev set)。这些误差也存在非线性增长的现象,如右边所示,如语音激活后视镜这个例子。
image.png
其中,
①获得这个数据的方法是,邀请一些人为他们的后视镜语音数据贴标签,以衡量人类在这项任务的表现,也许这个数值仍然是6%。
②取一些后视镜语音数据,放入训练集中让神经网络学习,然后测量这个数据子集上的误差,假设也是6%。
那么在这个后视镜语音的任务上,你已经得到了人类水平的性能,也许你在这个数据分布上已经做的很好了,当你继续后续的分析时,并不一定总会得到清晰的前进方向。
具体来说训练与开发集测试集不同分布的数据,可以为训练提供更多的数据,帮助学习算法获得更好的性能。但是除了偏差和方差问题,现在你又有了新的潜在问题:数据失配(Data mismatch)。
解决数据失配问题又那些好方法? 老实说,实际上并没有很好的办法,至少是非常系统的处理数据失配的方法,但是有一些事情可以试试。

4.2 解决数据适配问题

如果发现出现了严重的数据不匹配问题,

  1. 我通常会人工地分析误差,并且试着去理解训练集与开发/测试集之间的差异。为了避免测试集上的过拟合,技术上对误差分析来说,你的关注点应该只是开发集而不是测试集。
  2. 当你研究开发集误差的本质时,或当观察开发集跟训练集相比,存在怎样的差异或者难点时,你所能做的就是想方设法使训练集更为相似,或者也可以收集更多与开发测试集较为相似的数据。比方说,如果你发现车辆的背景噪声是主要的误差来源,你可以模拟出车载噪声数据。

image.png
因此,如果你的目标是使训练集与开发集更加相似,这样有什么解决方法呢? 其中一个方法是你可以通过人工数据合成。
总得来说,如果你认为你遇到了数据不匹配的问题,我推荐你做误差分析,或者观察一下训练集,或者观察一下开发集,以便试图深入了解这两种数据分布的不同所在。你可以设法来获得更多的,看起来更像你的开发集的训练数据。我们所讨论的一种方法是人工数据合成并且人工数据合成的确能起到作用。在语音识别方面,我已经看到人工数据合成,显着提升了已经非常好的语音识别系统的性能,所以这种方法很好。但如果你使用人工数据合成,你必须小心并且记住,你是否可能意外地模拟了所有可能样本的子集中的数据,造成过拟合。
接下来,我想与你分享一些想法,关于如何同时从多种类型的数据中学习。

多项元学习——从多种类型的数据中学习

1. 迁移学习

深度学习中最有力的方法之一,是有时你可以把在一个任务中神经网络 学习到的东西,应用到另一个任务中去。比如,你可以让神经网络学习去识别物体,比如猫,然后用学习到的(一部分)知识,来帮助你更好地识别X射线的结果,这就是所谓的迁移学习。
image.png
训练得出了这样一个神经网络之后,要实现迁移学习,你现在需要把数据集X和Y设定为放射影像。现在的Y是你想要预测的诊断结果,你要做的是初始化最后一层的权值,我们叫这个为WL和PL。然后现在,重新在新的数据集上训练这个神经网络,就是新的放射数据集上。
你有几种方法来重新训练这个放射数据的神经网络。

  1. 如果你只有一个小的放射数据集,你可以只重新训练最后一层的权值,就是WL和PL,同时保留其它所有参数。(或者也可以训练最后一到两层的神经网络)
  2. 如果你有足够的数据,你也可以重新训练神经网络的其余所有层。

要是你对神经网络的所有参数进行重新训练,那么这样训练的初始化阶段,有时候被我们叫做预训练(pre-training。原因是,你在是使用图像识别的数据来预初始化(pre-initialize)或者说预训练神经网络的权重。然后如果你在之后对所有的权重进行更新,那么在放射扫描的数据上的训练有时候被我们叫做微调(fine tuning)。

当神经网络学会了图像识别,意味着它可能学习到了以下信息:关于不同图片的点,线,曲面等等信息在不同图片中看起来是什么样子的。或许关于一个物体对象的很小的细节,都能够帮助你在放射信息诊断的神经网络中,学习得更快一些或者减少学习需要的数据。

image.png
总结一下,什么时候迁移学习是适用的呢?

  1. 如果你尝试从某个任务A中学习到的信息迁移到某个任务B中, 那么当任务A和任务B在有相同的输入时,迁移学习才能适用。在第一个例子中,A和B都以图片作为输入。 在第二个例子中,它们都以语音片段作为输入。
  2. 必须在任务A比任务B有更多的数据时,迁移学习才适用。所有条件都是在想要把任务B做好的前提下,因为在任务B中的数据比在任务A中更加地有价值,通常你需要为任务A准备更多的数据,因为在任务A中的样本比任务B中的样本价值更低。
  3. 最后,迁移学习更加适用的场景是当你认为,任务A中的低层次特征会帮助任务B达成目标。在上面我们提到的例子中,或许图像识别任务教给了神经网络足够的信息,用迁移学习来进行一个放射诊断,或者在语音识别的例子中,教给神经网络如何把语音识别系统迁移到语音唤醒系统中。

迁移学习必须是你尝试把任务B中的任务做好时才会有效,即通常情况下,你要把这个拥有更少数据的任务B做好时。例如图像识别,在这样的任务中,你或许可以获取到百万级的数据,并且从中学习到很多低层次的特征。如此以来你就能够通过迁移学习,来尝试把任务B即放射诊断任务做得很好,尽管你并没有那么足够多的数据。

2. 多任务学习

迁移过程是有先后顺序的,从任务A中学习,然后将其迁移到任务B。在多任务学习中,你(多个任务)一起开始尝试让一个神经网络同时做几件事,然后,每个任务将会帮助完成其他任务。
image.png

  1. 使用Logic回归分类,和softmax回归区别是,不像softmax回归,它将单个标签分配给单个示例。这一个图像可以有多个标签。
  2. 那么你会发现训练一个神经网络做4件事的结果,比训练4个完全独立的神经网络的结果要好。
  3. 到目前为止在算法中,好像每个图像都要标签。其实在多任务学习中,即使一些图像只标记某些对象也能正常工作。

那么什么时候进行多任务学习才有意义?
image.png
它在以下三个条件下适用:

  • 一是你要训练一系列的任务可以共享一些低层次的特征。自动驾驶的例子中,在识别交通灯、汽车和行人时,都有相似的特征,这可以帮你识别停车标志,因为他们都是道路特征。
  • 其次——这不是硬性的规则,所以不总是存在的——但我看到很多成功的多任务学习,他们每个单项任务的数据量非常相似。第二点不是硬性要求,但我更倾向于这样。为了增强多任务学习,如果你集中在任一任务上,其他任务比单一任务合计起来有更多的数据。
  • 多任务学习往往会更有意义,当你训练一个很大的神经网络来使所有任务都有高准确度。如果神经网络不够大。多任务学习与单项训练相比会损害准确率。但如果你训练足够大的神经网络,那多任务学习应该不会或很少影响性能。

请注意一点,实际上迁移学习比多任务学习用得更多,我想这是因为很难找到这么多不同的任务要单独在单个神经网络上训练(计算机视觉的物体检测是一个显著的例外)。所以如果你想解决一个机器学习问题,但你有一个相对较小得数据集,迁移学习可以帮助你。当你有个相关的问题有更大得数据集,你可以用来训练你的神经网络,然后迁移到小数据集的问题上。
多任务学习与迁移学习是你的工具包中的重要工具。最后,我想讨论一下端到端的深度学习。

端到端的深度学习(End-to-end deep learning)

1. 什么是端到端的深度学习

近期,深度学习最令人兴奋的进展之一是端到端深度学习的崛起。那么,什么是“端到端“的深度学习呢?
简单地说,我们有一些数据处理系统或者是由多个阶段组成的学习系统,端到端的深度学习做的,就是它可以捕获所有的阶段。并且,通常可以将其替代为单个神经网络,也就是说运行速度更快。
image.png
以语音识别为例,其目标是接收输入音频片段X,将其转换为该音频剪辑对应的脚本输出Y。传统的语音识别分为多个处理阶段。首先,需要提取音频的一些特征,一些人工设计的音频特征。或许你听说过MFCC这种算法,用于提取一组特定的人工设计的音频特征。提取了低级特征之后,可以应用机器学习算法从音频剪辑中查找音素。

音素是声音的基本单位,比如说,单词"cat"由三个音构成Cu,Ah和Tu,算法会提取出这三个音素,然后把音素串在一起,形成单词。再将这些单词串在一起,构成音频剪辑的脚本。

不同于上述由多个阶段组成的途径(管道),端到端的深度学习可以训练一个庞大的神经网络,只需输入音频片段,然后直接输出脚本。
它在某些情况下,确实淘汰了很多年对于(管道)中间部件的研究。结果表明,端到端深度学习的一个挑战是它需要大量的数据才能取得很好的结果。例如,如果用3000小时的训练数据构建一个语音识别系统,传统的完整管道方法(Pipeline) 能取得很好的结果。只有当你有一个非常大的数据集,比如说10,000小时的数据,也许甚至需要增加到100,000小时的数据时,端到端的方法才突然开始工作得很好。
如果你有中等量的数据,可以采用折衷的方法:输入音频,绕过这些特征,只学习输出神经网络的音素,然后继续其它阶段。因此这是端到端学习的一个步骤,不是彻底的端到端学习。
image.png

2. 什么时候使用端到端的深度学习

让我们先来看一下端到端深度学习的优缺点,这样你可以获得一些准则来判断端到端的方法是否适用于你的系统。
image.png
优点:

  1. 端到端学习真正地让数据发挥主导作用,例如在语音识别系统中的“音素”概念,实际上是人类语言学创造的产物,强迫你的学习算法使用它,不一定是有利的,说不定不加限制的学习效果会更好;
  2. 所需的人类动手设计的组件变的更少了,所以这可以简化你的设计工作流程,意味着你不需要话大量的时间去动手设计特征,手工设计这些中间表示形式。

缺点:

  1. 端到端学习需要大量的数据,所以为了使用机器学习直接得出X到Y的映射,你需要大量的(X, Y)数据;
  2. 它排除了一些具有潜在用途的手工设计组件,所以机器学习研究人员往往会轻视手工设计的组件。但是如果你没有足够的数据,那么你的学习算法就不能够洞悉你数据中的规律,如果你的训练集很小,所以手工设计的组件的确是一条可行之路,去将人工知识融入到算法中。

我认为学习算法有两个主要的知识来源:一个是数据,另一个是你手工设计的东西。
这些东西可以是算法中的组件,或者是特征,或者是其他的东西,所以如果你有很多很多的数据,手工设计就没那么重要了,但是如果你没有那么多的数据,那么有一个精心手工设计的系统实际上可以让人们向算法中注入人类关于这个问题的知识,而且这会是非常有用的。

结论:
要回答你是否应该使用端到端的深度学习,你应该回答一个关键问题,即你是否有足够的数据去学习出具有能够映射X到Y所需复杂度的方程?

在这里插入图片描述

关注我,不迷路
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值