一、当实际任务数据与其他数据分布不同时的数据集划分
以猫咪分类来举例,左边是从网络爬取的猫猫数据及图像,一般为专业人员拍摄,因此较为清晰,且背景不杂乱;而我们在部署工程时,比如设计一个猫猫识别软件,由用户拍摄,为右边的那样,很多模糊和背景杂乱。对于一个任务,需要根据其目的来构建val、test集,并且要保证val、test集的数据来自同一分布,因为test集是用来:比如我有好几个模型可以选择,但是最后我会根据哪个模型再test集上表现最好,来选择哪个模型,因为test集是更符合实际任务的的数据集,而val数据集用来评测模型的优劣,要尽可能保证模型在val上具有好的特性,同时在test也要好,因此val和test数据分布必须保持一致。
当我们实际任务的数据很少,而其他数据分布的数据很多时,应该怎么划分哪,图中有两种option,第一种是将来自网络和手机拍摄的图像合在一起,然后random.shuffle打乱按照一定比例分到train、val、test,但是这种方法显然是不合理的,因为我们实际任务分布为由手机拍摄的图片,而如果混合打乱,在val、test种就大部分为从网络爬取的高清数据,这样的评价是错误的。因此第二种诞生,即val、test用全部是用从手机拍摄的猫咪图像,而分一部分从手机拍摄的猫咪图像去train集进行训练(例如总共有10000张手机拍摄的低分辨率图像,分5000给train,剩下的5000给test和val)。
还有一个知识是,原来机器学习阶段,常常把train、val、test分为6:2:2,或者不要test,将train、val分为7:3。但是随着深度学习发展,以及数据集的丰富,其实比例不用7:3,只需要保证val、test的数量能够满足测试的需求,能够通过这些数据集得到的指标反应真实情况即可,例如有100万的数据,我可以分给train集98万,因为网络是很吃数据的,而用预测或选择不同的模型val、test集各1w就已经足够了。
二、当val与train数据分布不同时的偏差、方差等分析
还是以猫咪分类为例,我们假设人对猫咪的识别错误率为0%,并将其约等于贝叶斯最优错误,那么一切的系统都只能逼近这个错误率,而不能比他更小。我们知道,val和train的数据分布不同时,如果Dev error和train error差距很大,可能有两个原因,一个是模型方差大,也即泛化性差;第二个原因可能是由于数据分布不同导致的,可能模型泛化性并不差,只是缺少val(dev)集的数据,所有没有达到很好效果,因此我们需要确定是哪个问题。
为了解决以上问题,我们将train分为两部分,一部分用于训练、一部分用于评测(图中的train_dev),此时我们可以得到三种错误率,
1、Train Error 2、 Train_Dev Error 3、Dev Error
(1)其中train和train_dev具有相同的数据分布,因此可以通过两者error差距来看待方差,如果两者差距很小,证明方差小,则证明val错误率高的原因是由于数据分布不同导致的,这时我们就应该收集更多的实际任务的数据进行训练
(2)如果 Train_Dev Error和Train Error 差距较大,证明是方差较大,而如果同时,Train_Dev Error与Dev Error差距很小,则证明Dev Error大是由于方差大导致,我们应该加入正则化或引入更多的训练数据或者采用其他网络等等
(3)如果Train Error与人类的Error差距很大,则证明模型拟合不够好,可避免偏差较大,可以采用更复杂的网络或者采用更好的优化器等等
(4)当然,我们也可以看一下Test Error并与Dev Error对比,如果差距很大,证明在Dev集上过拟合了,需要扩充Dev集
以上的表述均是遵循了正交化的思想,单独的分析每个问题,而不会对其他产生影响,更容易确定修改的方向
三、如何解决训练集、测试集数据分布不同
对于此问题,没有系统的解决办法,这里只是提供思路,具体需要实践,但不一定有效。我们可以人工看一下预测错误的那些输入都有什么特性,并进行人工的分类,去区分train、val之间的差距,以此找到修改方向。其次,可以采用人工合成的数据(符合实际任务的数据)来扩充训练集,但是要注意一个问题,看下图:
右边两个是人工合成的数据,我们人眼似乎看不出他与真实的区别,但是网络不同。比如人工合成的车可能局限在了20个类别,但是实际世界中的车有上万种,尽管我们人类无法分别,但是网络对于加入的人工合成的车就会过拟合那20个类别,这时效果会变得糟糕。