如何在Keras中自定義機器學習性能指標

Keras提供的指標使我們能夠評估深度學習模型的性能。由於Keras提供了大量指標,因此為生產模型選擇理想指標是一項複雜的工作。在某些情況下,您可能必須自定義指標(因為Keras根本無法提供所需的指標),這會影響模型的最終性能。

在本教程中,我們不會深入探討每一個指標或何時使用它,我們將使用Keras構建幾個簡單的自定義指標,以進行二元分類。

請始終參考下面的混淆矩陣以瞭解其餘內容。

如何在Keras中自定義機器學習性能指標

混淆矩陣

首先,我們從導入必要的Python庫開始。

<code>

import

keras.backend

as

K/<code>

精度(Precision)

如何在Keras中自定義機器學習性能指標

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

如何在Keras中自定義機器學習性能指標

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

如何在Keras中自定義機器學習性能指標

<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分數

如何在Keras中自定義機器學習性能指標

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

如何在Keras中自定義機器學習性能指標

它是特異性和靈敏度的平均值,我們將其稱為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>


分享到:


相關文章: