2017-01-29 23 views
2

我正在嘗試爲Diabetic Retinopathy Detection做一個預測模型。本次比賽的訓練數據集包括5幅不對稱水下圖像:Normal-25807圖像-73.48%; Mild-2442圖片 - 6.96%;中等-5291圖像-15.07%; Severe-873圖像-2.48%和增殖-708圖像-2.01%。 爲此,我使用Keano框架與Theano後端(用於CUDA comutations)。Keras非對稱數據糖尿病視網膜病變檢測

對於圖像增強,我使用了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') 

起初,只是爲了測試,我desided使用一個簡單的卷積模型:

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

  • 每個圖像模型預測爲 '0' 類:
  • datagen_2 = ImageDataGenerator(重新縮放= 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

    Epoch 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) 
    

    我做錯了什麼?


    塞爾吉Gryshkevych的回答後,我定我的模型:我已經改變了class_weight爲{0:1,1:10.57,2:4.88,3:29,4:35}(我分圖像每個班級最大的圖像(在第一類))。接下來,我將指標更改爲categorical_accuracy。並且我模擬了模型中的層數(如here)。 所以,5個紀元後的輸出是:

    Epoch 1/5 500/500 [=========================== ===] - 52S - 損失:5.6944 - categorical_accuracy:0.1840
    大紀元2/5 500/500 [========================= =====] - 52S - 損失:6.7357 - categorical_accuracy:0.2040
    大紀元3/5 500/500 [======================= ======= - 52S - 損失:6.7373 - categorical_accuracy:0.0800
    大紀元4/5 500/500 [===================== =========] - 52s - 損失:6.0311 - categorical_accuracy:0.0180
    Epoch 5/5 500/500 [==============================] - 51s - loss:4.9924 - categorical_accuracy:0.0560

    這是對的嗎?

    有什麼辦法可以將二次加權Kappa指定爲keras中的度量?

    回答

    1

    「高」圍繞73-74%的準確度來自於一個事實,即所有圖像被劃分爲0類。您的數據集是不平衡的,因爲大多數類別佔樣本的73%。所以準確性不說,在這種情況下多,你需要使用像從精度,召回,F1分數等混淆矩陣派生的其他指標

    多類日誌損失函數極其懲罰錯誤的預測。除了0之外,你的預測幾乎爲零,所以在這樣高的損失值中沒有什麼奇怪的。

    總結一下,你正面臨經典的類不平衡問題。減輕它的兩種最常用的方法是

    1. 調整類別權重。讓少數類更「重要」,所以學習算法不會忽略它們。您可以提供自定義類的權重作爲參數傳遞給fit方法:

    class_weight:字典映射類的權重值,用於(訓練期間)縮放損失函數。

    1. 過採樣/欠採樣。簡單地過度抽樣少數類別的例子,以使數據集合保持平衡,或者將其與欠採樣相結合,即在每個學習時期開始時,隨機選擇大多數類別的例子。

    的類不平衡問題是什麼新鮮事,所以有大量的閱讀關於這個主題一樣thisthis介紹職位。

    +0

    Sergii,謝謝你的回答!我改變了我的模型,但它仍然做錯了什麼。我在下面的答案中寫下輸出結果------------- –

    +0

    僅5個紀元後很難得出任何結論。現在損失值看起來更合理。讓它訓練更多。順便說一句,在這種情況下,'categorical_accuracy'和''accuracy'是一樣的。看到這個[關於Keras如何定義準確性的問題](http://stackoverflow.com/questions/41531695/how-does-keras-define-accuracy-and-loss/41534323)@MaxTitkov –