1
votes

I'm using Keras with Tensorflow backend. I would like to create a new custom loss function where I pool the individual values of y_true and y_pred into bins (think of a histogram), and then calculate the chi2 between the two histograms.

I understand tensor object are not iterable, so I can't loop over the individual elements of y_true and y_pred to fill the histograms.

Update:

I tried to create a loss function like this:

def Chi2Loss(y_true, y_pred):
     h_true = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20) 
     h_pred = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20) 
     return K.mean(K.square(h_true - h_pred))

But I get an error:

TypeError: Input 'y' of 'Mul' Op has type float32 that does not match type int32 of argument 'x'.

2
Hello there. Could you please provide a minimal, complete, and verifiable example? - Hagbard
I tried to create a loss function like this: def Chi2Loss(y_true, y_pred): h_true = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20) h_pred = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20) return K.mean(K.square(h_true - h_pred)) But I get an error: TypeError: Input 'y' of 'Mul' Op has type float32 that does not match type int32 of argument 'x'. - Riccardo Di Sipio
Does it help to convert the int32 values of argument 'x' to float32 values? - Hagbard
if I add the option dtype=tf.float32 I get the following error: ``` TypeError: Value passed to parameter 'dtype' has DataType float32 not in list of allowed values: int32, int64 ``` - Riccardo Di Sipio

2 Answers

1
votes

It's a problem of numerical types: tf.histogram_fixed_width can just provide a int32 or int64 tensor, while K.square does not support any of these formats.

Solution: cast the tf.histogram_fixed_width output to a compatible numerical type, e.g. float32:

def Chi2Loss(y_true, y_pred):
    h_true = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20)
    h_pred = tf.histogram_fixed_width( y_pred, value_range=(-1., 1.), nbins=20)
    h_true = tf.cast(h_true, dtype=tf.dtypes.float32)
    h_pred = tf.cast(h_pred, dtype=tf.dtypes.float32)
    return K.mean(K.square(h_true - h_pred))
0
votes

i think it is because y_pred or Y_true is not directly used in the return and keras complains.

you can use this litle trick in keras:

def Chi2Loss(y_true, y_pred):
     h_true = tf.histogram_fixed_width( y_true, value_range=(-1., 1.), nbins=20) 
     h_pred = tf.histogram_fixed_width( y_pred, value_range=(-1., 1.), nbins=20) 
     return K.mean(K.square(h_true - h_pred)) + y_pred*0 

hope it helps