当使用 fit() 方法训练神经网络时,优化器会努力使在训练数据上计算出的损失函数最小化。在这些数据上报告的指标,例如训练准确率,能说明模型对所见特定样本的学习情况。然而,我们的最终目标不仅仅是在模型已见过的数据上表现良好;而是要构建一个能很好地泛化到全新、未见数据的模型。如何在训练过程中评估这种泛化能力呢?这就是验证数据的作用所在。仅仅监控训练损失和指标可能会产生误导。模型可能会变得极其擅长预测训练样本,实际上是“记忆”了它们,包括它们的噪声和特性。这种现象,称为过拟合,会导致在训练集上表现出色,但在遇到新数据时表现不佳。模型未能捕获泛化所需的潜在规律。划分验证数据为了更实际地评估模型在未见数据上的表现,我们需要定期在一个模型未参与训练的单独数据集上对其进行评估。这就是验证集。在Keras中,在训练期间引入验证有两种主要方式:使用 validation_split: 您可以专门保留一部分训练数据用于验证。Keras 会在训练开始前自动划出指定百分比的数据,并在每个周期结束时专门将其用于验证。如果您没有预定义的验证集,这会很方便。# 假设 x_train 和 y_train 包含您的全部训练数据 history = model.fit(x_train, y_train, epochs=30, batch_size=64, validation_split=0.2) # 使用最后 20% 的数据进行验证使用 validation_data: 您可以提供一个元组 (x_val, y_val),其中包含一个完全独立的验证数据集的特征和标签。这通常是更受欢迎的方式,因为它让您能更好地控制,以确保验证集具有代表性且与训练过程独立。# 假设 x_train_p, y_train_p 是训练部分 # x_val, y_val 是单独的验证集 history = model.fit(x_train_p, y_train_p, epochs=30, batch_size=64, validation_data=(x_val, y_val)) # 使用提供的验证集重要的是,验证数据应来自与训练数据相同的底层分布,但其中包含模型在训练更新过程中未曾见过的样本。模型的权重绝不会根据验证集的表现进行更新;它纯粹用于监控。监控性能指标当您使用 fit() 方法并结合 validation_split 或 validation_data 时,Keras 会在每个周期结束时在验证集上评估模型。结果会被添加到 fit() 返回的 History 对象中。这些指标通常以 val_ 为前缀。例如,如果您使用 loss='binary_crossentropy' 和 metrics=['accuracy'] 编译模型,history.history 字典将包含如下键:loss:每个周期的训练损失。accuracy:每个周期的训练准确率。val_loss:每个周期的验证损失。val_accuracy:每个周期的验证准确率。绘制这些指标随周期变化的图表是理解训练动态的常规做法。解释训练与验证曲线分析训练与验证损失及指标的图表,对于诊断过拟合或欠拟合等潜在问题非常基础。理想情况: 训练和验证损失都稳步下降并收敛到相似的低值。同样,训练和验证准确率上升并停留在相似的高值。这表明模型正在学习可泛化的规律。过拟合: 训练损失持续下降(或训练准确率提高),但在若干周期后,验证损失开始上升(或验证准确率停滞或下降)。这种背离表明模型开始记忆训练数据,并失去泛化能力。训练和验证曲线之间的差距显著拉大。{"layout": {"title": "训练与验证损失对比(过拟合示例)", "xaxis": {"title": "周期"}, "yaxis": {"title": "损失"}, "legend": {"orientation": "h", "yanchor": "bottom", "y": 1.02, "xanchor": "right", "x": 1}, "margin": {"l": 40, "r": 0, "t": 40, "b": 40}, "autosize": true}, "data": [{"x": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50], "y": [0.8, 0.5, 0.35, 0.25, 0.2, 0.15, 0.12, 0.1, 0.08, 0.07, 0.06], "mode": "lines", "name": "训练损失", "line": {"color": "#339af0"}}, {"x": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50], "y": [0.9, 0.6, 0.45, 0.4, 0.38, 0.39, 0.42, 0.45, 0.5, 0.55, 0.6], "mode": "lines", "name": "验证损失", "line": {"color": "#ff922b"}}]}训练损失稳步下降,而验证损失在第20个周期后开始上升,表明出现过拟合。欠拟合: 训练和验证损失都保持在高位,或者下降非常缓慢并在高值处停滞。同样,准确率保持在低位。这表明模型过于简单,或者训练时间不足以捕获数据中的潜在规律。{"layout": {"title": "训练与验证损失对比(欠拟合示例)", "xaxis": {"title": "周期"}, "yaxis": {"title": "损失"}, "legend": {"orientation": "h", "yanchor": "bottom", "y": 1.02, "xanchor": "right", "x": 1}, "margin": {"l": 40, "r": 0, "t": 40, "b": 40}, "autosize": true}, "data": [{"x": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50], "y": [1.5, 1.3, 1.2, 1.15, 1.1, 1.08, 1.06, 1.05, 1.04, 1.03, 1.02], "mode": "lines", "name": "训练损失", "line": {"color": "#339af0"}}, {"x": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50], "y": [1.55, 1.35, 1.25, 1.2, 1.15, 1.13, 1.11, 1.1, 1.09, 1.08, 1.07], "mode": "lines", "name": "验证损失", "line": {"color": "#ff922b"}}]}训练和验证损失都较高且下降缓慢,表明出现欠拟合。"因此,监控验证性能非常重要。它提供了模型在未见数据上表现的替代指标,并有助于确定训练期间模型达到最佳泛化能力的时刻。及早识别过拟合,可以使您在模型在新数据上的性能下降之前停止训练。像早期停止和正则化这样的方法(我们将在第6章讨论),直接利用验证监控来提升模型的泛化能力。目前,请记住在 fit() 期间观察 val_ 指标是您评估训练是否朝正确方向前进的主要工具。"