猫狗数据集按8:1:1拆分train/val/test失败,测试集为空求助
问题分析与修复方案
你的核心问题是拆分逻辑错误:你只把数据集分成了80%训练集和20%验证集,完全没有从剩余数据中划分出测试集。从数据量来看,每个类别总共有12500条(10000+2500),2500刚好是总数据的20%,说明你把训练集之外的所有数据都给了验证集,测试集没有分到任何数据。
常见错误点及修复
1. 比例计算与切片错误
你可能写了类似这样的错误逻辑:
train_size = int(0.8 * total) val_files = files[train_size:] # 把剩下的20%全给验证集,没留测试集
正确的做法是从剩余的20%中再拆分出1:1的验证集和测试集:
total = len(files) train_size = int(0.8 * total) # 验证集占总数据的10%,测试集取剩余部分(避免浮点计算误差) val_size = int(0.1 * total) test_size = total - train_size - val_size train_files = files[:train_size] val_files = files[train_size:train_size+val_size] test_files = files[train_size+val_size:]
2. 遗漏测试集的文件移动逻辑
检查你的代码是否写了测试集文件的复制/移动代码,以及是否创建了测试集的目录。如果只处理了训练和验证集的文件,测试集目录自然是空的。
比如要确保有这部分代码:
# 创建测试集目录 os.makedirs(os.path.join(dest_dir, 'test', category), exist_ok=True) # 移动测试集文件 for file in test_files: shutil.copy(os.path.join(source_path, file), os.path.join(dest_dir, 'test', category, file))
3. 完整可用的拆分函数示例
这里是修正后的完整函数,适配猫狗数据集的12500条/类的规模:
import os import random import shutil def split_data(source_dir, dest_dir): # 遍历猫狗两个类别 for category in ['cat', 'dog']: source_path = os.path.join(source_dir, category) if not os.path.exists(source_path): continue files = [f for f in os.listdir(source_path) if f.endswith('.jpg')] random.seed(42) # 设置随机种子保证结果可复现 random.shuffle(files) total = len(files) train_size = int(0.8 * total) val_size = int(0.1 * total) test_files = files[train_size+val_size:] train_files = files[:train_size] val_files = files[train_size:train_size+val_size] # 创建所有需要的目录 for split in ['train', 'validation', 'test']: target_dir = os.path.join(dest_dir, split, category) os.makedirs(target_dir, exist_ok=True) # 批量移动文件 for file in train_files: shutil.copy(os.path.join(source_path, file), os.path.join(dest_dir, 'train', category, file)) for file in val_files: shutil.copy(os.path.join(source_path, file), os.path.join(dest_dir, 'validation', category, file)) for file in test_files: shutil.copy(os.path.join(source_path, file), os.path.join(dest_dir, 'test', category, file))
调用这个函数后,每个类别的训练集应该是10000条,验证集和测试集各1250条,符合8:1:1的比例要求。
内容的提问来源于stack exchange,提问作者Collander
相关产品推荐
相关产品推荐

