将数据数值化、特征缩放并处理分类变量之后,在开始训练神经网络之前,还有一个必要的步骤:恰当地划分数据集。简单地用所有可用数据训练模型,然后用相同数据评估,这样做会产生误导。模型可能表现得非常好,但这种表现通常是由于记忆了训练样本,而非学习到普遍规律。这种现象称为过拟合,它会导致模型遇到新的、未见过的数据时性能不佳。为构建对新数据泛化能力强的模型,我们需要一种方法来评估模型在训练期间未见过样本上的表现。这通过将数据集分成不同的子集实现,通常是三个:训练集、验证集和测试集。训练集这是数据中最大的部分,也是模型直接从中学习的唯一数据。在训练过程中,模型会遍历训练集,计算预测值,衡量误差(损失),并通过反向传播和梯度下降调整其内部参数(权重和偏差),以最小化此误差。目标是让模型学习此数据中输入到输出的内在映射。验证集“在训练集上训练模型之后,如何调整其设置或决定哪种模型架构最有效?直接在训练集上评估无益,因为会发生过拟合。在调整过程中使用最终测试集进行评估也存在问题,因为你可能会无意中使模型专门针对该测试集表现良好,从而对其性能产生虚高的认知。”这就是验证集(有时也称开发集或开发用数据集)的作用所在。它是数据中模型不用于训练的独立部分。它的主要用途有:超参数调整: 神经网络有多种并非直接从数据中学习,而是预先设定的设置,这些设置称为超参数。例子包括学习率、层数、每层的神经元数量、激活函数类型或正则化强度。你在训练集上训练不同版本的模型(使用不同的超参数设置),并在验证集上评估它们的表现。那些在验证集上产生最佳表现的设置通常会被选用。模型选择: 如果你正在比较根本不同的模型架构,验证集会帮助你选择最有潜力的那个。提前停止: 你可以在训练期间监控模型在验证集上的表现(例如,损失或准确率)。通常,训练损失会持续下降,而验证损失在某个点后开始上升。这表示过拟合。提前停止利用这个信号在模型过度过拟合之前中止训练过程,从而保存验证表现最佳时的模型参数。验证集在模型开发周期中充当未见过数据的代表。测试集一旦你使用训练集训练了模型,并使用验证集调整了超参数和做出了模型决策,你需要对你选择的模型在全新数据上的表现进行最终的、无偏的评估。这就是测试集的作用。“测试集被保留,且仅在所有训练和调整完成后使用一次。它应代表模型将遇到的数据。在测试集上评估可获得你将为模型报告的最终性能指标(如准确率、精确率、召回率或均方误差)。绝对不要将测试集用于任何调整或模型选择决策;这样做会使其作为泛化性能无偏估计器的作用失效。可以将其视为模型的期末考试。”划分比例与策略你应该为每个集合分配多少数据?没有固定规则,最佳划分取决于数据集的总大小和具体问题。常见的起始分配方式包括:70% 训练集,15% 验证集,15% 测试集: 适中规模数据集的常见划分方式。80% 训练集,10% 验证集,10% 测试集: 数据量充足时常使用。60% 训练集,20% 验证集,20% 测试集: 另一种均衡选项。对于非常大的数据集(数百万样本),验证集和测试集有时可以占更小的百分比(例如,98%训练,1%验证,1%测试),因为即使是1%也代表了大量的样本,足以进行可靠评估。digraph G { rankdir=LR; node [shape=box, style=filled, fillcolor="#e9ecef"]; splines=false; fontname="sans-serif"; edge [fontname="sans-serif"]; node [fontname="sans-serif"]; FullDataset -> Train [label=" 划分 (~70%)"]; FullDataset -> Validation [label=" 划分 (~15%)"]; FullDataset -> Test [label=" 划分 (~15%)"]; FullDataset [label="原始数据集", fillcolor="#ced4da"]; Train [fillcolor="#a5d8ff", label="训练集\n(模型学习)"]; Validation [fillcolor="#b2f2bb", label="验证集\n(超参数调整,\n模型选择, 提前停止)"]; Test [fillcolor="#ffd8a8", label="测试集\n(最终无偏评估)"]; { rank=same; Train; Validation; Test; } }数据集划分为训练集、验证集和测试集的可视化图示,强调了它们的主要作用。实现数据划分数据划分在实践中很少手动执行。Python中的Scikit-learn等库提供了便捷的函数。一种常见的方法是首先将数据划分为一个较大的训练集和一个较小的测试集,然后将较大的训练集再次划分为最终的训练集和验证集。# 使用Scikit-learn的例子 from sklearn.model_selection import train_test_split # 假设X包含特征,y包含标签/目标 # 首先划分为训练+验证集 (85%) 和测试集 (15%) X_train_val, X_test, y_train_val, y_test = train_test_split( X, y, test_size=0.15, random_state=42, stratify=y # 在分类任务中使用 stratify ) # 计算验证集相对于 train_val 集的大小 # 如果测试集是15%,验证集是15%,则验证集相对于 train_val 集的比例为 15 / (100-15) = 15/85 = 约0.176 val_size_relative = 0.15 / (1.0 - 0.15) # 将 train_val 划分为最终的训练集和验证集 X_train, X_val, y_train, y_val = train_test_split( X_train_val, y_train_val, test_size=val_size_relative, random_state=42, stratify=y_train_val # 再次使用 stratify ) print(f"原始数据集大小: {len(X)}") print(f"训练集大小: {len(X_train)}") print(f"验证集大小: {len(X_val)}") print(f"测试集大小: {len(X_test)}")分层抽样注意 train_test_split 例子中的 stratify 参数。处理分类问题时,特别是当某些类别远不如其他类别常见(数据不平衡)时,确保训练集、验证集和测试集中每个类别的比例与原始数据集大致相同是很重要的。随机划分可能导致某些类别在子集中出现过多或过少的情况,从而可能使训练或评估产生偏差。分层划分可以保持跨分割的类别比例,从而带来更可靠的模型开发和评估。通常,你根据目标变量 y 进行分层。通过将数据仔细划分为这三个集合,你就建立了一种健全的方法来训练神经网络、调整其配置,并获得其在新、未见过数据上表现能力的可靠衡量。这种结构化方法对于开发有效的机器学习模型非常重要。