Skip to content

Instantly share code, notes, and snippets.

@lmassaron
Last active May 28, 2019 09:54
Show Gist options
  • Select an option

  • Save lmassaron/9e218a3ac53700a34c26e158d6d3e412 to your computer and use it in GitHub Desktop.

Select an option

Save lmassaron/9e218a3ac53700a34c26e158d6d3e412 to your computer and use it in GitHub Desktop.
Custom metrics for Keras from Scikit-learn
# Custom metrics for Keras from Scikit-learn
from sklearn.metrics import roc_auc_score
from sklearn.metrics import average_precision_score
def auroc(y_true, y_pred):
return tf.py_func(roc_auc_score, (y_true, y_pred), tf.double)
def mAP(y_true, y_pred):
return tf.py_func(average_precision_score, (y_true, y_pred), tf.double)
def balanced_recall(y_true, y_pred):
"""
Computes the average per-column recall metric
for a multi-class classification problem
"""
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)), axis=0)
possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)), axis=0)
recall = true_positives / (possible_positives + K.epsilon())
balanced_recall = K.mean(recall)
return balanced_recall
"""
Custom loss functions
def custom_loss_function(y_true, y_pred):
"""
Compute custom loss, returns value
"""
from keras import backend as K
return K.max(K.abs(y_pred - y_true), axis=-1)
model.compile(loss=custom_loss_function, [...])
"""
# FOCAL LOSS
gamma = 2.0
epsilon = K.epsilon()
def focal_loss(y_true, y_pred):
pt = y_pred * y_true + (1-y_pred) * (1-y_true)
pt = K.clip(pt, epsilon, 1-epsilon)
CE = -K.log(pt)
FL = K.pow(1-pt, gamma) * CE
loss = K.sum(FL, axis=1)
return loss
# F2
from keras import backend as K
def f_score(y_true, y_pred, threshold=0.1, beta=2):
tp = tp_score(y_true, y_pred, threshold)
fp = fp_score(y_true, y_pred, threshold)
fn = fn_score(y_true, y_pred, threshold)
precision = tp / (tp + fp)
recall = tp / (tp + fn)
return (1+beta**2) * ((precision * recall) / ((beta**2)*precision + recall))
def tp_score(y_true, y_pred, threshold=0.1):
tp_3d = K.concatenate(
[
K.cast(K.expand_dims(K.flatten(y_true)), 'bool'),
K.cast(K.expand_dims(K.flatten(K.greater(y_pred, K.constant(threshold)))), 'bool'),
K.cast(K.ones_like(K.expand_dims(K.flatten(y_pred))), 'bool')
], axis=1
)
tp = K.sum(K.cast(K.all(tp_3d, axis=1), 'int32'))
return tp
def fp_score(y_true, y_pred, threshold=0.1):
fp_3d = K.concatenate(
[
K.cast(K.expand_dims(K.flatten(K.abs(y_true - K.ones_like(y_true)))), 'bool'),
K.cast(K.expand_dims(K.flatten(K.greater(y_pred, K.constant(threshold)))), 'bool'),
K.cast(K.ones_like(K.expand_dims(K.flatten(y_pred))), 'bool')
], axis=-1
)
fp = K.sum(K.cast(K.all(fp_3d, axis=1), 'int32'))
return fp
def fn_score(y_true, y_pred, threshold=0.1):
fn_3d = K.concatenate(
[
K.cast(K.expand_dims(K.flatten(y_true)), 'bool'),
K.cast(K.expand_dims(K.flatten(K.abs(K.cast(K.greater(y_pred, K.constant(threshold)), 'float') - K.ones_like(y_pred)))), 'bool'),
K.cast(K.ones_like(K.expand_dims(K.flatten(y_pred))), 'bool')
], axis=1
)
fn = K.sum(K.cast(K.all(fn_3d, axis=1), 'int32'))
return fn
def precision_score(y_true, y_pred, threshold=0.1):
tp = tp_score(y_true, y_pred, threshold)
fp = fp_score(y_true, y_pred, threshold)
return tp / (tp + fp)
def recall_score(y_true, y_pred, threshold=0.1):
tp = tp_score(y_true, y_pred, threshold)
fn = fn_score(y_true, y_pred, threshold)
return tp / (tp + fn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment