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

使用ImageDataGenerator对肝脏超声图像数据集过采样时遇参数错误

问题原因

keras.preprocessing.image.ImageDataGenerator 类的初始化方法中没有oversample这个参数,传入该参数会触发TypeError。

解决数据集不平衡的可行方案

方案1:使用类权重(Class Weight)

在模型训练阶段,给样本量少的类别设置更高权重,让模型更重视少数类样本。

代码示例

from keras.preprocessing.image import ImageDataGenerator
from sklearn.utils.class_weight import compute_class_weight
import numpy as np

# 初始化数据生成器(移除不存在的oversample参数)
train_datagen = ImageDataGenerator(
    rescale=1./255,
    samplewise_center=True,
    samplewise_std_normalization=True,
    horizontal_flip=True,
    vertical_flip=True,
    rotation_range=90,
    brightness_range=[0.5, 1.5],
    zoom_range=0.2,
    shear_range=0.2
)

# 从目录加载训练数据
train_generator = train_datagen.flow_from_directory(
    'train_dir',
    target_size=(224, 224),
    batch_size=32,
    class_mode='binary'  # 根据任务调整,多分类用'categorical'
)

# 计算类权重
class_weights = compute_class_weight(
    class_weight='balanced',
    classes=np.unique(train_generator.classes),
    y=train_generator.classes
)
class_weight_dict = dict(enumerate(class_weights))

# 训练时传入类权重
model.fit(
    train_generator,
    epochs=20,
    class_weight=class_weight_dict
)

方案2:手动过采样少数类

针对少数类样本单独做数据增强,生成更多样本平衡两类数据量。

代码示例

from keras.preprocessing.image import ImageDataGenerator
import numpy as np

# 为两类分别定义生成器:多数类仅基础缩放,少数类做全量增强
major_datagen = ImageDataGenerator(rescale=1./255)
minor_datagen = ImageDataGenerator(
    rescale=1./255,
    samplewise_center=True,
    samplewise_std_normalization=True,
    horizontal_flip=True,
    vertical_flip=True,
    rotation_range=90,
    brightness_range=[0.5, 1.5],
    zoom_range=0.2,
    shear_range=0.2
)

# 加载两类数据
major_generator = major_datagen.flow_from_directory(
    'train_dir/major_class',
    target_size=(224, 224),
    batch_size=32,
    class_mode='binary'
)
minor_generator = minor_datagen.flow_from_directory(
    'train_dir/minor_class',
    target_size=(224, 224),
    batch_size=32,
    class_mode='binary'
)

# 计算少数类需要重复生成的次数,匹配多数类样本量
major_count = len(major_generator.filenames)
minor_count = len(minor_generator.filenames)
repeat_times = major_count // minor_count

# 合并生成器,输出平衡的批次
def balanced_generator():
    while True:
        x_major, y_major = next(major_generator)
        # 多次获取少数类批次并合并
        x_minor_list, y_minor_list = [], []
        for _ in range(repeat_times):
            x_min, y_min = next(minor_generator)
            x_minor_list.append(x_min)
            y_minor_list.append(y_min)
        x_minor = np.concatenate(x_minor_list)
        y_minor = np.concatenate(y_minor_list)
        # 合并两类数据并打乱
        x_combined = np.concatenate([x_major, x_minor])
        y_combined = np.concatenate([y_major, y_minor])
        shuffle_idx = np.random.permutation(len(x_combined))
        yield x_combined[shuffle_idx], y_combined[shuffle_idx]

# 使用平衡生成器训练
model.fit(
    balanced_generator(),
    steps_per_epoch=major_count // 32,
    epochs=20
)

方案3:使用tf.data.Dataset实现平衡采样

利用TensorFlow数据集API,按指定比例从不同类别采样,实现类别平衡。

代码示例

import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator

# 从目录加载数据并转为tf.data.Dataset
train_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
    'train_dir',
    target_size=(224, 224),
    batch_size=32,
    class_mode='binary',
    shuffle=False
)

dataset = tf.data.Dataset.from_generator(
    lambda: train_generator,
    output_types=(tf.float32, tf.float32),
    output_shapes=([None, 224, 224, 3], [None])
)

# 拆分出两类数据集
class_0_ds = dataset.unbatch().filter(lambda x, y: y == 0).batch(32)
class_1_ds = dataset.unbatch().filter(lambda x, y: y == 1).batch(32)

# 按1:1比例采样两类数据
balanced_ds = tf.data.experimental.sample_from_datasets(
    [class_0_ds, class_1_ds],
    weights=[0.5, 0.5]
).prefetch(tf.data.AUTOTUNE)

# 训练模型
model.fit(balanced_ds, epochs=20)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:25:56