Keras 3 API 文件 / 指標

指標

指標是一個用來判斷模型效能的函數。

指標函數與損失函數類似,只是評估指標的結果不會用於訓練模型。請注意,您可以將任何損失函數用作指標。

可用指標

基礎指標類別

準確度指標

機率指標

迴歸指標

基於真/假陽性與陰性的分類指標

影像分割指標

「最大邊界」分類的 Hinge 指標

指標包裝器和縮減指標


compile() & fit() 的使用方式

compile() 方法接受一個 metrics 引數,該引數是一個指標列表

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=[
        metrics.MeanSquaredError(),
        metrics.AUC(),
    ]
)

指標值會在 fit() 期間顯示,並記錄到 fit() 返回的 History 物件中。它們也會由 model.evaluate() 返回。

請注意,在訓練期間監控指標的最佳方法是透過 TensorBoard

若要追蹤特定名稱下的指標,您可以將 name 引數傳遞給指標建構函式

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=[
        metrics.MeanSquaredError(name='my_mse'),
        metrics.AUC(name='my_auc'),
    ]
)

所有內建指標也可以透過它們的字串識別符號傳遞 (在這種情況下,會使用預設的建構函式引數值,包括預設的指標名稱)

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=[
        'MeanSquaredError',
        'AUC',
    ]
)

獨立使用

與損失不同,指標是有狀態的。您可以使用 update_state() 方法更新它們的狀態,並使用 result() 方法查詢純量指標結果

m = keras.metrics.AUC()
m.update_state([0, 1, 1, 1], [0, 1, 0, 0])
print('Intermediate result:', float(m.result()))

m.update_state([1, 1, 1, 1], [0, 1, 1, 0])
print('Final result:', float(m.result()))

可以使用 metric.reset_states() 清除內部狀態。

以下是如何將指標用作簡單的自訂訓練迴圈的一部分

accuracy = keras.metrics.CategoricalAccuracy()
loss_fn = keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = keras.optimizers.Adam()

# Iterate over the batches of a dataset.
for step, (x, y) in enumerate(dataset):
    with tf.GradientTape() as tape:
        logits = model(x)
        # Compute the loss value for this batch.
        loss_value = loss_fn(y, logits)

    # Update the state of the `accuracy` metric.
    accuracy.update_state(y, logits)

    # Update the weights of the model to minimize the loss value.
    gradients = tape.gradient(loss_value, model.trainable_weights)
    optimizer.apply_gradients(zip(gradients, model.trainable_weights))

    # Logging the current accuracy value so far.
    if step % 100 == 0:
        print('Step:', step)        
        print('Total running accuracy so far: %.3f' % accuracy.result())

建立自訂指標

作為簡單的可呼叫物件 (無狀態)

與損失函數非常相似,任何具有簽名 metric_fn(y_true, y_pred) 且返回損失陣列 (輸入批次中的一個樣本) 的可呼叫物件,都可以作為指標傳遞給 compile()。請注意,任何此類指標都自動支援樣本加權。

以下是一個簡單的範例

from keras import ops

def my_metric_fn(y_true, y_pred):
    squared_difference = ops.square(y_true - y_pred)
    return ops.mean(squared_difference, axis=-1)  # Note the `axis=-1`

model.compile(optimizer='adam', loss='mean_squared_error', metrics=[my_metric_fn])

在這種情況下,您在訓練和評估期間追蹤的純量指標值是指定時期內 (或在給定呼叫 model.evaluate() 期間) 所有批次的每個批次指標值的平均值。

作為 Metric 的子類別 (有狀態)

並非所有指標都可以透過無狀態的可呼叫物件來表達,因為指標是在訓練和評估期間針對每個批次進行評估的,但在某些情況下,您感興趣的不是每個批次值的平均值。

假設您想要計算給定評估資料集的 AUC:每個批次 AUC 值的平均值與整個資料集的 AUC 不同。

對於此類指標,您會想要子類別化 Metric 類別,它可以跨批次維護狀態。這很容易

  • __init__ 中建立狀態變數
  • update_state() 中根據 y_truey_pred 更新變數
  • result() 中返回純量指標結果
  • reset_states() 中清除狀態

以下是一個計算二元真陽性的簡單範例

class BinaryTruePositives(keras.metrics.Metric):

  def __init__(self, name='binary_true_positives', **kwargs):
    super().__init__(name=name, **kwargs)
    self.true_positives = self.add_weight(name='tp', initializer='zeros')

  def update_state(self, y_true, y_pred, sample_weight=None):
    y_true = ops.cast(y_true, "bool")
    y_pred = ops.cast(y_pred, "bool")

    values = ops.logical_and(ops.equal(y_true, True), ops.equal(y_pred, True))
    values = ops.cast(values, self.dtype)
    if sample_weight is not None:
      sample_weight = ops.cast(sample_weight, self.dtype)
      values = values * sample_weight
    self.true_positives.assign_add(ops.sum(values))

  def result(self):
    return self.true_positives

  def reset_state(self):
    self.true_positives.assign(0)

m = BinaryTruePositives()
m.update_state([0, 1, 1, 1], [0, 1, 0, 0])
print(f'Intermediate result: {m.result().numpy()}')

m.update_state([1, 1, 1, 1], [0, 1, 1, 0])
print(f'Intermediate result: {m.result().numpy()}')