How to convert a tensor to a numpy array without enabling the run_eagerly flag in keras

I am writing my own metric call-back functions where I use sklearn to calculate the metrics and for that I need to have the y_true and y_pred tensors as numpy arrays. My functions look like this:

def precision_macro(y_true, y_pred):
    # get the y_true and y_pred tensors as 1-D numpy array
    y_true_array = np.array(true)
    y_pred_array = np.array(pred)
    ....................
    ....................
        CALCULATIONS
    ....................
    ....................
    precision = precision_score(y_true_array, y_pred_array, average="macro", zero_division=0)
    return precision

Everything works fine if I set the run_eargly=True during the compile call like this:

model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=lr),
                      loss='binary_crossentropy',
                      metrics=model_metrics,
                      run_eagerly=True) 

but this is very costly and way slower than with the flag set to False but if I don’t set the flag to True I have a problem with the conversion. Here are things I have tried without setting the run_eagrly flag to True and didn’t work:

If I just don’t set the run_eagerly flag, I get the following error

NotImplementedError: Cannot convert a symbolic Tensor (ExpandDims:0) to a numpy array. This error may indicate that you’re trying to pass a Tensor to a NumPy call, which is not supported

Then I tried

import tensorflow.keras.backend as K

def precision_macro(y_true, y_pred):
    # get the y_true and y_pred tensors as 1-D numpy array
    y_true_array = K.eval(y_true)
    y_pred_array = K.eval(y_pred)
    ....................

Or I try to call the numpy function on the tensors

def precision_macro(y_true, y_pred):
    # get the y_true and y_pred tensors as 1-D numpy array
    y_true_array = y_true.numpy()
    y_pred_array = y_pred.numpy()
    ....................

I also tried run this inside a session like this:

import tensorflow.keras.backend as K
import tensorflow as tf

def precision_macro(y_true, y_pred):
    sess = tf.compat.v1.Session()
    # get the y_true and y_pred tensors as 1-D numpy array
    with sess.as_default():
       y_true_array = K.eval(y_true)
       y_pred_array = K.eval(y_pred)
    ....................

I get the following error for all thress cases

AttributeError: ‘Tensor’ object has no attribute ‘numpy’

I tried to run it like this:

import tensorflow.keras.backend as K
import tensorflow as tf

def precision_macro(y_true, y_pred):
    sess = tf.compat.v1.Session()
    # get the y_true and y_pred tensors as 1-D numpy array
    with sess.as_default():
       y_true_array = sess.run(y_true)
       y_pred_array = sess.run(y_pred)
    ....................

I get the following error

InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: You must feed a value for placeholder tensor ‘iterator’ with dtype resource
(1) Invalid argument: You must feed a value for placeholder tensor ‘iterator’ with dtype resource

I tried downgrading numpy from 1.19.5 to 1.18.5 but that didn’t work either, I get the same errors

I am using keras = 2.6. tensorflow = 2.6 numpy = 1.19.5

So, can anybody help me ?

Why you don’t implement your custom metric composing TF ops if you want to run in graph mode?

See also Custom metrics section in:

1 Like

Thanks for the reply, I have looked into that and as I am fairly new to this I would like to ask you if what I have in mind is true or not. Here what I think could work

class PrecisionMacro(tf.keras.metrics.Metric):

  def __init__(self, name='precision_m', **kwargs):
    super(PrecisionMacro, self).__init__(name=name, **kwargs)
    self.precision= np.asarray(1,)

  def update_state(self, y_true, y_pred, sample_weight=None):
    y_true_array = tf.make_ndarray(y_true)
    y_pred_array = tf.make_ndarray(y_pred)

    self.precision = precision_score(y_true_array, y_pred_array)

  def result(self):
    return self.precision

Thanks

What I mean Is that you could write precision_score using TF ops instead of numpy ops.

1 Like