0

I am working on multilabel text classification using Keras. I have defined custom metrics for F1 score, recall, and precision and used them while compile(). but now I want to call my metrics function to predict the score I get the following error.

    from keras import backend as K
    import tensorflow as tf

    def recall_m(y_true, y_pred):
        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
        recall = true_positives / (possible_positives + K.epsilon())
        return recall

    def precision_m(y_true, y_pred):
        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
        precision = true_positives / (predicted_positives + K.epsilon())
        return precision

    def f1_m(y_true, y_pred):
        precision = precision_m(y_true, y_pred)
        recall = recall_m(y_true, y_pred)
        return 2*((precision*recall)/(precision+recall+K.epsilon()))

  model.compile('Adam', 'binary_crossentropy', metrics = [f1_m, precision_m, 
  recall_m])

  history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, 
  callbacks=[early_stopping, chk], validation_data=(x_valid, y_valid))

after training i want to predict my results as follows:

     y_pred=np.asarray(model.predict(x_test))>0.3
     y_pred.round()
     
   array([[0., 0., 0., ..., 0., 0., 0.],
   [0., 0., 0., ..., 0., 0., 0.],
   [0., 0., 1., ..., 0., 0., 0.],
   ...,
   [0., 0., 0., ..., 0., 0., 0.],
   [0., 0., 0., ..., 0., 0., 0.],
   [0., 0., 0., ..., 0., 0., 0.]], dtype=float16)

then i call my metrics:

   r=recall_m(y_test, y_pred)

it gives me the following error:

   ------------------------------------------------------------------------
   InvalidArgumentError            Traceback (most recent call last)
   <ipython-input-33-5cc75ee76627> in <module>()
   ----> 1 r=recall_m(y_test, y_pred)

   6 frames
   <ipython-input-27-4b9c46f5a788> in recall_m(y_true, y_pred)
         6     true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
         7     possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
   ----> 8     recall = true_positives / (possible_positives + K.epsilon())
         9     return recall
        10 

   /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/math_ops.py 
   in binary_op_wrapper(x, y)
        1162     with ops.name_scope(None, op_name, [x, y]) as name:
        1163       try:
     -> 1164         return func(x, y, name=name)
        1165       except (TypeError, ValueError) as e:
        1166         # Even if dispatching the op failed, the RHS may be a 
                      tensor aware
   /usr/local/lib/python3.7/dist- 
   packages/tensorflow/python/util/dispatch.py 
   in wrapper(*args, **kwargs)
         199     """Call target, and fall back on dispatchers if there is a 
                  TypeError."""
         200     try:
     --> 201       return target(*args, **kwargs)
         202     except (TypeError, ValueError):
         203       # Note: convert_to_eager_tensor currently raises a 
                   ValueError, 
              not a

    /usr/local/lib/python3.7/dist- 
    packages/tensorflow/python/ops/math_ops.py in _add_dispatch(x, y, name)
        1484     return gen_math_ops.add(x, y, name=name)
        1485   else:
     -> 1486     return gen_math_ops.add_v2(x, y, name=name)
        1487 
        1488 

     /usr/local/lib/python3.7/dist- 
     packages/tensorflow/python/ops/gen_math_ops.py in add_v2(x, y, name)
        470       return _result
        471     except _core._NotOkStatusException as e:
    --> 472       _ops.raise_from_not_ok_status(e, name)
        473     except _core._FallbackException:
        474       pass

    /usr/local/lib/python3.7/dist- 
    packages/tensorflow/python/framework/ops.py in 
    raise_from_not_ok_status(e, name)
        6860   message = e.message + (" name: " + name if name is not None 
               else "")
        6861   # pylint: disable=protected-access
     -> 6862   six.raise_from(core._status_to_exception(e.code, message), 
               None)
        6863   # pylint: enable=protected-access
        6864 

     /usr/local/lib/python3.7/dist-packages/six.py in raise_from(value, 
     from_value)

     InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was 
     expected to be a int64 tensor but is a float tensor [Op:AddV2]

kindly help

Raz
  • 25
  • 6
  • Does this answer your question? [how to implement custom metric in keras?](https://stackoverflow.com/questions/37657260/how-to-implement-custom-metric-in-keras) – Kipkurui Mar 02 '21 at 14:40
  • @Kipkurui not really, I read that post already. my query is how can I use my custom-defined metrics after model.predict() so that I can see my metric score(f1_m, recall_m, precision_m) in my case, on the test dataset. – Raz Mar 02 '21 at 15:09
  • Can you edit the code as to make the indentation correct please? Also, could you add the **full** traceback? – Lescurel Mar 02 '21 at 15:48
  • @Lescurel done with edit. thank you for your reply – Raz Mar 03 '21 at 04:34

1 Answers1

1

TensorFlow does not do implicit casting. When you add Tensors together, they need to have the same type. Your y_true tensor has a int64 type, while K.espilon is a float32. Cast the inputs before doing the calculations, for example:

def recall_m(y_true, y_pred):
    y_true = tf.cast(y_true, tf.float32)
    y_pred = tf.cast(y_pred, tf.float32)
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall
Lescurel
  • 10,749
  • 16
  • 39
  • thank you for your kind reply, i am going to try this. – Raz Mar 03 '21 at 16:30
  • i am really grateful to you and StackOverflow. your answer really saved my time. i really appreciate your efforts by my heart. thankyou your answer worked for me. – Raz Mar 04 '21 at 05:24