目录
1)Carrying out error analysis
2)Cleaning up Incorrectly labeled data
3)Build your first system quickly then iterate
4)Training and testing on different distributios
5)Bias and Variance with mismatched data distributions
6)Addressing data mismatch
7)Transfer learning
8)Multi-task learning
9)What is end-to-end deep learning
10)Whether to use end-to-end deep learning
以下笔记是吴恩达老师深度学习课程第三门课第二周的的学习笔记:ML Strategy。笔记参考了黄海广博士的内容,在此表示感谢。
通过人工检查机器学习模型得出的结果中出现的一些错误,有助于深入了解下一步要进行的工作。这个过程被称作错误分析(Error Analysis)。
例如,你可能会发现一个猫图片识别器错误地将一些看上去像猫的狗误识别为猫。这时,立即盲目地去研究一个能够精确识别出狗的算法不一定是最好的选择,因为我们不知道这样做会对提高分类器的准确率有多大的帮助。
这时,我们可以从分类错误的样本中统计出狗的样本数量。根据狗样本所占的比重来判断这一问题的重要性。假如狗类样本所占比重仅为 5%,那么即使花费几个月的时间来提升模型对狗的识别率,改进后的模型错误率并没有显著改善;而如果错误样本中狗类所占比重为 50%,那么改进后的模型性能会有较大的提升。因此,花费更多的时间去研究能够精确识别出狗的算法是值得的。
这种人工检查看似简单而愚笨,但却是十分必要的,因为这项工作能够有效避免花费大量的时间与精力去做一些对提高模型性能收效甚微的工作,让我们专注于解决影响模型准确率的主要问题。
在对输出结果中分类错误的样本进行人工分析时,可以建立一个表格来记录每一个分类错误的具体信息,例如某些图像是模糊的,或者是把狗识别成了猫等,并统计属于不同错误类型的错误数量。这样,分类结果会更加清晰。
总结一下,进行错误分析时,你应该观察错误标记的例子,看看假阳性和假阴性,统计属于不同错误类型的错误数量。在这个过程中,你可能会得到启发,归纳出新的错误类型。总之,通过统计不同错误标记类型占总数的百分比,有助于发现哪些问题亟待解决,或者提供构思新优化方向的灵感。
在监督式学习中,训练样本有时候会出现输出Y标注错误的情况,即incorrectly labeled examples。如果这些label标错的情况是随机性的,DL算法对其包容性是比较强的,即健壮性好,一般可以直接忽略,无需修复。然而,如果是系统错误(systematic errors),这将对DL算法造成影响,降低模型性能。
刚才说的是训练样本中出现incorrectly labeled data,如果是dev/test sets中出现incorrectly labeled data,该怎么办呢?
方法很简单,利用上节内容介绍的error analysis,统计dev sets中所有分类错误的样本中incorrectly labeled data所占的比例。根据该比例的大小,决定是否需要修正所有incorrectly labeled data,还是可以忽略。举例说明,若:
- Overall dev set error: 10%
- Errors due incorrect labels: 0.6%
- Errors due to other causes: 9.4%
上面数据表明Errors due incorrect labels所占的比例仅为0.6%,占dev set error的6%,而其它类型错误占dev set error的94%,即错误标标注标签所占比例较低,这种情况下,可以忽略incorrectly labeled data。
如果优化DL算法后,出现下面这种情况:
- Overall dev set error: 2%
- Errors due incorrect labels: 0.6%
- Errors due to other causes: 1.4%
上面数据表明Errors due incorrect labels所占的比例依然为0.6%,但是却占dev set error的30%,而其它类型错误占dev set error的70%。因此,这种情况下,incorrectly labeled data不可忽略,需要手动修正。
我们知道,dev set的主要作用是在不同算法之间进行比较,选择错误率最小的算法模型。但是,如果有incorrectly labeled data的存在,当不同算法错误率比较接近的时候,我们无法仅仅根据Overall dev set error准确指出哪个算法模型更好,必须修正incorrectly labeled data。
关于修正incorrect dev/test set data,有几条建议:
- Apply same process to your dev and test sets to make sure they continue to come from the same distribution
- Consider examining examples your algorithm got right as well as ones it got wrong
- Train and dev/test data may now come from slightly different distributions
对于每个可以改善模型的合理方向,如何选择一个方向集中精力处理成了问题。如果想搭建一个全新的机器学习系统,建议根据以下步骤快速搭建好第一个系统,然后开始迭代:
设置好训练、验证、测试集及衡量指标,确定目标;
快速训练出一个初步的系统,用训练集来拟合参数,用验证集调参,用测试集评估;
通过偏差/方差分析以及错误分析等方法,决定下一步优先处理的方向。
有时,我们很难得到来自同一个分布的训练集和验证/测试集。还是以猫识别作为例子,我们的训练集可能由网络爬虫得到,图片比较清晰,而且规模较大(例如 20 万);而验证/测试集可能来自用户手机拍摄,图片比较模糊,且数量较少(例如 1 万),难以满足作为训练集时的规模需要。
虽然验证/测试集的质量不高,但是机器学习模型最终主要应用于识别这些用户上传的模糊图片。考虑到这一点,在划分数据集时,可以将 20 万张网络爬取的图片和 5000 张用户上传的图片作为训练集,而将剩下的 5000 张图片一半作验证集,一半作测试集。比起混合数据集所有样本再随机划分,这种分配方法虽然使训练集分布和验证/测试集的分布并不一样,但是能保证验证/测试集更接近实际应用场景,在长期能带来更好的系统性能。
之前的学习中,我们通过比较人类水平误差、训练集错误率、验证集错误率的相对差值来判断进行偏差/方差分析。但在训练集和验证/测试集分布不一致的情况下,无法根据相对差值来进行偏差/方差分析。这是因为训练集错误率和验证集错误率的差值可能来自于算法本身(归为方差),也可能来自于样本分布不同,和模型关系不大。
在可能存在训练集和验证/测试集分布不一致的情况下,为了解决这个问题,我们可以再定义一个训练-验证集(Training-dev Set)。训练-验证集和训练集的分布相同(或者是训练集分割出的子集),但是不参与训练过程。
现在,我们有了训练集错误率、训练-验证集错误率,以及验证集错误率。其中,训练集错误率和训练-验证集错误率的差值反映了方差;而训练-验证集错误率和验证集错误率的差值反映了样本分布不一致的问题,从而说明模型擅长处理的数据和我们关心的数据来自不同的分布,我们称之为数据不匹配(Data Mismatch)问题。
人类水平误差、训练集错误率、训练-验证集错误率、验证集错误率、测试集错误率之间的差值所反映的问题如下图所示:
一般情况下,human-level error、training error、training-dev error、dev error以及test error的数值是递增的,但是也会出现dev error和test error下降的情况。这主要可能是因为训练样本比验证/测试样本更加复杂,难以训练。
这里有两条关于如何解决数据不匹配问题的建议:
- 做误差分析,尝试了解训练集和验证/测试集的具体差异(主要是人工查看训练集和验证集的样本);
- 尝试将训练数据调整得更像验证集,或者收集更多类似于验证/测试集的数据。
如果你打算将训练数据调整得更像验证集,可以使用的一种技术是人工合成数据。我们以语音识别问题为例,实际应用场合(验证/测试集)是包含背景噪声的,而作为训练样本的音频很可能是清晰而没有背景噪声的。为了让训练集与验证/测试集分布一致,我们可以给训练集人工添加背景噪声,合成类似实际场景的声音。
人工合成数据能够使数据集匹配,从而提升模型的效果。但需要注意的是,不能给每段语音都增加同一段背景噪声,因为这样模型会对这段背景噪音出现过拟合现象,使得效果不佳。
迁移学习(Tranfer Learning)是通过将已训练好的神经网络模型的一部分网络结构应用到另一模型,将一个神经网络从某个任务中学到的知识和经验运用到另一个任务中,以显著提高学习任务的性能。
例如,我们将为猫识别器构建的神经网络迁移应用到放射科诊断中。因为猫识别器的神经网络已经学习到了有关图像的结构和性质等方面的知识,所以只要先删除神经网络中原有的输出层,加入新的输出层并随机初始化权重系数(,),随后用新的训练集进行训练,就完成了以上的迁移学习。
如果新的数据集很小,可能只需要重新训练输出层前的最后一层的权重,并保持其他参数不变;而如果有足够多的数据,可以只保留网络结构,重新训练神经网络中所有层的系数。这时初始权重由之前的模型训练得到,这个过程称为预训练(Pre-Training),之后的权重更新过程称为微调(Fine-Tuning)。
你也可以不止加入一个新的输出层,而是多向神经网络加几个新层。
在下述场合进行迁移学习是有意义的:
两个任务有同样的输入(比如都是图像或者都是音频);
拥有更多数据的任务迁移到数据较少的任务;
某一任务的低层次特征(底层神经网络的某些功能)对另一个任务的学习有帮助。
迁移学习中的步骤是串行的;而多任务学习(Multi-Task Learning)使用单个神经网络模型,利用共享表示采用并行训练同时学习多个任务。多任务学习的基本假设是多个任务之间具有相关性,并且任务之间可以利用相关性相互促进。例如,属性分类中,抹口红和戴耳环有一定的相关性,单独训练的时候是无法利用这些信息,多任务学习则可以利用任务相关性联合提高多个属性分类的精度。
以汽车自动驾驶为例,需要实现的多任务是识别行人、车辆、交通标志和信号灯。如果在输入的图像中检测出车辆和交通标志,则输出的 y 为:
多任务学习模型的成本函数为:
其中,j 代表任务下标,有 c 个任务。对应的损失函数为:
多任务学习是使用单个神经网络模型来实现多个任务。实际上,也可以分别构建多个神经网络来实现。多任务学习中可能存在训练样本 Y 某些标签空白的情况,这不会影响多任务学习模型的训练。
多任务学习和 Softmax 回归看上去有些类似,容易混淆。它们的区别是,Softmax 回归的输出向量 y 中只有一个元素为 1;而多任务学习的输出向量 y 中可以有多个元素为 1。
在下述场合进行多任务学习是有意义的:
训练的一组任务可以共用低层次特征;
通常,每个任务的数据量接近;
能够训练一个足够大的神经网络,以同时做好所有的工作。多任务学习会降低性能的唯一情况(即和为每个任务训练单个神经网络相比性能更低的情况)是神经网络还不够大。
在多任务深度网络中,低层次信息的共享有助于减少计算量,同时共享表示层可以使得几个有共性的任务更好的结合相关性信息,任务特定层则可以单独建模任务特定的信息,实现共享信息和任务特定信息的统一。
在实践中,多任务学习的使用频率要远低于迁移学习。计算机视觉领域中的物体识别是一个多任务学习的例子。
在传统的机器学习分块模型中,每一个模块处理一种输入,然后其输出作为下一个模块的输入,构成一条流水线。而端到端深度学习(End-to-end Deep Learning)只用一个单一的神经网络模型来实现所有的功能。它将所有模块混合在一起,只关心输入和输出。
如果数据量较少,传统机器学习分块模型所构成的流水线效果会很不错。但如果训练样本足够大,并且训练出的神经网络模型足够复杂,那么端到端深度学习模型的性能会比传统机器学习分块模型更好。
而如果数据集规模适中,还是可以使用流水线方法,但是可以混合端到端深度学习,通过神经网络绕过某些模块,直接输出某些特征。
应用端到端学习的优点:
只要有足够多的数据,剩下的全部交给一个足够大的神经网络。比起传统的机器学习分块模型,可能更能捕获数据中的任何统计信息,而不需要用人类固有的认知(或者说,成见)来进行分析;
所需手工设计的组件更少,简化设计工作流程;
缺点:
需要大量的数据;
排除了可能有用的人工设计组件;
根据以上分析,决定一个问题是否应用端到端学习的关键点是:是否有足够的数据,支持能够直接学习从 x 映射到 y 并且足够复杂的函数?