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

使用zip对象传入model.fit()报错:数据类型无法识别的解决方法

分割模型生成器适配问题解决方案

问题背景

开发分割模型时,使用ImageDataGenerator()加载图像和掩码并返回zip对象,传入model.fit()时触发如下错误:

ValueError: Unrecognized data type: x=<zip object at 0x00000172364F6040> (of type <class 'zip'>)

原代码如下:

def create_segmentation_generator_train(img_path, msk_path, BATCH_SIZE):
    data_gen_args = #augmentation code
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    return zip(img_generator, msk_generator)

# Remember not to perform any image augmentation in the test generator!
def create_segmentation_generator_test(img_path, msk_path, BATCH_SIZE):
    data_gen_args = dict(rescale=1./255)
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    return zip(img_generator, msk_generator)

train_generator = create_segmentation_generator_train(data_dir_train_image, data_dir_train_mask, BATCH_SIZE_TRAIN)
test_generator = create_segmentation_generator_test(data_dir_test_image, data_dir_test_mask, BATCH_SIZE_TEST)

解决方案

Keras不支持直接将原生zip对象作为训练输入,需将其包装为Keras可识别的生成器或tf.data.Dataset,以下是两种可行方案:

方案1:包装为自定义生成器

修改生成器函数,返回一个逐批次输出图像和掩码对的Python生成器:

def create_segmentation_generator_train(img_path, msk_path, BATCH_SIZE):
    data_gen_args = # 填入你的图像增强参数
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    
    def seg_generator():
        for img_batch, msk_batch in zip(img_generator, msk_generator):
            # 掩码归一化到0-1区间(多分类任务需转one-hot编码)
            msk_batch = msk_batch / 255.0
            yield img_batch, msk_batch
    return seg_generator()

# 测试生成器同步修改
def create_segmentation_generator_test(img_path, msk_path, BATCH_SIZE):
    data_gen_args = dict(rescale=1./255)
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    
    def seg_generator():
        for img_batch, msk_batch in zip(img_generator, msk_generator):
            msk_batch = msk_batch / 255.0
            yield img_batch, msk_batch
    return seg_generator()

方案2:使用tf.data.Dataset包装

借助TensorFlow的Dataset API整合生成器,适配性更强且性能更优:

import tensorflow as tf

def create_segmentation_generator_train(img_path, msk_path, BATCH_SIZE):
    data_gen_args = # 填入你的图像增强参数
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    
    # 转换为tf.data.Dataset并指定输出格式
    seg_dataset = tf.data.Dataset.from_generator(
        lambda: zip(img_generator, msk_generator),
        output_signature=(
            tf.TensorSpec(shape=(BATCH_SIZE, *IMG_SIZE, 1), dtype=tf.float32),
            tf.TensorSpec(shape=(BATCH_SIZE, *IMG_SIZE, 1), dtype=tf.float32)
        )
    )
    # 添加掩码预处理
    seg_dataset = seg_dataset.map(lambda x, y: (x, y / 255.0))
    return seg_dataset

# 测试生成器同步修改
def create_segmentation_generator_test(img_path, msk_path, BATCH_SIZE):
    data_gen_args = dict(rescale=1./255)
    datagen = ImageDataGenerator(**data_gen_args)
    
    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode='grayscale', batch_size=BATCH_SIZE, seed=SEED)
    
    seg_dataset = tf.data.Dataset.from_generator(
        lambda: zip(img_generator, msk_generator),
        output_signature=(
            tf.TensorSpec(shape=(BATCH_SIZE, *IMG_SIZE, 1), dtype=tf.float32),
            tf.TensorSpec(shape=(BATCH_SIZE, *IMG_SIZE, 1), dtype=tf.float32)
        )
    )
    seg_dataset = seg_dataset.map(lambda x, y: (x, y / 255.0))
    return seg_dataset

注意事项

  • 掩码预处理需根据任务调整:二分类分割归一化到0-1即可,多分类需转换为one-hot编码。
  • output_signature中的形状要与你的IMG_SIZE、批量大小和通道数匹配。

内容的提问来源于Stack Exchange,提问作者Ashwin Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:47:03