Keras提供的指標使我們能夠評估深度學習模型的性能。由於Keras提供了大量指標,因此為生產模型選擇理想指標是一項複雜的工作。在某些情況下,您可能必須自定義指標(因為Keras根本無法提供所需的指標),這會影響模型的最終性能。
在本教程中,我們不會深入探討每一個指標或何時使用它,我們將使用Keras構建幾個簡單的自定義指標,以進行二元分類。
請始終參考下面的混淆矩陣以瞭解其餘內容。
混淆矩陣
首先,我們從導入必要的Python庫開始。
<code>
import
keras.backendas
K/<code>精度(Precision)
<code>
def
precision(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)))
return
true_positives / (predicted_positives + K.epsilon())
/<code>我們需要記住,y_true和y_pred的操作不是NumPy數組,而是Theano或Tensorflow張量。這就是為什麼我們將Keras後端提供的操作用於指標的原因。
召回率(Recall)或靈敏度(Sensitivity)
<code>
def
recall(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)))
return
true_positives / (possible_positives + K.epsilon())
/<code>特異性(Specificity)
<code>
def
specificity(y_true, y_pred):
true_negatives
=K.sum(K.round(K.clip((1 - y_true) * (1 - y_pred), 0, 1)))
possible_negatives
=K.sum(K.round(K.clip(1 - y_true, 0, 1)))
return
true_negatives / (possible_negatives + K.epsilon())
/<code>F beta分數
<code>
def
f_beta_m(y_true, y_pred):
beta
=1
precision
=precision_m(y_true, y_pred)
recall
=recall_m(y_true, y_pred)
numer
=(1 + beta ** 2) * (precision * recall)
denom
=((beta ** 2) * precision) + recall + K.epsilon()
return
numer / denom
/<code>在F-beta分數中選擇beta時,您越想關注召回率而不是精度,應該選擇更高的beta。例如,對於F1分數,我們同樣關心recall和precision,對於F2分數,recall對我們來說是兩倍重要。
在0 1時,我們的最佳閾值朝著更低的閾值移動,當beta = 1時,它處於中間位置。
特異性(Specificity)/靈敏度(Sensitivity)
它是特異性和靈敏度的平均值,我們將其稱為average_metric。請注意,靈敏度與前面定義的recall是同一個函數。
<code>
def
average_metric(y_true, y_pred):
spec
=specificity(y_true, y_pred)
sens
=sensitivity(y_true, y_pred)
return
0.5 * (spec + sens)
/<code>另外,為了確保我的模型不會在某個類上過度擬合,我傾向於在average_metric中添加一個條件操作,我們將調用新指標
conditional_average_metric。這背後的直覺是監測靈敏度和特異性的值,如果它們中的任何一個下降到某個水平以下,那麼我們將大幅降低所述度量的最終值。
之所以這樣做,是因為在訓練模型時,Keras並沒有在每個epoch之後保存每個模型,而是為我們提供了監視度量的選項,並根據監視的數量保存最新的最佳模型。
<code>
def
conditional_average_metric(y_true, y_pred):
spec
=specificity(y_true, y_pred)
sens
sensitivity(y_true, y_pred)
minimum
=K.minimum(spec, sens)
condition
=K.less(minimum, 0.5)
multiplier
=0.001
result_greater
=0.5 * (spec + sens)
result_lower
=multiplier * (spec + sens)
result
=K.switch(condition, result_lower, result_greater)
return
result
/<code>使用首選指標定義機器學習模型
首先,建立模型並選擇您想要監視的首選指標。我們將在這個例子中繼續有三個指標,即
conditional_average_metric,specificity,sensitivity。
<code>model = Sequential() ..... model.
add
(Dense(1
)) model.add
(Activation('sigmoid'
)) model.compile(optimizer, loss='binary_crossentropy'
, metrics=[conditional_average_metric, specificity, sensitivity])/<code>訓練機器學習模型並保存最佳模型
儘管我們在訓練過程中使用了三個指標,但我們應該僅選擇其中一個指標,即
conditional_average_metric,來保存基於它的模型。訓練模型時,基於監視指標的最佳性能模型將自動保存到指定路徑。
<code>
monitor
='val_conditional_average_metric'
checkpoint
= ModelCheckpoint(model_path, monitor=monitor, verbose=1
, save_best_only=True
, mode='max'
)callbacks_list
= [checkpoint]history
= model.fit(trainX, trainY, epochs=epochs, batch_size=batch_size, validation_data=(testX, testY),callbacks=callbacks_list)/<code>加載預訓練機器學習模型
完成訓練過程後,我們可以按如下所示再次加載機器學習模型。
<code>
model
= load_model(model_path, custom_objects={'conditional_average_metric'
: conditional_average_metric,'specificity'
: specificity,'sensitivity'
: sensitivity})/<code>