Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining an AUC metric for Keras to support evaluation of validation dataset

Tags:

keras

I am trying to implement an AUC metric for Keras so that I have AUC measurement after my validation set runs during a model.fit() run.

I define the metric as such:

def auc(y_true, y_pred):   
    keras.backend.get_session().run(tf.global_variables_initializer())
    keras.backend.get_session().run(tf.initialize_all_variables())
    keras.backend.get_session().run(tf.initialize_local_variables())

    #return K.variable(value=tf.contrib.metrics.streaming_auc(
    #    y_pred, y_true)[0], dtype='float32')
    return tf.contrib.metrics.streaming_auc(y_pred, y_true)[0]

This results in the following error which I don't know understand.

tensorflow.python.framework.errors_impl.FailedPreconditionError: 
Attempting to use uninitialized value auc/true_positives...

From online reading, it seems that the problem is 2-fold, a bug in tensorflow/keras and partially and issue with tensorflow being unable to initialize local variables from inference. Given these 2 issues, I do not see why I get this error or how to overcome it. Any suggestions?

I wrote two other metrics that work just fine:

# PFA, prob false alert for binary classifier
def binary_PFA(y_true, y_pred, threshold=K.variable(value=0.5)):
    y_pred = K.cast(y_pred >= threshold, 'float32')
    # N = total number of negative labels
    N = K.sum(1 - y_true)
    # FP = total number of false alerts, alerts from the negative class labels
    FP = K.sum(y_pred - y_pred * y_true)    
    return FP/N

# P_TA prob true alerts for binary classifier
def binary_PTA(y_true, y_pred, threshold=K.variable(value=0.5)):
    y_pred = K.cast(y_pred >= threshold, 'float32')
    # P = total number of positive labels
    P = K.sum(y_true)
    # TP = total number of correct alerts, alerts from the positive class labels
    TP = K.sum(y_pred * y_true)    
    return TP/P
like image 692
Avedis Avatar asked Apr 06 '17 18:04

Avedis


People also ask

What is AUC in Keras?

The AUC (Area under the curve) of the ROC (Receiver operating characteristic; default) or PR (Precision Recall) curves are quality measures of binary classifiers. Unlike the accuracy, and like cross-entropy losses, ROC-AUC and PR-AUC evaluate all the operational points of a model.

How do you write custom metrics in Keras?

How to create a custom metric in Keras? As we had mentioned earlier, Keras also allows you to define your own custom metrics. The function you define has to take y_true and y_pred as arguments and must return a single tensor value. These objects are of type Tensor with float32 data type.

How does Keras use the validation set?

Keras can separate a portion of your training data into a validation dataset and evaluate the performance of your model on that validation dataset in each epoch. You can do this by setting the validation_split argument on the fit() function to a percentage of the size of your training dataset.

How do I choose Keras metrics?

You can do this by specifying the “metrics” argument and providing a list of function names (or function name aliases) to the compile() function on your model. The specific metrics that you list can be the names of Keras functions (like mean_squared_error) or string aliases for those functions (like 'mse').


1 Answers

Here are the tricks that I often use. Basically, this allows you to use whatever existing metrics in sklearn

from sklearn.metrics import roc_auc_score
import tensorflow as tf
def auc( y_true, y_pred ) :
    score = tf.py_func( lambda y_true, y_pred : roc_auc_score( y_true, y_pred, average='macro', sample_weight=None).astype('float32'),
                        [y_true, y_pred],
                        'float32',
                        stateful=False,
                        name='sklearnAUC' )
    return score

Now we can create a simple model to verify this metric.

from keras.layers import Input
from keras.models import Model

x = Input(shape=(100,))
y = Dense(10, activation='sigmoid')(x)
model = Model(inputs=x, outputs=y)
model.compile( 'sgd', loss='binary_crossentropy', metrics=[auc] )
print model.summary()


a = np.random.randn(1000,100)
b = np.random.randint(low=0,high=2,size=(1000,10))
model.fit( a, b )
like image 104
pitfall Avatar answered Oct 27 '22 19:10

pitfall