簡體   English   中英

Keras 2.3.0 指標准確度、精度和召回率的值相同

[英]Same value for Keras 2.3.0 metrics accuracy, precision and recall

我正在嘗試獲取 keras 的准確度、精確度和召回率指標,但它們三個都顯示相同的值,這實際上是准確度。

我正在使用 TensorFlow 文檔示例中提供的指標列表:

metrics = [keras.metrics.TruePositives(name='tp'),
           keras.metrics.FalsePositives(name='fp'),
           keras.metrics.TrueNegatives(name='tn'),
           keras.metrics.FalseNegatives(name='fn'),
           keras.metrics.BinaryAccuracy(name='accuracy'),
           keras.metrics.Precision(name='precision'),
           keras.metrics.Recall(name='recall'),
           keras.metrics.AUC(name='auc')]

Model 是用於圖像分類的非常基本的 CNN:

model = Sequential()

model.add(Convolution2D(32, 
                      (7, 7), 
                      padding ="same", 
                      input_shape=(255, 255, 3), 
                      activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 
                      (3, 3), 
                      padding ="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(256, 
              activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, 
              activation='softmax'))

使用上面顯示的指標列表進行編譯:

model.compile(loss=loss,
            optimizer=optimizer,
            metrics=metrics)

這是我在訓練時一直看到的問題的一個例子:

Epoch 1/15
160/160 [==============================] - 6s 37ms/step - loss: 0.6402 - tp: 215.0000 - fp: 105.0000 - tn: 215.0000 - fn: 105.0000 - accuracy: 0.6719 - precision: 0.6719 - recall: 0.6719 - auc: 0.7315 - val_loss: 0.6891 - val_tp: 38.0000 - val_fp: 42.0000 - val_tn: 38.0000 - val_fn: 42.0000 - val_accuracy: 0.4750 - val_precision: 0.4750 - val_recall: 0.4750 - val_auc: 0.7102
Epoch 2/15
160/160 [==============================] - 5s 30ms/step - loss: 0.6929 - tp: 197.0000 - fp: 123.0000 - tn: 197.0000 - fn: 123.0000 - accuracy: 0.6156 - precision: 0.6156 - recall: 0.6156 - auc: 0.6941 - val_loss: 0.6906 - val_tp: 38.0000 - val_fp: 42.0000 - val_tn: 38.0000 - val_fn: 42.0000 - val_accuracy: 0.4750 - val_precision: 0.4750 - val_recall: 0.4750 - val_auc: 0.6759

每次折疊的指標,每次都具有相同的准確度、精度和召回值:

['loss', 'tp', 'fp', 'tn', 'fn', 'accuracy', 'precision', 'recall', 'auc']
[[ 0.351 70.    10.    70.    10.     0.875  0.875  0.875  0.945]
 [ 0.091 78.     2.    78.     2.     0.975  0.975  0.975  0.995]
 [ 0.253 72.     8.    72.     8.     0.9    0.9    0.9    0.974]
 [ 0.04  78.     2.    78.     2.     0.975  0.975  0.975  0.999]
 [ 0.021 80.     0.    80.     0.     1.     1.     1.     1.   ]]

sklearn.metrics.classification_report 顯示正確的精度和召回率

================ Fold 1 =====================
Accuracy: 0.8875
              precision    recall  f1-score   support

      normal       0.84      0.95      0.89        38
          pm       0.95      0.83      0.89        42

    accuracy                           0.89        80
   macro avg       0.89      0.89      0.89        80
weighted avg       0.89      0.89      0.89        80

================ Fold 2 =====================
Accuracy: 0.9375
              precision    recall  f1-score   support

      normal       1.00      0.87      0.93        38
          pm       0.89      1.00      0.94        42

    accuracy                           0.94        80
   macro avg       0.95      0.93      0.94        80
weighted avg       0.94      0.94      0.94        80

================ Fold 3 =====================
Accuracy: 0.925
              precision    recall  f1-score   support

      normal       0.88      0.97      0.92        37
          pm       0.97      0.88      0.93        43

    accuracy                           0.93        80
   macro avg       0.93      0.93      0.92        80
weighted avg       0.93      0.93      0.93        80

================ Fold 4 =====================
Accuracy: 0.925
              precision    recall  f1-score   support

      normal       0.97      0.86      0.91        37
          pm       0.89      0.98      0.93        43

    accuracy                           0.93        80
   macro avg       0.93      0.92      0.92        80
weighted avg       0.93      0.93      0.92        80

================ Fold 5 =====================
Accuracy: 1.0
              precision    recall  f1-score   support

      normal       1.00      1.00      1.00        37
          pm       1.00      1.00      1.00        43

    accuracy                           1.00        80
   macro avg       1.00      1.00      1.00        80
weighted avg       1.00      1.00      1.00        80

當我發布我的問題時,我沒有意識到真陽性和假陽性也與真陰性和假陰性具有相同的價值。 我的驗證集有 80 個觀察值,因此 tp、fp、tn 和 fn 的這些指標實際上意味着正確預測了 70 個觀察值而 10 個是錯誤的,無論每個觀察值的 class 是什么:

      1. 10.

我無法弄清楚為什么所有這些指標都搞砸了,也許這只是Zabir Al Nazi 提到的問題。 但是,由於一些小的變化,我能夠獲得正確的指標:

  • 損失 function:binary_crossentropy 而不是 categorical_crossentropy。
  • 頂層:1 個神經元 sigmoid,而不是 n_classes 個神經元 softmax。
  • 標簽形狀:一維 numpy 數組,而不是 one-hot 編碼。

我希望這可以幫助別人。

精度和召回率已經存在一些問題。

看這個問題: https://github.com/keras-team/keras/issues/5400

您可以嘗試tensorflow.keras代替。 這個問題應該 go 了。

或者,您可以使用自定義實現並在編譯 function 中傳遞這些實現。

from keras import backend as K

def check_units(y_true, y_pred):
    if y_pred.shape[1] != 1:
      y_pred = y_pred[:,1:2]
      y_true = y_true[:,1:2]
    return y_true, y_pred

def precision(y_true, y_pred):
    y_true, y_pred = check_units(y_true, y_pred)
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

def recall(y_true, y_pred):
    y_true, y_pred = check_units(y_true, y_pred)
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall
metrics = [keras.metrics.TruePositives(name='tp'),
           keras.metrics.FalsePositives(name='fp'),
           keras.metrics.TrueNegatives(name='tn'),
           keras.metrics.FalseNegatives(name='fn'),
           keras.metrics.BinaryAccuracy(name='accuracy'),
           precision,
           recall,
           keras.metrics.AUC(name='auc')]

TP 和 TN 相等的問題在於使用格式化為 one-hot 編碼向量的標簽進行二進制分類。 one-hot 編碼向量中的標簽表示為:[[0,1], [0,1], [1,0],[1,0],[0,1],[1,0],… .,[0,1],[1,0]],因此,每當算法預測正確時,class A 在 label 中表示為 [1,0]; 度量標准將 A 的 TP 和 class B 的 TN 都視為正確。因此,在 80 個觀察的樣本中,它最終具有 70 TP 和 70 TN。

您的更新中描述的解決方案具有更多詳細信息:

  1. Transform the output of the dense layer to have 1 output class: model.add(Dense(1, activation='sigmoid'))

  2. 將 y 的格式更改為具有 [1,1,0,0,1,0….,1,0] 的一維數組,而不是單熱向量 [[0,1], [0,1], [1, 0],[1,0],[0,1],[1,0],….,[0,1],[1,0]] 和

  3. 將損失 function 更改為BinaryCrossentropy ,例如: model.compile(loss="BinaryCrossentropy", optimizer=optimizer, metrics=metrics)

Keras 不提供從多標簽分類問題到二元分類問題的“自動轉換”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM