Как использовать собственные метрики проверки в TensorFlow 2
Keras предлагает набор показателей для проверки набора тестовых данных, таких как точность, MSE или AUC. Однако иногда для проверки вашей модели требуется настраиваемая метрика. В этом посте я покажу три разных подхода к реализации ваших метрик и их использованию в Keras.
Если вначале в Keras было всего несколько показателей, сегодня доступно множество других. Для версии Keras в комплекте с TensorFlow 2 все показатели можно найти в tf.keras.metrics.
Использование дополнений tensorflow
Библиотека Tensoflow Addons предоставляет некоторые дополнительные метрики. Перед тем, как приступить к реализации самостоятельно, лучше проверьте, доступна ли там ваша метрика. Чтобы использовать аддоны тензорного потока, просто установите его через pip:
pip install tensorflow-addons
Если вы не нашли там свои показатели, теперь мы можем рассмотреть три варианта. Объекты функций, обратных вызовов и показателей.
Простые функции метрик
Самый простой способ определения показателей в Keras - просто использовать обратный вызов функции. Функция принимает два аргумента. Первый параметр - это истинное значение (y_true), а второй - прогноз модели (y_pred). Во время проверки эти аргументы являются тензорами, поэтому для расчетов мы должны использовать бэкэнд Keras.
import tf.keras.backend as K
def matthews_correlation(y_true, y_pred):
y_pred_pos = K.round(K.clip(y_pred, 0, 1))
y_pred_neg = 1 - y_pred_pos
y_pos = K.round(K.clip(y_true, 0, 1))
y_neg = 1 - y_pos
tp = K.sum(y_pos * y_pred_pos)
tn = K.sum(y_neg * y_pred_neg)
fp = K.sum(y_neg * y_pred_pos)
fn = K.sum(y_pos * y_pred_neg)
numerator = (tp * tn - fp * fn)
denominator = K.sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn))
return numerator / (denominator + K.epsilon())
Использование этой функции с моделями Keras:
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=[matthews_correlation])
И вызов fit () теперь выводит:
245063/245063 [==============================] - 63s 256us/step - matthews_correlation: 0.0032 - val_matthews_correlation: 0.0039
(Note that the name is the function name, while for validation data there is always the val_ prefix)
Оценка интервала с использованием обратных вызовов
Если вы хотите оценивать модель на отдельном наборе данных каждые N эпох, вы можете использовать настраиваемый обратный вызов. В этом случае используется оценка AUC из scikit-learn.
from sklearn.metrics import roc_auc_score
from tf.keras.callbacks import Callback
class IntervalEvaluation(Callback):
def __init__(self, validation_data=(), interval=10):
super(Callback, self).__init__()
self.interval = interval
self.X_val, self.y_val = validation_data
def on_epoch_end(self, epoch, logs={}):
if epoch % self.interval == 0:
y_pred = self.model.predict_proba(self.X_val, verbose=0)
score = roc_auc_score(self.y_val, y_pred)
print("interval evaluation - epoch: {:d} - score: {:.6f}".format(epoch, score))
Чтобы обучить модель этой настройке оценки, экземпляр объекта передается в Keras в качестве обратного вызова.
ival = IntervalEvaluation(validation_data=(x_validate, y_validate), interval=10)
model.fit(x_train, y_train,
batch_size=8196,
epochs=25,
validation_data=[x_test, y_test],
class_weight=class_weight,
callbacks=[ival],
verbose=1 )
И результат выглядит так:
interval evaluation - epoch: 0 - score: 0.545038
interval evaluation - epoch: 10 - score: 0.724098
interval evaluation - epoch: 20 - score: 0.731381
Расширить tf.keras.metrics.Metric
И, наконец, можно расширить сам объект метрики. (Кредиты на Geeocode из Stackoverflow)
class CategoricalTruePositives(tf.keras.metrics.Metric): def __init__(self, num_classes, batch_size, name="categorical_true_positives", **kwargs): super(CategoricalTruePositives, self).__init__(name=name, **kwargs) self.batch_size = batch_size self.num_classes = num_classes self.cat_true_positives = self.add_weight(name="ctp", initializer="zeros") def update_state(self, y_true, y_pred, sample_weight=None): y_true = K.argmax(y_true, axis=-1) y_pred = K.argmax(y_pred, axis=-1) y_true = K.flatten(y_true) true_poss = K.sum(K.cast((K.equal(y_true, y_pred)), dtype=tf.float32)) self.cat_true_positives.assign_add(true_poss) def result(self): return self.cat_true_positives
Есть только одно заметное отличие от первого примера. Функция результата возвращается, и метод update_state должен быть переопределен (это место, где происходит вычисление). Он также принимает один дополнительный аргумент (sample_weight). И, наконец, тензор результата возвращается методом re result.
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[
CategoricalTruePositives(num_classes, batch_size)])
Мы видели три разных способа реализации настраиваемой метрики проверки. Надеюсь, это помогло решить, какой способ подходит для вашего варианта использования, и не забудьте проверить, доступна ли уже ваша метрика в большом количестве предопределенных в tf.keras.metrics.
Этот пост был первоначально опубликован на digital-thinking.de (19 декабря 2018 г.)