指標是一個用來判斷模型效能的函數。
指標函數與損失函數類似,只是評估指標的結果不會用於訓練模型。請注意,您可以將任何損失函數用作指標。
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_true
和 y_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()}')