【问题标题】:Keras unsymmetrical data Diabetic Retinopathy DetectionKeras 不对称数据糖尿病视网膜病变检测
【发布时间】:2017-06-14 15:59:19
【问题描述】:

我正在尝试为Diabetic Retinopathy Detection 创建一个预测模型。比赛的训练数据集包括 hy-res 图像不对称地分为 5 类:Normal-25807 images-73.48%;轻度 2442 图像-6.96%;中等 5291 张图片 - 15.07%; Severe-873 图像 - 2.48% 和 Proliferative-708 图像 - 2.01%。 为此,我使用带有 Theano 后端的 Keras 框架(用于 CUDA 计算)。

对于图像增强,我使用了 ImageDataGenerator(代码如下)。我已将图像大小调整为 299x299,并根据它们的类别将它们分成 5 个文件夹:

train_datagen=ImageDataGenerator(rescale=1./255, rotation_range=40, zoom_range=0.2, horizontal_flip=True, fill_mode="constant", zca_whitening=True)
train_generator=train_datagen.flow_from_directory('data/~huge_data/preprocessed_imgs/', target_size=(299, 299), batch_size=32, class_mode='categorical')

起初,只是为了测试,我决定使用一个简单的卷积模型:

model=Sequential()
model.add(Convolution2D(32,3,3, input_shape=(3, 299, 299), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(5, activation='softmax'))

model.compile(loss='categorical_crossentropy', 
              optimizer='rmsprop', 
              metrics=['accuracy'])

在拟合图像生成器时,我指出了 class_weights 以修复数据的不对称性:class_weight ={0: 25807., 1:2442., 2:5291., 3:873., 4:708.};

model.fit_generator(train_generator,
                   samples_per_epoch=2000,
                   nb_epoch=50, 
                    verbose=2, 
                   callbacks=callbacks_list,
                   class_weight ={0: 25807., 1:2442., 2:5291., 3:873., 4:708.})

My folders with images

问题:

  1. 模型输出具有高损耗和高精度。为什么?

纪元 1/50 110s - 损失:5147.2669 - acc:0.7366

纪元 2/50 105s - 损失:5052.3844 - acc:0.7302

时代 3/50 105s - 损失:5042.0261 - acc:0.7421

纪元 4/50 105s - 损失:4986.3544 - acc:0.7361

5/50 纪元 105s - 损失:4999.4177 - acc:0.7361

  1. 每个图像模型都预测为“0”类:

datagen_2=ImageDataGenerator(rescale=1./255)

val_generator=datagen_2.flow_from_directory('data/color_validation_images/',
                                         target_size=(299,299),
                                         batch_size=100,
                                           class_mode='categorical')

y_predict=model.predict_generator(val_generator,
                       val_samples=82)


[np.argmax(i) for i in y_predict]

它的输出是:

0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0,
 0

没有 argmax(部分)

array([  9.47651565e-01,   7.30426749e-03,   4.40788604e-02,
          6.25302084e-04,   3.39932943e-04], dtype=float32),
 array([  9.51994598e-01,   6.50278665e-03,   4.07058187e-02,
          5.17037639e-04,   2.79774162e-04], dtype=float32),
 array([  9.49448049e-01,   6.50656316e-03,   4.32702228e-02,
          5.20388770e-04,   2.54814397e-04], dtype=float32),
 array([  9.47873473e-01,   7.13181263e-03,   4.40776311e-02,
          6.00705389e-04,   3.16353660e-04], dtype=float32),
 array([  9.53514516e-01,   6.13699574e-03,   3.96034382e-02,
          4.82603034e-04,   2.62484333e-04], dtype=float32),
....

如果我尝试使用 class_weight ='auto'。在这种情况下,模型显示“可预测”的输出:

纪元 1/50 107s - 损失:0.9036 - acc:0.7381

纪元 2/50 104s - 损失:0.9333 - acc:0.7321

时代 3/50 105s - 损失:0.8865 - acc:0.7351

纪元 4/50 106s - 损失:0.8978 - acc:0.7351

5/50 纪元 105s - 损失:0.9158 - acc:0.7302

但是,还是不行:

severe_DR=plt.imread('data/~huge_data/preprocessed_imgs/3_Severe/99_left.jpeg')
mild_DR=plt.imread('data/~huge_data/preprocessed_imgs/1_Mild/15_left.jpeg')
moderate_DR=plt.imread('data/~huge_data/preprocessed_imgs/2_Moderate/78_right.jpeg')

model.predict(mild_DR.reshape((1,)+x[1].shape))
array([[ 1.,  0.,  0.,  0.,  0.]], dtype=float32)

model.predict(severe_DR.reshape((1,)+x[1].shape))
array([[ 1.,  0.,  0.,  0.,  0.]], dtype=float32)

model.predict(moderate_DR.reshape((1,)+x[1].shape))
array([[ 1.,  0.,  0.,  0.,  0.]], dtype=float32)

我做错了什么?


在回答 Sergii Gryshkevych 之后,我修复了我的模型:我已将 class_weight 更改为 {0:1, 1:10.57, 2:4.88, 3:29, 4:35}(我将每个类中的图像划分为最大图片(头等舱))。接下来,我将指标更改为 categorical_accuracy。我增加了模型中的层数(如here)。 所以,5 epochs 后的输出是:

纪元 1/5 500/500 [===============================] - 52s - 损失:5.6944 - 分类准确度:0.1840
纪元 2/5 500/500 [===============================] - 52s - 损失:6.7357 - 分类准确度:0.2040
时代 3/5 500/500 [===============================] - 52s - 损失:6.7373 - 分类准确度:0.0800
时代 4/5 500/500 [==============================] - 52s - 损失:6.0311 - 分类准确度:0.0180
纪元 5/5 500/500 [===============================] - 51s - 损失:4.9924 - 分类准确度:0.0560

对吗?

有没有办法在 keras 中指定一个二次加权 kappa 作为指标?

【问题讨论】:

    标签: python machine-learning keras theano-cuda


    【解决方案1】:

    大约 73-74% 的“高”准确度来自于所有图像都归类为0 类的事实。您的数据集不平衡,因为多数类占样本的 73%。所以在这种情况下准确率并不能说明什么,您需要使用从混淆矩阵中导出的其他指标,例如准确率、召回率、F1 分数等。

    多类对数损失函数极大地惩罚了错误的预测。除了0,您对所有类别的预测几乎为零,因此损失值如此之高也就不足为奇了。

    总而言之,您面临着经典的类不平衡问题。两种最常见的缓解方法是

    1. 调整班级权重。使少数类“更重要”,因此学习算法不会忽略它们。您可以将自定义类权重作为参数提供给 fit 方法:

    class_weight:将类映射到权重值的字典,用于缩放损失函数(仅在训练期间)。

    1. 过采样/欠采样。只需对少数类的示例进行过采样以使您的数据集保持平衡,或者在每个学习时期开始时丢弃一些随机选择的多数类示例时,将其与欠采样相结合。

    类不平衡问题并不是什么新鲜事,所以有很多关于这个主题的阅读,比如thisthis 介绍性帖子。

    【讨论】:

    • Sergii,谢谢您的回答!我已经改变了我的模型,但它仍然有问题。我已经在我的答案中写了输出 -------------
    • 仅在 5 个 epoch 之后很难得出任何结论。损失值现在看起来更加合理。让它训练更多。顺便说一句,在这种情况下,categorical_accuracyaccuracy 相同。看到这个question about how does Keras define accuracy@MaxTitkov
    猜你喜欢
    • 1970-01-01
    • 2013-11-03
    • 2019-01-27
    • 2015-07-26
    • 2019-11-11
    • 2019-02-15
    • 2020-12-06
    • 2016-06-24
    • 2010-10-13
    相关资源
    最近更新 更多