Machine_Learning_Yearning 翻译与理解

注:并没有按原文字面意思翻译,仅仅是看后按自己的理解来记录,建议各位过客看英文原版

在模型准确度不够好时,采用的策略有:

1、更多数据

2、尝试更大的神经网络模型

3、尝试更小的神经网络模型

4、更多的迭代

5、收集更多样化的数据集

6、尝试添加正则化,如L1,L2

7、改变神经网络结构:激活函数,隐藏单元数量

...

但时间有限,面临巨大压力时,如何采用这些策略显得至关重要。很多的机器学习问题如何优化是有线索可循的,这本书的目的就是学习及解读这些线索,提高模型的准确度。


为什么深度学习现在才火:规模驱动机器学习进展

1、使用电子设备的越来越多,带来数据的几何倍数增加

2、计算设备的计算能力增强

3、结合上面两点,即使有海量数据和超强的计算能力,比较老的算法,比如逻辑回归,在性能上提升也是很有限的


而用一个小的神经网络来完成同样的任务,可能会得到较好一点的效果


这里的“小的神经网络”意思是只有少量的隐藏层和参数,如果训练更大的神经网络,可以得到更好的效果


也就是说在计算能力牛,数据多的情况下大的神经网络效果会更优越,如果没啥数据,大家估计就差不多了,搞不好,老的算法还更优。

提高预测效果,还有很多细节也是很重要的,如神经网络的结构,这里面是有很多创新的东西的,但目前一个更稳妥的提高模型性能的方案是去训练更大的网络,获取更多的数

据。


建立开发和测试集合

       猫识别的例子:想做个猫识别器在手机app上使用,从各个网站下载了很多猫和非猫的图片,并且把图片分割成70%的训练集,30%的验证集,使用这些数据,训练了一个猫识别器,会发现在训练集合验证集都work得很好,但当用户使用app来识别他们的图片时,效果却很差。

       这是因为用户使用智能机拍摄的图像可能存在低分辨率,光照不理想,模糊等问题,而构建识别器的数据集是由网络图片构成的,因此,算法并没有生成能够很好刻画我们关心的智能机图像的分布。

       使用随机的70%/30%拆分来形成训练和测试集是机器学习中的一个常见规则,在实际工作中,训练数据分布不同于实际我们关心的数据分布是比较常见的问题,需要有意识避免这样的错误。

       通常定义:

训练集:在上面跑算法的,我理解的这个数据应该是比较大的,用来跑效果较好的或最终模型的

开发集:用来调整参数,特征选择,对学习算法做出其他决定,我理解的这个数据集应该是比较小的,可以快速验证算法性能,调整模型,特征选择等,可以测试很多想法

测试集:用于评估算法的性能

开发集、测试集应该是选择期望在后续模型使用中能高精度识别的样本,这样在测试集ok的识别器在实际中才能表现一致

有了这三个集合,我们就可以得到三个误差值:


其中,人类水平的误差(human level error)是人类自己处理这类问题的误差值;训练集误差(training set error)是指在训练集上跑出来的误差值;开发集误差(devset error)是指用开发集跑出来的误差值。(测试集误差后面会说)

然而我们关注的并不是这个误差值本身,而是它们互相之间的差距。人类误差与训练集误差之间的差距称为「avoidable bias」(可避免的偏差,可简称为偏差)。之所以说「可避免的(avoidable)」,是因为这部分误差可以通过进一步的学习/模型调整优化来避免。而训练集和开发集之间的差距称为「variance(方差)」,它是因为跑了不同的数据而导致的误差率变化(比如跑在见过的数据集上和没见过的数据集上的误差率之差)这两种偏差合在一起,就是机器学习领域著名的 bias-variance trade-off(偏差-方差权衡)。

吴恩达给出的解决配方是:

如果训练误差高(偏差),就使用更大的模型、训练更长的时间、采用新的模型架构如果开发误差高(方差),就使用更多数据、正则化、新的模型架构


    下来问题来了,有时候在系统没投入使用前是拿不到未来做识别的样本的,这就构建不了测试集和开发集了,这种情况只能最大程度去模拟、获取了,在系统投入使用后再更新数据集,实在找不到数据集就只能曲线救国,先使用当前最理想的数据集,例如猫的例子,就只能使用网络图片了,但要注意使用这样的数据集的风险


案例:智能后视镜,如果我们要做个智能后视镜(语音操作的车内智能助手),我们的数据该怎么搞?

    首先,假设我们有 50000 小时的语音资料(随便在哪里下载来的)和 10 小时的车内对着后视镜讲话的语音资料(比如,让客户假装他的后视镜是智能的,然后录下一些语音指令……)。面对这些数据,我们该如何构造我们的训练集?

    有人可能会这样说:50000 小时语料够大,可以分出一些来做开发集(dev set),其他的用来训练。而 10 小时珍贵的车内语音则做成测试集。(其实我就是这么想的!!!)

    错!这是个非常不好的处理方式,因为你的开发集和测试集没能遵从相同的数据分布(distribution)。换句话说,开发集和测试集的内容「根本就不在同一个宇宙」。这样的结果就是,你的数据工程师在开发集上花费了很大的精力之后,结果放到测试集上却发现并没有什么用。

    一个比较靠谱的处理方式应该是:把 10 小时的车内语料分成开发集和测试集。同时,你也可以拿出训练集中的一部分内容作为训练-开发集(train-dev set)。这个数据集能帮助你的算法在训练集上做好优化,再转移到真实场景中。按照这个构架,我们于是可以得到五种不同的误差值:人类误差、训练集误差,训练-开发集误差、开发集误差、测试集误差.其中,人类误差与训练集误差之间的差值还是称为 bias(偏差);训练集误差与训练-开发误差之间的差值称为「训练集的过拟合」(也就是说,它代表了模型单纯在训练集上表现能力);训练-开发误差与开发集误差之间的差值称为「data mismatch」(数据不匹配,就是刚才说的两组数据不在同一个「宇宙」带来的偏差);开发集误差与测试集误差之间的差值称为「开发集过拟合」(同理)。这个时候,拥有的差值就更多了,我们就需要一个新的处理策略:


    用于机器学习的新配方:如果训练误差高(偏置),就使用更大的模型、训练更长时间、使用新的模型架构;如果训练-开发误差高(方差),就使用更多数据、正则化、新的模型架构;如果开发误差高(训练-测试数据不匹配),就使训练数据更近似于测试数据、进行数据合成(域适应)、使用新的模型架构。


开发集合测试集应该来自同样的分布

     当模型在开发集工作得很好,在测试集却表现很差时,要考虑是不是开发集合测试集的分布不一样。如果是一样的,估计就是开发集训练的模型过拟合了,显而易见的方法

就是增加开发集的数据量,但如果是开发集和测试集不一样,要定位到具体问题所在就不是那么清晰明了了,有几个方面会造成这样的结果:

1、开发集训练过拟合

2、测试集比开发集要复杂,因此,你的算法可能做得和预期的一样好,但对于测试集可能没有进一步的改进

3、测试集可能没开发集复杂,但模型在开发集上表现很好,在测试集上不行,提升开发集上的模型的性能都是徒劳的

     总之,最好是开发集和测试集来自相同的分布。研究迁移学习的除外。


开发集和测试集应该多大合适

     开发集应该足够用于检测不同算法之间的差异。例如分类器A准确率是90.0%,分类器B准确率是90.1%,一个仅包含100个样本的开发集是不足以检测这0.1%的差异的,这种情况推荐1000-10000个样本的开发集,使用10000的开发集就很可能发现这0.1%的差异了。

     对于一些成熟或重要的应用,例如广告、搜索引擎、产品推荐等,0.01%的提升也是很重要的,因为这直接影响到公司的收益,这种情况,为了检测出模型间更小的差异,开发集会比10000多得多

     测试集应该多大呢?测试集应该要足够用于高可信度的评估系统的性能,一个流行的配置的用30%的数据作为测试集,这在数据适中的情况下工作得很好,即100-10000个样

本时。但在大数据时代,常常面临多达上亿数据的机器学习问题,30%的比率其实是往下调的,但样本量是增加的。


为团队建立单一的优化指标

      在实际建模过程中算法性能的评估指标有多种,如准确率、召回率、F1score等,如果我们建立一个单一的指标就会方便判断模型的好坏,如用准确率做为指标,A分类器的准确度是97%,B分类器的是95%,可以判断A优于B,但如果我们使用多指标,我们就没法立即判断哪个模型更好,如:

在开发过程中团队会尝试关于模型结构,模型参数,特征选择等的一些想法,建立单一优化指标有助于快速判断

有时我们可能会即关于准确率又关注召回率,这时我们可以用他们的平均值或者平均值的替代品F1score

有时可能也关注执行效率


如果像Accuracy - 0.5*RunningTime 这样整合成单一指标,貌似很不自然,这时除了单一指标,还需建立满意指标,就拿执行效率来说,只要在100ms内就能接受,那我们就建立个执行时间小于100ms的满意指标,在满足满意指标的前提下去优化准确度


有开发集和度量加速迭代

   对于一个没有研究过的问题,一开始就知道什么方法有效是很困难的,即使经验丰富的机器学习研究者在没有发现有效方法前都需要去尝试很多的想法,在建立机器学习系统的时候,吴恩达通常是这样做的:

1、首先就如何构建系统提出一些想法

2、将这些想法编码

3、进行试验看看这些想法效果怎么样,然后回到第一点又有一些新的想法,这样一直迭代直达满意为止。


从中我们就可以看出为什么需要开发集,测试集以及一个评估指标的重要性:每次尝试一个想法,在开发集和测试集上测试这个想法的性能,而单一指标能快速判断这个想法的效果,如果没有设计好上诉的开发集,测试集,单一评估指标,时间上就会慢得多,而且像模型0.1%的提升可能会被忽略掉。


什么时候应该更改开发集和测试集

    开发集、测试集以及单一评估指标、满意指标最好在一周内创建,这样可以使团队的目标明确。如果在之后发现开发集、测试集以及单一评估指标不再能正确指导建立正确更好的模型时,就需要立即修正了,例如分类器A的评估分高于B的,但发现实际使用时B的效果比A的好,这就是需要改变开发集、测试集或评估指标的信号。

可能有以下几种可能导致这样的问题:

1、需要识别的实际的分布不同于开发测试集的分布

   比如猫的识别,开发测试集是成年猫,而实际使用是年幼猫,这时需要更新开发/测试集,使其更具代表性

2、在开发集上过拟合,如果开发集上的表现比测试集上好很多,这就是过拟合的信号,如果需要跟踪团队的进展,可以有规律的使用测试集评估系统,但不要使用测试集对算

法做出任何决定,包括是否回滚到前一周的系统。如果这样做了,在测试集上也开始过拟合了,并且再也不能指望它对系统的性能给予完全无偏见的估计

3、制定的单一指标与实际的项目优化的方向不一致,例如项目要求召回率,但指标是准确率。


基本误差分析



数据合成

    什么是数据合成?举个例子,在语音识别领域,用清晰的声音记录来做训练集是不给力的。因为在应用场景中,不会有那么安静的背景环境。所以需要人为添加一些噪音。这些噪音在人类的眼里没什么大问题,但是对机器学习算法来说,却是个大大的考验。

    自动数据合成的例子。 OCR :将文本插入随机背景中 ;语 音识别:将清晰的音频混入不同的背景噪声中 NLP :语法纠错:合成随机的语法错误。有时候,一些在人眼看来很好的合成数据实际上对机器学习算法来说是信息不足的,而且只涵盖了实际数据分布的一小部分。比如说,从视频游戏中提取出来的汽车图像。


贝叶斯最优误差

对于人类误差和机器学习误差,你会发现一个规律:


当机器学习比人类水平低时,它的准确率的提升是很快的。但是当它超越人类以后,往往准确率提升效率就逐步降低了。并且,在人类水平线的上方,有一个叫 Bayes Optimal Error(贝叶斯最优误差)的线,这是我们人和机器学习都永远无法逾越的。

这一切的原因有二:

   1. 机器学习超越人类以后,很快就会靠近贝叶斯最优误差线,这是一条理论上无法逾越的线。

   2. 数据带有人类自己做的标签(label),所以本身就含有人类自己的见解(insight)

   那如果确定人类误差,下面有个例子:在医学领域,如果我们想用深度学习来观察医学图像并作出判断,那么,以下哪一种应该被我们选作人类的误差值(human-level error)?

1. 一个普通人 3%

2. 一个普通医生 1%

3. 一个专家医生 0.7%

4. 一个医生专家组 0.5%

答案:选 4.

    因为 4 是人类能达到的最大限度,也是最靠近 Bayes Error 线的地方。我们做机器学习的目的就是要让我们的误差率无限接近于Bayes Error 线。


未来的趋势

      真正的人工智能未来还是会落在 unsupervised learning(无监督学习)和 reinforcement learning(强化学习)上,其中强化学习飞得慢点,因为目前大多数强化学习都还仅仅被运用在电子游戏模拟上,而无监督学习似乎是起点高一点,因为我们熟知的很多算法就已经是无监督学习了(比如:word2vec),然而,在这一切还没有成熟之前,他认为还有一个折中的处理方法:迁移学习(transfer learning)。简单来说,就是把有标签或者数据量大的集合用于预训练(pre-train),然后在此基础上对真正的目标数据集进行无监督优化。相比于完全的无监督,这条路似乎更有希望.

猜你喜欢

转载自blog.csdn.net/wuxianfeng1987/article/details/77711756