在不同的划分上进行训练和测试
深度学习算法对训练数据的胃口很大,当你收集到足够多的带标签数据构成训练集时,算法效果最好。
这导致很多团队用尽一切方法收集数据,然后把它们堆到训练集里,让训练的数据量更大。但是有些数据,甚至是大部分数据,都来自和开发集和测试集不同的分布。
所以深度学习时代,越来越多的团队都用和dev set、test set分布不同的数据来训练。
这里有一些微妙的地方,一些最佳做法来处理训练集training set和测试集test set存在差异的情况。
option1(不推荐):
面对不同分布的图片,一个做法是把他们放到一起打乱,然后随机分配的训练集、开发集和测试集。
这样做的优点是:这样三者就来自同一分布,这样更好管理。
这样做的缺点是(缺点还不小):如果你观察开发集,看这2500个样本,它们其中很多图片都来自网页下载,而不是我们真正关心的数据分布。要记住:设立开发集的目的你告诉你的团队where to aim the target. 而你瞄准目标的方式,你的大部分精力都在优化网页下载的图片,而这并不是我们想要的。
option2(推荐):
在这里,我们将200000张网页下载的图片和5000张来自应用的图片组成训练集,然后各用2500张来自应用的图片组成开发集、测试集。
这样划分训练集、开发集和测试集的好处在于:现在你瞄准的目标就是你想要处理的目标。你告诉你的团队,我的开发集包含的数据全部来自手机上传,而这是我真正关心的图片分布。
这样划分训练集、开发集和测试集的坏处在于:现在你的训练集分布,和开发集和测试集的分布并不一样。
但事实证明,这样把数据分成训练集、开发集和测试集,在长期能给你带来更好的系统性能。
再看另一个例子:
划分数据的方式还是和上面的option2一样。
在开发集和测试集中数据全部来自我们想要优化的目标数据,在训练集中数据选用其他(大量)数据和目标数据的组合。
不匹配数据划分的偏差和方差
存在的问题
估算学习算法的偏差和方差,真的可以帮你确定接下来应该优先做的方向。
但是当你的训练集来自和开发/测试集不同分布的时候,分析偏差和方差的方式可能不一样。
如果开发集和训练集同分布,你可能会说,这里存在很大的方差问题。你的算法不能从训练集很好地泛化,它处理训练集很好,但处理开发集就突然间效果很差了。
但如果你的训练数据和开发数据来自不同的分布,那么我们就不能简单地下这个结论。特别是,也许算法在开发集上做的不错,可能因为训练集都是高分辨率图片,很容易识别,但开发集要难以识别得多。
所以也许软件没有方差问题,这只不过反应了开发集包含更难准确分类的问题。
所以这个分析的问题在于,当你看训练误差,再看开发误差,有两个事情改变了:
- 算法只见过训练集数据,没见过开发集数据。
- 开发集数据来自不同的分布。
因为我们同时改变了两件事,所以很难确认这增加的9%的误差,有多少是因为算法没看到开发集中的数据导致的(问题的方差部分),有多少是因为开发集的数据就是不一样。
训练-开发集的引入
为了分辨这两个因素的影响,定义一组新的数据是有意义的,我们称之为训练-开发集(training-dev set)
得到训练-开发集的方法为:随机打散训练集(randomly shuffle the training set),然后分出一部分作为训练-开发集。
这样,我们有了训练集、和训练集不同分布的开发集和测试集(但二者同分布)、和训练集同分布的训练-开发集。
神经网络的训练方式+区分方差偏差和数据不匹配
我们只在训练集来训练神经网络(不让神经网络在训练-开发集上跑后向传播),之后我们看神经网络在训练集、训练-开发集、开发集上的误差。
在上方左边例子中,我们可以得出模型方差过大的问题(high variance),即神经网络在训练集表现良好,但无法泛化到同分布的训练-开发集上(也就是同分布但没见过的数据)。
在上方右边的例子中,我们可以看到模型的方差的问题已经很小了,现在的问题是数据不匹配(data mismatch)的问题(很好理解)。
对于下方左边的例子,训练集的误差就很大,说明模型存在偏差过大的问题(high bias),或者叫可避免偏差问题。
当然,以上三个问题也可能同时存在多个。比如下方右边的例子,同时存在高偏差和数据不匹配的问题。
判断问题所在的几个重要参数
左边从上到下依次为:
- human level
- training set error(可避免误差)
- training-dev set error(方差,对训练集过拟合)
- dev error(数据不匹配)
- test error(方差,对开发集过拟合)
对上面的图标改一下表现形式:
一般来说,看红圈中的数,就可以明晰问题所在了。