细说深度学习训练集、验证集、测试集(为什么有的论文的数据集只有训练集和验证集而无测试集)

验证集的作用:验证集是用来让我们验证一下网络的当前训练结果,以便于我们观察模型的泛化能力,看模型是否有过拟合,以调整网络的超参数如网络架构,学习率等。注意网络的训练并没有真的用到验证集,因为验证期间没有计算梯度,没有更新参数!

我们知道,传统机器学习的根本假设是:用于训练模型的数据和用来测试模型的数据来自同一个概率分布

对于规模很大的数据集,我们可以理想一点,认为他们服从这个根本假设。既然数据集很大,那我们就可以奢侈一点,把数据集划分为术业有专攻的三块:训练集,验证集,测试集。

但是其实很多时候只分为两块,即训练集和测试集,一是因为数据量有限,二是因为测试集可以身兼两职,既可以用作验证集来验证模型的训练结果,又可以用来得到最终测试结果

分为两块的这种划分还有个专门的名字,叫做“留出法”。

训练集用来训练NN,即根据反向传播的误差对每个参数的梯度进行参数更新;

验证集专门用来看看每经过1个epoch的训练之后,NN的性能如何,即验证一下当前模型的能力,那当然要用模型从来没见过的数据,即验证集绝对不能来自训练集

(如果把训练集的一部分作为验证集,那模型当然会表现很好,因为已经见过了,并且根据这些数据还做了自我校正。就像考试出原题无法验证考生的真实学习能力一样。)

最重要的一点:验证NN性能的过程不会更新网络的参数,因为验证时停止了梯度的反向传播!这一点一看代码就知道了。

所以!验证就是测试,测试就是验证,使用的是同样的代码,只是由于目的不同而有了不同的名字

所以!如果你的任务中数据集比较小的话,完全可以拿测试数据作为验证数据,而不必非要分为三部分,害的每一部分的size都很捉襟见肘,搞得训练集太小不够训练,测试集太小使得测试精度不那么可信,很尴尬。

这也是为什么很多论文中给出的训练过程图中给的是训练精度(train_accuracy)和测试精度(test_accuracy)的变化,而非训练精度和验证精度(validation_accuracy)。比如:

如果验证集就是测试数据的话,那么test_accuracy曲线的最后一个值就是最终的测试精度啦。

测试集就是最终要测试的数据了,是要得到一个结果,比如精度或者误差。

既然测试集可以用作验证集,那为啥还要分成三个集呢?
这太简单了,因为测试数据会变化啊。训练好一个模型后,之后可能会把他用到新的测试数据上,但是之前训练过程中用了当时任务的测试数据做验证集。

有必要说一说交叉验证,因为我之前把交叉验证和验证集搞混。

上面的留出法多做几次,把结果取平均就是交叉验证了。

交叉验证是针对数据集太小的情况,想要充分榨干这个小数据集的光和热,数据集够大就不需要折腾这个了。直接举个例子说明:

如果一个数据集有100条数据,按照8:2分为训练集和测试集(直接用测试集作为验证集),则应该用训练集的80条数据训练模型,用测试集的20条数据来测试训练的效果如何。

显然,这个模型只见到了80条数据,而有20条没见过,如果这俩数字是80000和20000,那我们觉得这个模型是可信的,毕竟8万条数据含有的多样性大概率已经包含了这2万条所含的多样性,所以无需钻研交叉验证。

但是80和20这两个数字,样本量太吝啬,我们会觉得这80条数据很可能没有包含着20条所能展示的多样性(信息),所以用这80条数据训练的模型的效果也就不那么可信了,因为这个模型没见过这20条数据的模式,所以识别效果也许也不好,即过拟合。

如果不考虑扩充数据集,那就只能充分利用这个小数据集。于是就有了交叉验证:我们再重新划分4次训练集和测试集,每次拿不同的80条作为训练集,另外20条作为测试集;最后把五次实验结果一平均,就是5折交叉验证。

注意在实现中,5次实验的5个测试集,不是说必须完全不同(第一次以编号为0-19的作为测试集,第二次20-39,第三次40-59,第四次60-79...),当然,这样做才严格符合交叉验证的定义,这样最好。

但是为了实现方便,一般是用随机法来近似。即:随机选择20条作为测试集,剩下的就是训练集了,5折就选5次,10折就选10次。


总之,训练集是用来通过梯度反向传播更新参数的,而验证集和测试集不会通过梯度反向传播更新参数,所以测试集和验证集完全可以是同一个数据集,而他俩都不可以和训练集有交叠,即必须互斥。

### 解决 KITTI 数据集缺少验证集的问题 在机器学习项目中,尤其是涉及到自动驾驶计算机视觉的任务时,数据集的质量至关重要。对于像KITTI这样的经典数据集,其结构设计可能并不完全满足现代研究的需求,特别是缺乏独立的验证集这一问题。 #### 方法一:划分训练集创建验证集 一种常见的做法是从现有的训练集中随机抽取一部分样本作为验证集。这可以通过设定固定的随机种子来确保不同实验之间的可重复性[^4]。具体实现如下: ```python import numpy as np from sklearn.model_selection import train_test_split # 假设 X 是输入特征, y 是标签 X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 进一步将训练集划分为训练子集验证子集 X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.25, random_state=42) ``` 这种方法的优点在于简单易行,并且能够利用已有的全部可用数据进行模型训练与调优;然而,这也可能导致过拟合的风险增加,因为测试集的数据分布未必能很好地代表实际应用场景下的情况。 #### 方法二:交叉验证技术的应用 另一种更为严谨的方式是采用k折交叉验证(k-fold Cross Validation),即将原始训练集分成 k 个互斥的小集合(fold),依次轮流选取其中一个 fold 作验证集,其余 k-1 folds 合并起来构成临时训练集来进行建模训练。此过程中每一轮都会得到一组性能度量结果,最终取平均值得到整体评估指标。 ```python from sklearn.model_selection import KFold kf = KFold(n_splits=5, shuffle=True, random_state=42) for train_index, val_index in kf.split(X_train_val): X_train_fold, X_val_fold = X_train_val[train_index], X_train_val[val_index] y_train_fold, y_val_fold = y_train_val[train_index], y_train_val[val_index] # 训练模型... # 使用验证集评估模型... ``` 这种方式有助于更全面地理解模型泛化能力的同时减少因单一验证集带来的偏差影响。 #### 方法三:引入外部相似环境的数据增强 考虑到KITTI本身存在局限性——即大部分场景局限于城市道路及高速公路上相对简单的路况[^2],因此还可以考虑寻找其他具有互补性的公开数据源并与之融合使用。例如,Waymo Open Dataset 或者 nuScenes 提供了更加多样化的真实世界驾驶情景描述,这些额外资源可以帮助构建更具代表性也更为丰富的验证集。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值