深度学习实战
上QQ阅读APP看书,第一时间看更新

2.5 超参数与验证集

我们已经学习了不少机器学习的概念,同时我们也引入了不少符号及专业术语。不知你是否已经被这些概念弄糊涂了,现在我们就对这些内容进行梳理。我们可以很粗浅地认为,机器学习其实就是通过一些优化手段去调整数据权重w(参数)。我们也了解到了梯度下降中的学习率α(步长)和正则化中权重衰减的惩罚因子λ都对机器学习算法的最终性能产生着巨大的影响,在学习过程中我们需要不停地调整学习率与惩罚因子,那么如何去区分这些不同的符号呢?

我们目前说到的学习,通俗点也可以说是去寻找最佳的权重w,而学习率与惩罚因子这些设置,其实就是帮助我们去寻找最佳的权重,这些设置控制着机器学习算法的行为,我们就将其统称为超参数(Hyperparameters)。

虽然超参数与参数我们都需要去调整,但通常针对参数的调整叫作学习,而对超参数的调整叫作选择。其原因在于,我们通常在训练数据集中是不去修改超参数的。接下来引入一个例子帮助你理解参数和超参数,“杨老师想在班上选择一个‘爬树小冠军’,但大家都不会爬树,不过小灿、小嫣和小姣同学热情都很高涨。那杨老师就指着一棵树说,你们先学会儿爬树吧,然后再选出最厉害的那个。于是小嫣同学就去学了半小时的爬树技能,结果摔得鼻青脸肿,不过至少还是学会了爬树;小姣同学就比较灵敏学得快,爬得也快;小灿同学就不得了,经过半小时的学习就和小猴子一样厉害了。老师最后就让他们去爬另外一棵树,最终,小灿获得了‘猴王’称号。”

以上例子中的同学各自学习爬树的过程就相当于机器学习中的学习过程,需要注意的是,她们都是学习爬同一棵树,也就是都是在训练数据集中学习。而老师选择哪一个厉害,就相当于超参数选择,选择是在一棵新树上进行测试的。这里需要注意的一个小知识点是,超参数选择的是同一算法的不同性能,或者是对同一算法族的选择。就好像小灿、小嫣和小姣都是人,而且还都是女生。如果是对小猴、小猫和小狗的选择,那就不算是超参数选择了,那是不同算法的比较了。

以上例子中还有一个重点在于老师是让她们在一棵“新树”进行比赛的,需要特别注意的是这里的“新树”不是测试数据。刚开始进入机器学习的“青椒”们常见的误区就在于此,我们这里所说的“新树”,称之为验证数据集(validation set)。

简单来说,我们将已知数据分成两大部分,一部分用于训练,一部分用于测试。而在训练数据集中我们又可分为两部分,一部分用于学习参数,我们称为训练数据集;一部分用于选择超参数,我们称之为验证数据集。而最终性能测试的数据,我们称为测试数据集

那我们为什么要这样划分呢?

我们先来玩一个简单的摇骰子游戏,有三个骰子,每个骰子有6个面,如果能同时摇出三个6,那就可以得到一颗棒棒糖,奖励给我们的“天选之子”。

正常情况下,摇出三个6的概率可看做独立重复事件,其概率为:

我们能摇出“豹子”的概率只有0.46%,就连百分之一都没有,假设我们班共有100个同学玩这个游戏,那么至少有一人获得棒棒糖的概率又为多少呢?

我们班里至少一个同学摇出“豹子”的概率为0.371,看来棒棒糖送出去的概率还是比较小的。可是当我们这个游戏被升级为“年级摇骰王选拔赛”时,我们共有7个班,每个班都可以参与进来。假设每个班人数相同,那整个年级至少一人摇出豹子的概率又为多少呢?

我们整个年级能摇出“豹子”的概率就高达0.961了,这几乎可以断定,一定会出现这么一个“天选之人”了。

介绍完了以上的小游戏,不知你会不会有点失落。机器学习算法可以想象成在空间中找“分割面”,机器学习算法能力的大小也可以说成是可选分割面数量的多少。机器学习从某种程度上而言不就是去寻找我们游戏中的“豹子”吗?一个人要摇出“豹子”的概率是很低的,但让7个班、每班100个人去摇骰子,出现“豹子”的概率就非常大了。我们天真地以为这个“天选之人”就是赌神,但其实他和我们一样普通。

一个班级就相当于一套超参数配置下的学习算法,配置数量越多,就相当于参加比赛的班级越多。我们在所有超参数配置中找一个最佳性能参数,不就是相当于在所有班级中找一个“摇骰王”吗?

我们的模型能力越大,那最终在训练数据集中的表现也就会越好,但这个“好”是乱猜还是学习,就需要在新的数据上测试一番,但我们并没有真正的新数据,我们只能划分一部分训练数据去充当“新数据”。初学者可能会把测试数据当成验证数据来用,但要记住,验证数据是帮你去选择超参数的,虽然验证数据不直接参与训练过程,但进行超参数选择的时候,其实也间接地包含在整个学习过程中

那怎样去划分训练数据与验证数据呢?

通常使用80%的训练数据作为训练,20%的数据用于验证。由于验证数据也用于“训练”,因此验证集的错误率是要低于真实的泛化错误率的。当配置出了最佳的超参数时,再用测试数据集去测试学习器的泛化性能。

通常将数据集分成固定的训练集与固定的验证集,使用训练数据集去学习,使用验证数据集去验证训练的结果。但测试是存在偶然性的,也许划分出来的训练数据与验证数据差别很大,可能我们的机器学习算法性能也挺不错的,但由于验证数据的问题,而变成了“窦娥冤”;也许我们的算法其实一般,但恰恰就很幸运地在验证数据集上表现优异。为了减少这种偶然性,使用平均验证错误是一个比较好的方式,而K折交叉验证(K-fold Cross-Validation)[15]就是其最常用的一个方法。

K折交叉验证先将数据集分割成大小相同的K组数据集,我们先使用2~K组数据集作为训练数据集进行训练,而后用第一组数据集进行验证;接下来使用第二组数据集作为验证数据,而剩余的作为训练数据,直至遍历完所有数据集,将K组验证错误率取平均值,而平均验证错误率就当作泛化错误率。

K最常用的取值为10,称为10折交叉验证。K的取值越大,划分的数据集越多,那最终的泛化错误率的可靠性就越高,但相应的时间花费就越大。因此K的取值需要在实际应用中,在训练时间与可靠性中做一个取舍,其也是一对鱼和熊掌。