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

Keras是否内置方法将未拆分数据集划分为训练、验证、测试集?

Keras拆分未预先划分的类别式数据集

当然有啦!Keras针对这种按类别子文件夹存放的未拆分数据集,提供了非常实用的工具,完全不用你手动写复杂的拆分脚本。下面给你分享两种最常用的方法:

方法一:使用image_dataset_from_directory(推荐,TensorFlow 2.3+适用)

这个API是TensorFlow 2.3之后推出的,能直接从类别子文件夹加载数据,同时一键完成训练集、验证集的拆分,甚至可以间接得到测试集,用法特别简洁。

先看你的数据集结构:

data/
├── cats/
│   ├── cat1.jpg
│   ├── cat2.jpg
│   └── ...
└── dogs/
    ├── dog1.jpg
    ├── dog2.jpg
    └── ...

拆分训练集+验证集

直接用以下代码就能搞定:

import tensorflow as tf
from tensorflow.keras.utils import image_dataset_from_directory

# 加载训练集
train_ds = image_dataset_from_directory(
    'data/',
    validation_split=0.2,  # 预留20%的数据作为验证集
    subset="training",
    seed=123,  # 固定随机种子,保证每次拆分结果一致
    image_size=(150, 150),  # 统一图片尺寸,适配模型输入
    batch_size=32
)

# 加载验证集
val_ds = image_dataset_from_directory(
    'data/',
    validation_split=0.2,
    subset="validation",
    seed=123,  # 和训练集用同一个seed,确保拆分不重叠
    image_size=(150, 150),
    batch_size=32
)

额外拆分测试集

如果还需要单独的测试集,可以分两步走:先拆分出「训练+验证池」和测试集,再从池子里拆分训练集和验证集:

# 第一步:拆分出训练验证池(80%)和测试集(20%)
train_val_ds = image_dataset_from_directory(
    'data/',
    validation_split=0.2,
    subset="training",
    seed=456,
    image_size=(150, 150),
    batch_size=32
)

test_ds = image_dataset_from_directory(
    'data/',
    validation_split=0.2,
    subset="validation",
    seed=456,
    image_size=(150, 150),
    batch_size=32
)

# 第二步:从训练验证池中拆分90%作为训练集,10%作为验证集
# 这样总数据比例就是72%训练、8%验证、20%测试
train_ds = train_val_ds.take(int(len(train_val_ds)*0.9))
val_ds = train_val_ds.skip(int(len(train_val_ds)*0.9))

方法二:ImageDataGenerator配合train_test_split(旧版兼容方案)

如果你习惯用ImageDataGenerator做数据增强,也可以结合scikit-learn的train_test_split手动拆分文件路径,再用生成器加载数据。

步骤示例代码:

import os
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 第一步:收集所有图片的路径和对应标签
data_dir = 'data/'
classes = ['cats', 'dogs']
file_paths = []
labels = []

for cls_idx, cls_name in enumerate(classes):
    cls_dir = os.path.join(data_dir, cls_name)
    for img_name in os.listdir(cls_dir):
        file_paths.append(os.path.join(cls_dir, img_name))
        labels.append(cls_idx)

# 第二步:拆分训练验证池和测试集(8:2)
# 注意*stratify=labels*参数,保证每个类别的比例在拆分后和原数据集一致
train_val_paths, test_paths, train_val_labels, test_labels = train_test_split(
    file_paths, labels, test_size=0.2, random_state=123, stratify=labels
)

# 第三步:拆分训练集和验证集(9:1)
train_paths, val_paths, train_labels, val_labels = train_test_split(
    train_val_paths, train_val_labels, test_size=0.1, random_state=456, stratify=train_val_labels
)

# 第四步:用数据生成器加载数据
datagen = ImageDataGenerator(rescale=1./255)  # 归一化像素值

train_ds = datagen.flow_from_dataframe(
    dataframe=pd.DataFrame({'path': train_paths, 'label': train_labels}),
    x_col='path',
    y_col='label',
    target_size=(150,150),
    batch_size=32,
    class_mode='binary'
)

val_ds = datagen.flow_from_dataframe(
    dataframe=pd.DataFrame({'path': val_paths, 'label': val_labels}),
    x_col='path',
    y_col='label',
    target_size=(150,150),
    batch_size=32,
    class_mode='binary'
)

test_ds = datagen.flow_from_dataframe(
    dataframe=pd.DataFrame({'path': test_paths, 'label': test_labels}),
    x_col='path',
    y_col='label',
    target_size=(150,150),
    batch_size=32,
    class_mode='binary',
    shuffle=False  # 测试集不需要打乱,方便后续评估
)

关键注意点

  • 无论用哪种方法,都要记得用随机种子(比如seed或random_state)固定拆分结果,这样实验才能复现
  • 拆分时一定要保证类别比例一致:方法一中image_dataset_from_directory会自动分层,方法二中要加上stratify参数,避免某类别在某个子集里占比过高,保证模型训练的公平性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:37:28