使用SMOTE算法对图像数据进行过采样

10

我正在使用卷积神经网络进行二元分类,数据不平衡,其中阳性医学图像 : 阴性医学图像 = 0.4 : 0.6。因此,在训练之前,我想使用SMOTE来对阳性医学图像数据进行过采样。 然而,数据的维度是4D(761,64,64,3),这导致了错误。

Found array with dim 4. Estimator expected <= 2

所以,我重新整理了我的train_data:

X_res, y_res = smote.fit_sample(X_train.reshape(X_train.shape[0], -1), y_train.ravel())

它的功能很好。在将其馈送给卷积神经网络之前,我通过以下方式将其重新整形:

X_res = X_res.reshape(X_res.shape[0], 64, 64, 3)

现在,我不确定过采样是否正确,并且重塑操作会改变图像的结构吗?


你好,你是否进行了测试以检查你的shape/reshape操作是否正常工作? - akhetos
3个回答

7
我曾遇到过类似的问题。我使用了reshape函数来重塑图像(基本上是将图像压平)。
X_train.shape
(8000, 250, 250, 3)

ReX_train = X_train.reshape(8000, 250 * 250 * 3)
ReX_train.shape
(8000, 187500)

smt = SMOTE()
Xs_train, ys_train = smt.fit_sample(ReX_train, y_train)

虽然这种方法非常慢,但有助于提高性能。

此外,作为上一个问题的扩展。如果您正在使用预训练网络和特征提取方法,则无需将平铺图像重新整形回来。但如果没有,则必须将图像再次调整为原始尺寸。 此外,有一篇关于SMOTE的文章可以帮助: https://medium.com/@adib0073/how-to-use-smote-for-dealing-with-imbalanced-image-dataset-for-solving-classification-problems-3aba7d2b9cad - Aditya Bhattacharya

3
  1. 一旦你将图像压缩成平面化格式,就会失去局部信息,这是图像机器学习中使用卷积的原因之一。
  2. 8000x250x250x3有固定的含义 - 8000个图像样本,每个图像宽度为250,高度为250,并且所有图像都有3个通道。当你做8000x250*250*3重塑时,这只是一堆数字,除非你使用某种序列网络来训练它。
  3. 过度采样对图像数据不利,你可以进行图像增强(20倍裁剪、引入高斯模糊噪声、旋转、平移等等)。

你有任何引用来证明你的第三个想法吗?关于“过采样对图像数据不利”的观点? - CuCaRot
1
当我说“过采样不好”时,我的意思是如果我们只是尝试复制低类图像的数量,我们并没有试图泛化,它会多次看到相同的图像,这在某些情况下会导致过度拟合。对于这个不确定的陈述再次道歉。 - cerofrais
只是想讨论一下。除了增广方法,你知道如何处理不平衡问题吗?我面对的数据集主要-次要比例为98-2,这意味着该数据集中仅有2%的类别。 - CuCaRot
1
假设是图像数据,我建议使用k折交叉验证(https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html)+图像增强(https://github.com/albumentations-team/albumentations)。除非你在进行异常检测,否则98-2的划分真的很糟糕。 - cerofrais
我认为对于处理不平衡图像数据集来解决分类问题,采用过采样然后只增强少数类是一个好主意(https://medium.com/swlh/how-to-use-smote-for-dealing-with-imbalanced-image-dataset-for-solving-classification-problems-3aba7d2b9cad)。 - CuCaRot

2
  • 首先将图像压平
  • 对这个压平的图像数据及其标签应用SMOTE
  • 将压平的图像重新调整为RGB图像
from imblearn.over_sampling import SMOTE
    
sm = SMOTE(random_state=42)
    
train_rows=len(X_train)
X_train = X_train.reshape(train_rows,-1)
(80,30000)

X_train, y_train = sm.fit_resample(X_train, y_train)
X_train = X_train.reshape(-1,100,100,3)
(>80,100,100,3)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接