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

Keras使用ImageDataGenerator训练时报y参数不支持错误

问题根源

这个报错的核心触发原因是:Keras中当你给model.fit()传入的输入是keras.utils.Sequence类型对象(flow_from_directory返回的目录迭代器就属于这类对象)时,不支持再单独传入y参数传标签。这种输入模式下,要求传入的Sequence对象本身每次迭代必须返回(输入批次, 对应标签批次)的元组,你现在把输入X和标签Y拆成了两个独立的Sequence对象,分别传给fit的x和y位置,就会直接抛出这个错误。

除了这个直接触发报错的问题,你写的加载代码还有几个隐藏逻辑错误,就算绕开报错也无法正常训练:

  • 验证集标签的加载参数写错:训练集标签从train_cleaned_path下的output文件夹读取,验证集标签却错误指向同路径下的train_cleaned文件夹;同时验证集标签生成器的class_mode填了不存在的合法值'output',正确的返回图像本身作为标签的取值应该是'input'。
  • 样本配对无保证:两个独立的生成器分别加载X和Y,只要shuffle规则、文件排序逻辑、种子值有一点不一致,就会出现输入图和标注图错配的问题,训练出来的模型完全无效。
  • 参数重复传无效:你已经用flow_from_directory生成批次数据,又在fit里传了batch_size=16,这个参数仅对数组形式的输入生效,传入Sequence时不会起作用,批大小需要在生成器初始化时设置。
修正方法

最稳妥的方案是自定义一个配对图像的Sequence数据集类,同时读取对应路径下的输入图和标注图,从根源上保证样本配对正确,也能天然适配fit的输入要求。

  1. 先导入依赖
from tensorflow.keras.utils import Sequence
from PIL import Image
import numpy as np
import os
from sklearn.model_selection import train_test_split
  1. 实现配对图像加载的数据集类
class PairedImgDataset(Sequence):
    def __init__(self, input_dir, target_dir, batch_size, img_size, shuffle=True, file_list=None):
        self.input_dir = input_dir
        self.target_dir = target_dir
        self.batch_size = batch_size
        self.img_size = img_size
        self.shuffle = shuffle
        # 加载指定的文件名列表,用于训练/验证集划分
        self.file_list = file_list if file_list is not None else [
            f for f in os.listdir(input_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))
        ]
        self.on_epoch_end()

    def __len__(self):
        # 返回单个epoch包含的batch数量
        return len(self.file_list) // self.batch_size

    def on_epoch_end(self):
        # 每个epoch结束后打乱样本顺序
        self.indexes = np.arange(len(self.file_list))
        if self.shuffle:
            np.random.shuffle(self.indexes)

    def __getitem__(self, idx):
        # 加载当前batch的所有样本
        batch_idx = self.indexes[idx*self.batch_size : (idx+1)*self.batch_size]
        batch_x, batch_y = [], []
        for i in batch_idx:
            fname = self.file_list[i]
            # 读取输入图,resize后归一化到0-1区间
            x = np.array(Image.open(os.path.join(self.input_dir, fname)).convert('RGB').resize(self.img_size)) / 255.0
            # 读取同文件名的标注图,保证和输入严格配对
            y = np.array(Image.open(os.path.join(self.target_dir, fname)).convert('RGB').resize(self.img_size)) / 255.0
            batch_x.append(x)
            batch_y.append(y)
        return np.array(batch_x), np.array(batch_y)
  1. 划分训练/验证集,初始化数据加载器
# 按你的实际路径修改配置
INPUT_FOLDER = "input文件夹的完整路径"
TARGET_FOLDER = "output文件夹的完整路径"
BATCH_SIZE = 16
IMG_SHAPE = (256, 256) # 替换为你模型要求的输入尺寸
VAL_SPLIT = 0.2

# 按比例划分训练/验证集对应的文件名
all_imgs = [f for f in os.listdir(INPUT_FOLDER) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
train_files, val_files = train_test_split(all_imgs, test_size=VAL_SPLIT, random_state=42)

# 初始化训练、验证数据集
train_ds = PairedImgDataset(
    input_dir=INPUT_FOLDER,
    target_dir=TARGET_FOLDER,
    batch_size=BATCH_SIZE,
    img_size=IMG_SHAPE,
    shuffle=True,
    file_list=train_files
)
val_ds = PairedImgDataset(
    input_dir=INPUT_FOLDER,
    target_dir=TARGET_FOLDER,
    batch_size=BATCH_SIZE,
    img_size=IMG_SHAPE,
    shuffle=False,
    file_list=val_files
)
  1. 调用fit训练,不需要单独传y和batch_size
history = conv_NN.fit(
    train_ds,
    validation_data=val_ds,
    epochs=20,
    callbacks=[early_stop, tensorboard_callback],
    verbose=1
)

如果你坚持要用flow_from_directory实现,必须保证X和Y的两个生成器参数完全一致(相同的seed、shuffle设为False、相同batch_size、相同文件排序逻辑),再用tf.data.Dataset.zip把两个生成器打包成返回(x,y)的数据集传入fit,但这种方式很容易因为参数不匹配出现样本错配,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:31:02