0
votes

BACKGROUND:

I want to retrieve the equal of len(x) and x.shape[0] for y_pred and y_true inside a custom Keras metric without using anything but Keras backend.

Consider a minimal Keras metric example:

from keras import backend as K

def binary_accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

Here y_pred and y_true are tensors that represent numpy arrays of a certain shape.

QUESTION:

How to get the length of the underlying array inside the keras metric function so that the resulting code will be in the form:

def binary_accuracy(y_true, y_pred):
    # some Keras backend code 
    return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

NOTE: the code has to be Keras backend code, so that it works on any Keras backend.

I've already tried K.ndim(y_pred) which returns 2 even though the length is 45 actually and K.int_shape(y_pred) which returns None.

2

2 Answers

2
votes

You need to remember that in some cases, the shape of a given symbolic tensor (e.g. y_true and y_pred in your case) cannot be determined until you feed values to specific placeholders that this tensor relies on.

Keeping that in mind, you have two options:

  1. Use K.int_shape(x) to get a tuple of ints and Nones that represent the shape of the input tensor x. In this case, the dimensions with undetermined lengths will be None. This is useful in cases where your non-Tensorflow code does not depend on undetermined dimensions. e.g. you cannot do the following:

    if K.shape(x)[0] == 5:
        ...
    else:
        ...
    
  2. Use K.shape(x) to get a symbolic tensor that represents the shape of the tensor x. This is useful in cases where you want to use the shape of a tensor to change your TF graph, e.g.:

    t = tf.ones(shape=K.shape(x)[0])

0
votes

You can access the shape of the tensor through K.int_shape(x) By taking the first value of the result, you will get the length of the underlying array : K.int_shape(x)[0]