2017-01-29 9 views
2

Diabetic Retinopathy Detectionの予測モデルを作成しようとしています。競争の訓練データセットには、高精細画像が非対称に5つのクラスに分けられています。通常画像25807枚-73.48%軽度2442画像 - 6.96%;中位-5291画像-15.07%;重度-873画像-2.48%および増殖-708画像-2.01%。 この目的のために、私はTheanoバックエンドでKerasフレームワークを使用しています(CUDAコミットメント用)。Kerasの非対称データ糖尿病性網膜症の検出

イメージを拡大するためにImageDataGeneratorを使用しました(コードは以下です)。 I 299x299にリサイズした画像をしましたし、5つのフォルダに応じて自分のクラスにそれらを分け:フィッティング画像で

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']) 

:最初は

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私はclass_weight = {0:25807.、1:2442。、2:5291、3:873、4:708}のデータの非対称性を修正するためにclass_weightsを指摘しました。

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に再スケール) ARGMAX無し

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

    (部分的に)

    0:

    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] 
    

    それの出力であります

    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 105 - 損失: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つのエポック後の出力は次のようになります。

    エポック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 [===================== =========] - 52秒 - 喪失:6.0311 - 分類精度:0.0180
    エポック5/5 500/500 [===============] - 51秒 - 損失:4.9924 - categorical_accuracy:0.0560

    それが正しいか?

    ケラスのメトリックとして二次重み付きκを割り当てる方法はありますか?

    答えて

    1

    73から74パーセントの周りに「高」の精度は、すべての画像が0クラスとして分類されているという事実から来ています。多数のクラスがサンプルの73%を占めるため、データセットの不均衡が生じます。この場合、精度はあまり言いません。精度、リコール、F1スコアなどの混同行列から得られた他のメトリックを使用する必要があります。

    マルチクラスログ損失関数は間違った予測を極端に罰します。あなたの予測は0を除くすべてのクラスでほぼゼロであるため、このような高損失値には驚くべきことはありません。

    合計すると、クラシッククラスの不均衡問題に直面しています。これを緩和する最も一般的な2つの方法は、

    1. です。クラスの重みを調整します。マイノリティクラスを「より重要」にすることで、学習アルゴリズムはそれらを無視しません。

    class_weight:(のみ訓練中)損失関数をスケーリングするために使用される加重値に辞書マッピングクラス、あなたはfitメソッドの引数としてカスタムクラスの重みを提供することができます。

    1. オーバーサンプリング/アンダーサンプリング。少数派クラスの例を単純にオーバーサンプルしてデータセットのバランスを取ったり、アンダーサンプリングと組み合わせたりします。多数のクラスの無作為に選択された例が各学習エポックの初めに削除されます。

    クラス不均衡問題は新しいものではありませんので、thisthis入門記事のように、このトピックで読んでたくさんのがあります。

    +0

    Sergii、あなたの答えに感謝します!モデルを変更しましたが、それでも何か問題があります。私は下の答えに出力を書いています------------- –

    +0

    わずか5エポック後に結論を導くことは難しいです。損失の価値は今よりずっと妥当に見えます。もっと訓練させてください。ちなみに、 'categorical_accuracy'はこの場合の' accuracy'と同じです。この[Kerasがどのように精度を定義するかについての質問]を参照してください(http://stackoverflow.com/questions/41531695/how-does-keras-define-accuracy-and-loss/41534323)@MaxTitkov –

    関連する問題