吴恩达第三门-结构化机器学习项目-第一周7-12学习笔记
1.7什么时候该改变开发/测试集和指标?
设置好开发集和评估指标就像是设置好了一个“目标靶子”,整个团队都会以此作为目标进行努力。但如果在项目进行的中途,发现目标定错了,就要及时地改变目标。也就是改变我们所说的开发集、测试集和指标。
加权法
以猫分类器为例,我们先以错误率作为评价两个算法好坏的指标,如下图所示,我们会发现分类器A看起来比B要更好。如果我们将这个分类器用在为用户推荐图片时,虽然A算法的错误率更低,但如果它会推荐出一些色情图片,那用户的体验感就会大大下降。这种情况下,如果B算法推荐的图片中能保证不出现色情图片,那么显然我们会选择错误率稍高一些的分类器B。
在这个例子中,以错误率作为指标去衡量算法的好坏显然是不恰当的。但这个指标是我们之前设定好的,为了选择出更好的分类器,我们这时候就应该去更改我们的选择指标。如果但以最初的错误率无法准确的衡量算法的好坏,我们就可以定义一个新的、全面的错误率:
E
r
r
o
r
=
1
m
d
e
v
∑
i
=
1
m
d
e
v
I
{
y
p
r
e
d
(
i
)
≠
y
(
i
)
}
Error=\frac{1}{m_{dev}}\sum\nolimits_{i=1}^{m_{dev}}I\{y_{pred}^{(i)}\neq y^{(i)}\}
Error=mdev1∑i=1mdevI{ypred(i)̸=y(i)}
在这个式子中,
m
d
e
v
m_{dev}
mdev是开发集的例子数,
y
p
r
e
d
(
i
)
y_{pred}^{(i)}
ypred(i)表示预测值,其值为0或1,
I
I
I表示一个函数,统计出里面这个表达式为真的样本数,这个公式的作用就是统计所有分类错误的样本。但这个公式对所有类型的错误都一视同仁,但有些类型的错误,比如在猫分类器里出现的色情图片,显然是我们希望尽力避免的,这种错误应该被特殊对待。为了解决这个问题,我们更新错误率公式,引入一个权重。新的公式如下:
E
r
r
o
r
=
1
m
d
e
v
∑
i
=
1
m
d
e
v
w
(
i
)
I
{
y
p
r
e
d
(
i
)
≠
y
(
i
)
}
Error=\frac{1}{m_{dev}}\sum\nolimits_{i=1}^{m_{dev}}w^{(i)}I\{y_{pred}^{(i)}\neq y^{(i)}\}
Error=mdev1∑i=1mdevw(i)I{ypred(i)̸=y(i)}
这个权重是认为设定的,对于我们不想看到的错误可以加大该项的权值。比如对于色情图片,如果x^{(i)}是色情图片,我们可以将其对应的
w
(
i
)
w^{(i)}
w(i)设置成100,而其他类型错误对应的权值仍是1.。
评估指标的意义就在于,准确地告诉我们,在已知的若干分类器中哪一个更适合你的应用。如果原本的评估指标无法正确评估算法的好坏,我们就需要花时间定义一个新的评估指标,这种加权法就是一种不错的方法。
确立唯一的评价指标
为了更好地比较不同分类器的好坏,我们应该使用一个唯一的评价指标,在确立这样的一个评价指标后再不断地改善系统在这样一个指标上的表现。
以之前的标靶为例,处理机器学习问题应该分为两步。
第一步是设定目标,定义要瞄准的目标,也就是确立一个可以调节的旋钮。如何设立目标是一个完全独立的问题,把它看成是一个单独的旋钮,可以调试算法表现的旋钮,如何精确瞄准,如何命中目标,定义指标是第一步。
第二步就是根据目标,不断优化对应的成本函数。
J
=
1
m
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
J=\frac{1}{m}\sum\limits_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)})
J=m1i=1∑mL(y^(i),y(i)),如果设置了权重,记得重新归一化,
J
=
1
∑
w
(
i
)
∑
i
=
1
m
w
(
i
)
L
(
y
^
(
i
)
,
y
(
i
)
)
J=\frac{1}{\sum w^{(i)}}\sum\limits_{i=1}^{m}w^{(i)}L(\hat{y}^{(i)},y^{(i)})
J=∑w(i)1i=1∑mw(i)L(y^(i),y(i))。
新的例子
假设我们得到了两个猫分类器A和B,用开发集评估,分别有着3%和5%的错误率。在开发集、测试集上用的是取景好的、高质量的图片,我们认为A分类器更好。但在实际应用中,却发现B分类器的使用效果更好。
这是另一个指标和开发集测试集出问题的例子。问题在于,我们在评估中用的是很漂亮的、高分辨率的开发集和测试集。而用户上传的图片没那么专业,甚至有些模糊。如果我们选择的分类器在指标上表现很好、在开发集上表现很好,但在实际应用中却表现一般,这种情况下我们就需要修改指标或者开发测试集。
总之,如果当前的指标和当前用来评估的数据和真正关心必须做好的事情关系不大,那就应该更改目标或者开发测试集,让它们能更够好地反映算法需要处理好的数据。
吴恩达老师的建议(引用原文)
吴恩达:“所以我的建议是,即使你无法定义出一个很完美的评估指标和开发集,你直接快速设立出来,然后使用它们来驱动你们团队的迭代速度。如果在这之后,你发现选的不好,你有更好的想法,那么完全可以马上改。对于大多数团队,我建议最好不要在没有评估指标和开发集时跑太久,因为那样可能会减慢你的团队迭代和改善算法的速度。”
1.8为什么是人的表现
题目的理解
这章的题目比较令人费解,其实本章的完整标题可以理解为:为什么将机器学习系统和人类的表现比较。主要有两个原因,首先是因为深度学习系统的进步,机器学习算法突然变得更好了。在许多机器学习的应用领域已经开始见到算法已经可以威胁到人类的表现了。其次,事实证明,当你试图让机器做人类能做的事情时,可以精心设计机器学习系统的工作流程,让工作流程效率更高,所以在这些场合,比较人类和机器是很自然的,或者你要让机器模仿人类的行为。
贝叶斯最优错误率
上图中给出了机器学习系统的准确率随时间推移的变化规律。在刚开始研发一个机器学习系统时,系统的准确率还没有达到人类表现水平之前,系统的提升速度是非常快的,但当这个算法表现的比人类更好时,那么其进展和精确度的提升就变得更慢了。也许我们训练出的系统会有超过人类表现水平的一天,但是进展会变得越来越慢。在不断训练的条件下,系统的模型会变得越来越大,数据会越来越多,但是系统的性能始终无法超过某个理论上限,这就是所谓的贝叶斯最优错误率。贝叶斯最优错误率一般认为是理论上可能达到的最优错误率,就是说没有任何办法设计出一个从x到y的函数,让它能够超过一定的准确度。
例如,对于语音识别来说,以音频片段作为x,有些音频十分嘈杂,基本不可能知道说的是什么,所以完美的准确率也有可能不是100%。而对于猫图识别来说,也许有一些图像非常模糊,不管是人类还是机器,都无法判断该图片中是否有猫。所以,完美的准确度也有可能不是100%。
为什么将机器学习系统和人类表现进行比较
机器学习系统在超越人类表现水平之前的进展都很快,而在超越人类表现水平之后的进展就会变慢。因为在人类水平在很多任务中离贝叶斯最优错误率已经不远了,比如对一些自然信息的处理。还因为在系统不如人类表现水平之前有一些工具可以用来提高性能,而超越之后,这些工具的作用将会降低。
对于人类相当擅长的任务,比如:看图识别事物,听写音频,或阅读语言,人类一般很擅长处理这些自然数据。对于这类任务,只要你的机器学习算法的效果比人类差,就可以从让人帮你标记数据,可以让人帮忙或者花钱请人帮你标记例子,从而将更多的数据喂给学习算法。而在超越人类表现水平之后,这种方法就很难再被应用。
1.9可避免偏差
我们希望自己的学习算法在训练集上表现良好,但其实也不希望表现的太好,因为表现的过好将会出现过拟合现象。所以我们应该将算法的效果和人类表现水平进行比较。
以猫分类器为例,如下图所示。人类的错误率为1%,而我们的学习算法在训练集上的错误率为8%,在开发集上的错误率为10%。我们的算法和人类表现有较大的差距,说明算法的你好效果并不好。从减少偏差和方差的工具这个角度看,我们应该把重点放在减少偏差上。
而如果人类的错误率为7.5%,可能图片比较模糊之类的。如下图所示,在这种情况下,我们的算法的错误率和人类表现水平的差距并不算大,可以主要把注意力放在减少方差上。比如可以使用正则化的方法,使开发错误率更接近训练错误率。
在这里我们用人类的错误率代替了贝叶斯错误率。对于计算机视觉任务而言,这种替代十分合理,因为人类非常擅长这类计算机视觉任务,所以人类能做到的水平和贝叶斯错误率相差不远。
我们在这里给出可避免偏差的概念,我们将贝叶斯错误率或者对贝叶斯错误率的估计和训练错误率之间的差值称为可避免偏差。在上图中上下红色方框中数据的差值。之所以叫做可避免偏差,是因为我们希望自己模型的错误率不断接近贝叶斯错误率,而我们又不希望自己模型的错误率低于贝叶斯错误率,因为那样将出现过拟合现象,所以这个差值被称为可避免偏差。
我们应该将可避免偏差与方差进行比较,以确定下一步应该将侧重点放在减小偏差还是减小方差上。
理解人类水平错误率,理解贝叶斯错误率,我们就可以在不同的场景中专注于不同的策略,采用避免偏差策略还是避免方差策略。
1.10理解人的表现
举一个医疗上的例子,我们要通过观察一个医学X光图片,诊断出患者的病变种类。一个普通的、未受过专业训练的人类的错误率可能是3%,一个普通的一生的错误率则是1%,而一个有经验的医生的错误率则达到了0.7%,而一个由有经验医生组成的团队得出的诊断结论的错误率只有0.5%。那么在这种情况下,应该如何界定人类表现水平呢?
人类水平错误率的定义,就是如果你想要替代或估计的贝叶斯错误率。因为一个由有经验医生组成的团队得出的诊断结论的错误率只有0.5%,所以最优贝叶斯错误率会低于0.5%,在这个背景下,我就可以用0.5%估计贝叶斯错误率。所以我将人类水平定义为0.5%,可以使用在上一章中介绍的方法来使用人类水平错误分析偏差和方差。
实际情况中,人类水平错误率的定义可以是不同的,我们也可以使用1%作为人类水平错误率,因为只要你的学习算法超越了一个普通医生的表现,就已经具有了部署的价值。在定义人类水平错误率时,核心就是要弄清楚我们的目标所在,如果想要学习算法的性能超越单个人类,那么就可以使用(b)的定义。但是如果我们的目标是替代贝叶斯错误率,那采用(d)的定义才是最合适的选择。
举一个错误率分析的例子,如上图所示,训练错误率是5%,开发错误率是6%。我们可以将人类表现水平看成0.5%,0.7%,0.1%。而我们将会用人类表现水平替代上一节中的贝叶斯错误率。因为贝叶斯错误率直接影响到了可避免偏差的值,所以人类表现水平的选取也就直接影响到了减小偏差或方差技术的选择。在这个例子中,无论人类表现水平选择多少,算出来的可避免误差都远远大于方差的大小,所以应该主要使用减少偏差的工具,比如构建更大的神经网络。
但如果换一个例子,此时的训练错误率为1%,开发错误率为5%。无论选择哪种作为人类表现水平,最终计算得到的可避免偏差0%,0.3%,0.5%都远远小于方差4%,所以应该主要使用减少方差的工具,比如正则化方法或者选取更大的训练集。
再举第三个例子,如果我们的训练错误率达到了0.7%,开发错误率达到了0.8%。如果用0.7%代替贝叶斯错误率,测得的可避免偏差基本上是0%,那你就可能忽略可避免偏差了,我们应该试试能不能在训练集上做得更好。但如果用0.5%来代替贝叶斯错误率,测量到的可避免偏差是0.2%,这是你测量到的方差问题0.1%的两倍,这表明也许偏差和方差都存在问题。但是,可避免偏差问题更严重。在这个例子中,一旦我们的错误率接近了0.7%,除非非常小心地估计贝叶斯错误率,否则可能无法知道离贝叶斯错误率有多远,只能尽量减少可避免偏差。如果你只知道单个普通医生能达到1%错误率,这可能很难知道是不是应该继续去拟合训练集,这种问题只会出现在你的算法已经做得很好的时候,已经十分接近人类水平时才会出现。
第三个例子很好地说明了为什么当模型的效果接近人类表现水平时很难更进一步,其中一个原因就是很难去判断是该去使用减少方差的工具还是减少偏差的工具。
对人类水平有大概的估计可以让我们做出对贝叶斯错误率的估计,这样我们可以更快地作出决定是应该专注于减少算法的偏差,还是减少算法的方差。这个决策技巧通常很有效,直到系统性能开始超越人类表现水平,这时我们对贝叶斯错误率的估计就不再准确了,但这些技巧还是可以帮人们做出明确的决定。
1.11超过人的表现
我们在上一章中已经讨论过了为什么系统在超过人类表现水平后更近一步会比较困难。即便如此,现在在很多问题上机器学习已经超过了人类。比如网络广告的推送(无语),产品推荐,以及物流预测等方面,甚至还可以用于预测贷款能否被按时归还。
这四个例子都是从结构化数据中学习得来的,可能有个数据库记录用户点击的历史,有一个个人购物历史数据库,或者从A到B需要多长时间的数据库,以前的贷款申请及结果的数据库,这些并不是自然感知问题,这些不是计算机视觉问题,或语音识别,或自然语言处理任务。人类在自然感知任务中往往表现非常好,所以有可能对计算机来说在自然感知任务的表现要超越人类要更难一些。
在上述四个问题中,机器学习团队都可以访问大量数据,它们中最好的系统看到的数据量可能比任何人类能看到的都多,所以这样就相对容易得到超越人类水平的系统。现在计算机可以检索非常大量的数据,也就可以比人类更敏锐地识别出数据中的统计规律。
在深度学习的最新进展中,即使在自然感知任务中,在某些情况下,计算机也已经可以超越人类的水平了。不过现在肯定更加困难,因为人类一般很擅长这种自然感知任务。
所以要达到超越人类的表现往往不容易,但如果有足够多的数据,系统就可能会超越人类的表现水平。已经有很多深度学习系统,在单一监督学习问题上达到了超越了人类的水平。
1.12改善你的模型的表现
如果想要一个监督学习算法达到使用,我们基本上有两件事需要完成。第一件事是要让算法在训练集上有很好的拟合效果,也就是尽可能地减少可避免偏差。第二件事就是要让在训练集上拟合良好的算法在开发集和测试集上也有较好的拟合效果,也就是减少系统的方差。
运用正交化的思想,我们可以将减少系统可避免偏差和减小系统方差的方法看成两个“旋钮”,可以通过训练更大的神经网络或者训练更长的时间来减小偏差,通过正则化方法或者收集更多的训练数据来处理方差问题。
如果想要减少可避免偏差,可以试试这样的策略:比如使用规模更大的模型,这样算法在训练集上的表现会更好,或者训练更久。使用更好的优化算法,比如说加入momentum或者RMSprop,或者使用更好的算法,比如Adam。也可以试试寻找更好的新神经网络架构,或者说更好的超参数。
另外当发现方差是个问题时,可以试试以下方法:收集更多数据,因为收集更多数据去训练可以帮你更好地推广到系统看不到的开发集数据。可以尝试正则化,包括L2正则化,dropout正则化或者数据增强等方法。同时你也可以试用不同的神经网络架构,超参数搜索,找到一个更适合你的问题的神经网络架构。这些会在以后的课程中介绍。