1
votes

I want to define a custom loss function using Keras, which contains the gradient of the difference between y_true and y_pred. I found numpy.gradient can help me get the gradient of an array. So part of my code for loss function looks like this:

def loss(y_true, y_pred):
    d   = y_true - y_pred
    gradient_x = np.gradient(d, axis=0)
    gradient_y = np.gradient(d, axis=1)

but it turns out d is a Tensorflow tensor class and numpy.gradient can't process it. I'm kind of new to Keras and Tensorflow.

Is there any other function can help me do this? Or I have to compute the gradient by myself?

1

1 Answers

0
votes

Tensorflow tensors are not arrays at all when they are executed, they are only references to a computational graph that is being built. You might want to review the tutorial on how Tensorflow builds graphs.

You have two problems with your loss function: first, collapsing on either axis will not yield a scalar, so it won't be possible to take a derivative and second, np.gradient doesn't appear to exist in Tensorflow.

For the first problem, you can solve it by reducing along the remaining axis of gradient_y or gradient_x. I don't know which function you might want to use because I don't know your application.

The second problem can be fixed in two ways:

  1. You could wrap np.gradient using py_func, but you plan to use this as a loss function, so you will want to take the gradient of that function, and defining the gradient of a py_func call is complicated.
  2. Write your own version of np.gradient using pure Tensorflow.

For example, here's a 1D np.gradient in tensorflow (untested):

def gradient(x):
    d = x[1:]-x[:-1]
    fd = tf.concat([x,x[-1]], 0).expand_dims(1)
    bd = tf.concat([x[0],x], 0).expand_dims(1)
    d = tf.concat([fd,bd], 1)
    return tf.reduce_mean(d,1)