Custom metric in Keras to calculate binary classification accuracy in regression task

Viewed 132

I am having significant trouble in navigating the tensorflow syntax and functions and am struggling with the fact that Keras isn't providing me with nice np arrays.

I have a network with a single tanh activation output.

Essentially this is what I want:

y_true = [-0.4, -0.2, 0, -0.3, 0.4, 0.1, -1, 1, 0, -0.2] 
y_pred = [-0.4, 0.2, 0, -0.3, -0.4, 0.1, -1, -1, 0, 1] 

I want to calculate the proportion of predictions that have the same sign as the ground truth values. e.g. in the above example, this would be 7/10 or 70%

I would calculate this using perhaps:

correct = np.where((y_true * y_pred) >= 0, 1 , 0)
correct.mean() 

Given the following function header for a custom metric in Keras, how would I go about doing this?

def binary_class_acc_metric(y_true, y_pred):

Many thanks

2 Answers

Using the Keras backend:

from tensorflow.keras import backend as K
import numpy as np
y_true = K.constant(np.array([-0.4, -0.2, 0, -0.3, 0.4, 0.1, -1, 1, 0, -0.2]))
y_pred = K.constant(np.array([-0.4, 0.2, 0, -0.3, -0.4, 0.1, -1, -1, 0, 1]))

def binary_class_acc_metric(y_true, y_pred):
    y_sign = y_true * y_pred
    pos_count = K.sum(K.cast(K.greater_equal(y_sign, 0.0), 'float32'))
    metric = pos_count / K.int_shape(y_pred)[0]
    print(metric)
    return metric

K.eval(binary_class_acc_metric(y_true, y_pred))

The numpy is just used to test the custom metric function. If you wish to exclude the 0's, you can use K.greater() only.

This seems to work:

def acc(y_true, y_pred):
    multi = tf.multiply(y_true, y_pred)
    correct = K.greater(multi,0)
    return K.mean(correct)
Related