You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卷积神经网络测试阶段是否作弊?数据集划分技术问询

关于CNN数据集划分与数据增强的问题解答

首先直接给你结论:你提出的将原测试集拆分为验证集和测试集的做法,确实属于测试阶段的作弊行为,原因我后面详细解释,先帮你解决核心困境——在不修改文件夹结构的前提下,实现训练集数据增强、验证集不增强,同时保证测试集的独立性。

为什么你的第二种方案是作弊?

测试集的核心作用是模拟模型部署后的真实场景,必须满足从未被模型训练过程、调参过程接触过的要求。如果把原测试集拆成验证集和测试集:

  • 你会用拆分出的验证集来调整模型的超参数(比如学习率、增强参数)、选择模型结构,这相当于模型已经间接"见过"测试集的部分数据分布
  • 最终用剩下的测试集评估时,结果会高估模型的真实泛化能力,因为测试集和验证集来自同一分布,模型已经适应了这个分布的特征

这完全违背了测试集的设计初衷,属于典型的"数据泄露"。

正确的解决方案:不修改文件夹,拆分训练集为训练/验证并分别处理

既然你无权修改原始文件夹结构,我们可以通过代码层面拆分训练集的文件路径,给训练集和验证集分别配置不同的ImageDataGenerator——训练集用带增强的,验证集只做归一化。

具体步骤如下:

  1. 提取训练集的所有文件路径和标签
    先遍历训练文件夹,把所有图像的路径和对应的类别标签提取出来:

    import os
    import numpy as np
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    
    def get_file_paths_and_labels(base_dir):
        file_paths = []
        labels = []
        # 获取所有类别文件夹
        class_folders = sorted([f for f in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, f))])
        for class_idx, class_name in enumerate(class_folders):
            class_dir = os.path.join(base_dir, class_name)
            # 遍历类别下的所有图像
            for img_file in os.listdir(class_dir):
                file_paths.append(os.path.join(class_dir, img_file))
                labels.append(class_idx)
        return np.array(file_paths), np.array(labels)
    
    # 替换成你的训练文件夹路径
    train_files, train_labels = get_file_paths_and_labels(training_path)
    
  2. 拆分训练集为训练子集和验证子集
    用train_test_split按比例拆分,注意用stratify参数保证类别分布一致:

    # 80%训练,20%验证,随机种子固定保证可复现
    train_subset_files, val_subset_files, train_subset_labels, val_subset_labels = train_test_split(
        train_files, train_labels, test_size=0.2, stratify=train_labels, random_state=42
    )
    
  3. 创建DataFrame并生成数据
    把拆分后的路径和标签转换成DataFrame,然后用flow_from_dataframe分别生成训练、验证、测试数据:

    # 训练集用带数据增强的生成器
    train_datagen = ImageDataGenerator(
        rescale=1./255,
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest'
    )
    
    # 验证集和测试集只做归一化,不增强
    val_test_datagen = ImageDataGenerator(rescale=1./255)
    
    # 转换为DataFrame
    train_df = pd.DataFrame({"filename": train_subset_files, "class": train_subset_labels})
    val_df = pd.DataFrame({"filename": val_subset_files, "class": val_subset_labels})
    
    # 生成训练数据
    train_generator = train_datagen.flow_from_dataframe(
        dataframe=train_df,
        x_col="filename",
        y_col="class",
        target_size=(150, 150),
        batch_size=20,
        class_mode="binary"
    )
    
    # 生成验证数据
    val_generator = val_test_datagen.flow_from_dataframe(
        dataframe=val_df,
        x_col="filename",
        y_col="class",
        target_size=(150, 150),
        batch_size=20,
        class_mode="binary"
    )
    
    # 生成测试数据(用原始测试文件夹)
    test_generator = val_test_datagen.flow_from_directory(
        directory=test_path,
        target_size=(150, 150),
        batch_size=20,
        class_mode="binary"
    )
    

这个方案的优势

  • 完全不需要修改原始文件夹结构,解决了你的权限问题
  • 训练集正常应用数据增强,验证集只做归一化,保证验证结果能准确反映模型的泛化能力
  • 测试集完全独立,没有参与任何训练或调参过程,评估结果真实可靠

内容的提问来源于stack exchange,提问作者Albert Friedmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:42:50