不平衡图像数据集 (Tensorflow2)

Posted

技术标签:

【中文标题】不平衡图像数据集 (Tensorflow2)【英文标题】:Imbalanced Image Dataset (Tensorflow2) 【发布时间】:2021-05-07 01:18:32 【问题描述】:

我正在尝试解决二值图像分类问题,但是这两个类(分别为 1 类和 2 类的 ~590 和 ~5900 个实例)严重倾斜,但仍然非常不同。

有什么办法可以解决这个问题,我想尝试 SMOTE/随机加权过采样。

我尝试了很多不同的东西,但我被卡住了。我试过使用class_weights=[10,1][5900,590][1/5900,1/590],但我的模型仍然只能预测第 2 类。 我试过使用tf.data.experimental.sample_from_datasets,但我无法让它工作。我什至尝试过使用 sigmoid 焦点交叉熵损失,这有很大帮助,但还不够。

我希望能够将 1 类过采样 10 倍,我尝试过的唯一有效的方法是手动过采样,即复制火车目录的 1 类实例以匹配 2 类中的实例数。

有没有更简单的方法可以做到这一点,我正在使用 Google Colab,所以这样做效率极低。

有没有办法在数据生成器或类似工具中指定 SMOTE 参数/过采样?

data/
...class_1/
........image_1.jpg
........image_2.jpg
...class_2/
........image_1.jpg
........image_2.jpg

我的数据如上所示。

TRAIN_DATAGEN = ImageDataGenerator(rescale = 1./255.,
                                   rotation_range = 40,
                                   width_shift_range = 0.2,
                                   height_shift_range = 0.2,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

TEST_DATAGEN = ImageDataGenerator(rescale = 1.0/255.)

TRAIN_GENERATOR = TRAIN_DATAGEN.flow_from_directory(directory = TRAIN_DIR,
                                                    batch_size = BACTH_SIZE,
                                                    class_mode = 'binary', 
                                                    target_size = (IMG_HEIGHT, IMG_WIDTH),
                                                    subset = 'training',
                                                    seed = DATA_GENERATOR_SEED)

VALIDATION_GENERATOR = TEST_DATAGEN.flow_from_directory(directory = VALIDATION_DIR,
                                                        batch_size = BACTH_SIZE,
                                                        class_mode = 'binary', 
                                                        target_size = (IMG_HEIGHT, IMG_WIDTH),
                                                        subset = 'validation',
                                                        seed = DATA_GENERATOR_SEED)
...
...
...

HISTORY = MODEL.fit(TRAIN_GENERATOR,
                    validation_data = VALIDATION_GENERATOR,
                    epochs = EPOCHS,
                    verbose = 2,
                    callbacks = [EARLY_STOPPING],
                    class_weight = CLASS_WEIGHT)

我对 Tensorflow 比较陌生,但我对整个机器学习有一些经验。我曾多次想切换到 PyTorch,因为它们有数据加载器的参数,可以自动(过度/不足)采样 sampler=WeightedRandomSampler

注意:我看过很多关于如何过采样的教程,但是它们都不是图像分类问题,我想坚持使用 TF/Keras,因为它可以轻松进行迁移学习,你们能帮忙吗?

【问题讨论】:

见***.com/questions/41648129/… 【参考方案1】:

您可以使用此策略根据不平衡计算权重:

from sklearn.utils import class_weight 
import numpy as np

class_weights = class_weight.compute_class_weight(
           'balanced',
            np.unique(train_generator.classes), 
            train_generator.classes)

train_class_weights = dict(enumerate(class_weights))
model.fit_generator(..., class_weight=train_class_weights)

【讨论】:

【参考方案2】:

由于您已经将class_weight 定义为字典,例如0: 10, 1: 1,您可以尝试增加少数类。请参阅balancing an imbalanced dataset with keras image generator 和https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html 上的教程(在那里提到)

【讨论】:

我在我的问题中输入错误,我确实将它们作为字典传递【参考方案3】:

在 Python 中,您可以使用 imblearn 库实现 SMOTE,如下所示:

from imblearn.over_sampling import SMOTE

oversample = SMOTE()
X, y = oversample.fit_resample(X, y)

【讨论】:

在这种情况下,我对如何获取 X 和 y 感到非常困惑,我可以从 DataGen 中提取它还是需要为 X 解析两个文件夹? @SakibAhamed 你能把整个数据加载到内存中吗?如果是,X和y就是整个数据的特征和标签 要加载到 RAM 中的数据太多了,这才是真正的问题 - 这就是为什么我如此热衷于使用生成器 @SakibAhamed 在这种情况下,您可以使用生成器分批加载数据,然后将每批数据过采样到 SMOTE,然后再将它们提供给模型。

以上是关于不平衡图像数据集 (Tensorflow2)的主要内容,如果未能解决你的问题,请参考以下文章

MobileNet实战:tensorflow2.X版本,MobileNetV3图像分类任务(大数据集)

MobileNet实战:tensorflow2.X版本,MobileNetV2图像分类任务(大数据集)

InceptionV3实战:tensorflow2.X版本,InceptionV3图像分类任务(大数据集)

DenseNet实战:tensorflow2.X版本,DenseNet121图像分类任务(小数据集)

MobileNet实战:tensorflow2.X版本,MobileNetV2图像分类任务(小数据集)

MobileNet实战:tensorflow2.X版本,MobileNetV1图像分类任务(大数据集)