2
votes

I'm new to Keras, neural networks and Python, but I'm very eager to learn... I'd like to use my own custom loss function, but I'm in trouble due to having the aforementioned handicaps :)

This is what I'm trying to accomplish:

  • Y_true is a float which can be either negative or positive
  • the model will predict a float that can be also negative or positive
  • I want to see how many times the prediction can match the sign (+/-) of the Y_true value
  • for this I'd multiply Y_pred and Y_true (so the result is positive if Y_pred and y_true has the same sign and it is negative if they are different)
  • then I'd count the number of positive and negative values in this multiplication result so then I can see how many times the prediction had the same sign and how many times the opposite
  • finally I'd return the ratio

First of all, my question would be: does this make sense? Am I correct that y_pred and y_true will have the shape of the batch size? So for ex. with a batch number of 100, if 60 out of the 100 predictions would match the y_true sign then the loss would be 0.60?

Second, actually I have no code yet :) This is the pseudocode:

def prediction_sign_accuracy(y_true, y_pred):
    y_sign_difference = y_pred * y_true
    pos_count = count number of positive values in y_sign_difference
    neg_count = count number of negative values in y_sign_difference
    if neg_count == 0:
      return a constant zero result
    else:
       return pos_count/neg_count

Can you please help me writing this ~10 lines of code? :) This may be obvious for others but a huge obstacle for me.

Many thanks in advance and have a nice day,

Tamás

1
Your loss function doesnt seem to be differentiable... just the way accuracy isnt differentiable :) - Nassim Ben
I don't think making your own loss function is the right approach. Why don't you just make Y_true 1.0 if it's positive and 0.0 if it's negative, and then use categorical cross entropy as loss with softmax as activation? - oscfri
Many thanks for your input! - Tamas Holics

1 Answers

1
votes

The first important thing to have in mind when you're writing a metric or loss function for keras is that it has to be written as tensor using keras.backend.

To achieve that, let's first "simulate" what we want to do using numpy arrays:

import numpy as np
y_true = np.array([1,4,-3,-1])
y_pred = np.array([5,-2,-1,1])
y_sign_difference = y_pred * y_true # this gives array([ 5, -8,  3, -1])
is_positive = np.greater(y_sign_difference, 0.0).astype(float)
# is_positive becomes array([ 1, 0, 1, 0])
pos_count = np.sum(is_positive) # --> 2

and use np.less for the negatives.

Now we can try to write that loss function (imho, this is rather a metric). Basically, all you have to do is turn np into K in the right place :

from keras import backend as K
def prediction_sign_accuracy(y_true, y_pred):
    y_sign_difference = y_pred * y_true
    pos_count = K.sum(K.cast(K.greater(y_sign_difference, 0.0), 'float32')
    # etc etc I'm not paid for this ;-)

Oh btw, if you want to test this function, you'll need to feed it accordingly, eg :

import numpy as np
y_true = K.constant(np.array([1,4,-3,-1]))
y_pred = K.constant(np.array([5,-2,-1,1]))

K.eval(prediction_sign_accuracy(y_true, y_pred)) # --> 1.0