Validation Data
验证数据是在开发期间进行评分的留出数据集,用于调整超参数、选择检查点,并在最终测试前发现过拟合。
验证数据是从带标注的数据中留出的一部分,在开发过程中会反复评分,用于比较模型、调整超参数、选择检查点以及检测过拟合。模型不会根据验证数据更新其权重,因此验证分数反映了模型从训练数据中学到的内容迁移到未见图像时的效果。验证集和开发集(dev set)是同义词。每一项基于验证分数作出的决策,都会让模型更贴合该特定数据划分;因此需要另外留出测试集,以获得最终且无偏的评估结果。
训练集、验证集和测试集划分#
带标注的数据集通常分为三个部分:
- 训练集: 优化器据此调整权重的样本,通常占数据的 70% 到 80%。
- 验证集: 在训练运行结束或每个 epoch 后进行评分,用于指导学习率、模型大小、增强强度以及停止训练时机等选择。
- 测试集: 所有选择确定后进行一次评分,用于报告模型的预期真实表现。
对于包含数千张图像的数据集,70/15/15 或 80/10/10 的划分很常见。超大型数据集只需较小比例的数据,就能获得可靠估计:ImageNet-1k从 1,281,167 张训练图像中留出 50,000 张验证图像。由于其测试标签不公开,ImageNet 的准确率通常在该验证集上报告,因此该验证集也充当测试集。
实用的验证集应与模型在部署后会遇到的数据相匹配,并且与训练集毫无重叠。如果多张图像来自同一段视频、同一位患者或同一地点,按图像随机划分就会泄露信息,因为模型可能认出场景,而不是目标。按组别进行划分,例如按患者或录制会话划分,可以避免这种数据泄露。
超参数调优与模型选择#
权重通过梯度下降学习,而超参数则通过训练多个候选模型并保留验证分数最高的模型来选择。不能用训练分数作出这一选择,因为更大、训练时间更长的模型几乎总是能更好地拟合训练数据。下面的 scikit-learn 脚本使用内置的手写数字数据集调整决策树的深度:
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# Split 1,797 digit images 60/20/20 into training, validation, and test sets
X, y = load_digits(return_X_y=True)
X_train, X_rest, y_train, y_rest = train_test_split(X, y, test_size=0.4, random_state=0, stratify=y)
X_val, X_test, y_val, y_test = train_test_split(X_rest, y_rest, test_size=0.5, random_state=0, stratify=y_rest)
# Fit one model per candidate tree depth and score each on the validation set
val_scores = {}
for depth in (2, 4, 8, 16):
model = DecisionTreeClassifier(max_depth=depth, random_state=0).fit(X_train, y_train)
val_scores[depth] = model.score(X_val, y_val)
print(f"depth {depth}: train {model.score(X_train, y_train):.3f}, validation {val_scores[depth]:.3f}")
# Refit the winner and score the test set exactly once
best = max(val_scores, key=val_scores.get)
final = DecisionTreeClassifier(max_depth=best, random_state=0).fit(X_train, y_train)
print(f"Chosen depth {best}: test accuracy {final.score(X_test, y_test):.3f}")随着深度增加,训练准确率持续上升,并在深度为 16 时达到 1.000;而验证准确率在深度为 8 时达到峰值 0.836,随后随着树开始记忆训练数据,在深度为 16 时降至 0.825。验证结果选出深度为 8 的模型,该模型在未触碰过的测试集上取得 0.853 的分数。
早停与检查点选择#
深度学习训练循环通常会在每个epoch结束后对验证集评分。随着网络越来越贴合训练数据,训练损失会持续下降,但验证损失或准确率最终会趋于平稳,随后开始变差。如果验证分数在设定数量的 epoch 内(该数量称为耐心值)没有改善,早停就会结束训练,并保留表现最佳的 epoch 所对应的权重。
Ultralytics 中的 YOLO26 训练默认会运行这一循环:每个 epoch 后,系统会根据数据集 YAML中的 val 划分进行评分,将验证适应度(检测任务中为 mAP50-95)最高的 epoch 保存为 best.pt;如果连续 patience 个 epoch 没有改善,就会停止训练,默认值为 100。
from ultralytics import YOLO
# 加载一个预训练的 YOLO26 nano 检测器
model = YOLO("yolo26n.pt")
# 每个 epoch 后在 val 划分上进行验证,并在连续 10 个 epoch 没有改善后停止
results = model.train(data="coco8.yaml", epochs=50, patience=10)小型数据集的交叉验证#
数据稀缺时,单次留出划分会浪费样本,且评分波动较大。K 折交叉验证会将数据分成 K 折,训练 K 个模型,每个模型都留出不同的一折用于验证,然后对 K 个分数取平均,因此每个样本都会同时用于训练和验证。五折和十折较常见;分层和分组变体会在每一折中保持类别比例均衡,或将相关图像放在一起。测试集仍位于所有数据折之外。
验证数据与相关术语的比较#
- 测试数据: 在最后评分一次。重复使用测试数据来作出选择,会使其变成第二个验证集,其分数也不再是无偏估计。
- 训练数据: 优化器据此学习权重的唯一数据划分。
- 交叉验证: 一种轮换不同样本作为验证数据的流程,可从一个数据集得到 K 个验证分数。
- 临床和监管文件中的验证: 在医学和受监管行业中,验证模型通常是指使用独立的外部数据评估已完成的模型;在机器学习术语中,这对应测试集。










