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

如何处理数据增强?CNN新冠胸片二分类遇过拟合与曲线异常

针对新冠胸片二分类任务的数据集增强方案建议

首先明确:将数据增强放在数据集层面还是模型层各有优劣,但结合你数据集严重不平衡的场景,更推荐在数据集层面实现增强,且针对性处理少数类,原因如下:

两种增强方式的核心差异

  • 模型层增强:
    你当前的做法是把增强层嵌入模型,训练时每个batch实时生成增强样本,测试阶段Keras随机增强层默认会自动关闭。优点是无需额外存储增强数据,节省磁盘空间;但缺点是增强逻辑和模型绑定,无法针对不同类别做差异化增强——这对你的不平衡数据集是个大问题,因为多数类(10000张)不需要过度增强,反而少数类(3000张)需要更多数据多样性。
    你提到训练曲线出现异常边缘,大概率是验证阶段误启用了增强(比如未明确设置training=False),导致验证集数据被随机修改,曲线波动异常。

  • 数据集层面增强:
    通过tf.data.Dataset的map函数或自定义数据生成器实现增强,逻辑和模型完全分离。这种方式的核心优势是:

    1. 可以仅对少数类做过采样+增强:比如从3000张新冠样本中每次采样时重复调用增强逻辑,生成更多有效样本,直接缓解类别不平衡;
    2. 增强逻辑更灵活:可以针对胸片的特点调整增强策略(比如限制旋转角度,因为胸片旋转过度会失去医学特征;或者添加高斯噪声、对比度调整等更适合医学图像的增强);
    3. 验证/测试集完全不受增强影响,曲线更稳定。

针对你场景的具体实现建议

1. 数据集层面增强的代码示例(针对少数类)

假设你用tf.data加载数据,先区分两类样本,对少数类单独应用增强:

# 假设已加载train_ds,包含label=0(多数类)和label=1(少数类)
def augment_image(image, label):
    # 只对少数类(label=1)做增强
    if label == 1:
        image = tf.image.random_flip_left_right(image)
        image = tf.image.random_flip_up_down(image)
        image = tf.image.rot90(image, k=tf.random.uniform(shape=[], minval=0, maxval=4, dtype=tf.int32))
        # 可添加更多胸片适配的增强:对比度调整、轻微高斯噪声等
    # 统一做灰度图缩放
    image = tf.cast(image, tf.float32) / 255.0
    return image, label

# 应用增强逻辑
train_ds = train_ds.map(augment_image, num_parallel_calls=tf.data.AUTOTUNE)

# 过采样少数类,平衡两类样本占比
minority_ds = train_ds.filter(lambda x, y: y == 1).repeat(3)  # 重复3次,接近多数类数量
majority_ds = train_ds.filter(lambda x, y: y == 0)
train_ds = tf.data.Dataset.sample_from_datasets(
    [majority_ds, minority_ds],
    weights=[0.5, 0.5]  # 两类采样权重各50%
).batch(32).prefetch(tf.data.AUTOTUNE)

2. 额外优化建议

  • 替换评价指标:别只用accuracy,不平衡数据集下accuracy会偏向多数类。改用AUC、Precision、Recall或F1-score作为核心指标:
    from tensorflow.keras.metrics import AUC, Precision, Recall
    model_1.compile(optimizer="adam",
                    loss=tf.keras.losses.BinaryCrossentropy(),
                    metrics=[AUC(name='auc'), Precision(name='precision'), Recall(name='recall')])
    
  • 优化模型结构:你当前的模型只有1个Conv层,容量不足且容易过拟合。建议增加Conv层深度,加入Dropout或BatchNormalization:
    model_1 = Sequential([
        resize_and_rescale,
        # 仅训练时启用增强,验证时自动关闭
        layers.Lambda(lambda x: data_augmentation(x, training=True)),
        layers.Conv2D(32, 3, padding="same", activation="relu"),
        layers.MaxPooling2D(),
        layers.Conv2D(64, 3, padding="same", activation="relu"),
        layers.MaxPooling2D(),
        layers.Dropout(0.2),  # 添加Dropout抑制过拟合
        layers.Flatten(),
        layers.Dense(64, activation="relu"),
        layers.Dense(1, activation="sigmoid")
    ])
    
  • 加权损失函数:给少数类设置更高的损失权重,让模型更关注少数类样本:
    # 计算权重:多数类样本数/少数类样本数 ≈ 10000/3000 ≈ 3.33
    class_weight = {0: 1.0, 1: 3.33}
    model_1.fit(train_ds, epochs=60, class_weight=class_weight)
    

总结

如果你的核心诉求是缓解数据不平衡+稳定训练曲线,优先选择数据集层面的增强,并针对少数类做差异化处理。模型层增强适合数据量充足且类别平衡的场景,但若要用,务必确保验证/测试阶段关闭增强逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:25:04