1

I want to count the number of matching label in a custom error function

I tested :

def custom__error(y_true, y_pred):
  # ---- y_pred
  yp = tf.nn.softmax( y_pred)
  bp = tf.argsort(yp,axis=-1,direction='DESCENDING',stable=False,name=None)
  cp = tf.keras.backend.eval(bp)
  # ---- y_true
  yt = tf.nn.softmax( y_true )
  bt = tf.argsort(yt,axis=-1,direction='DESCENDING',stable=False,name=None)
  ct = tf.keras.backend.eval(bt)
  # ---- common
  count =  tf.sets.intersection(cp[None,:10],ct[None,:10])
  return count

but I got an error:

AttributeError: 'Tensor' object has no attribute '_numpy'

I also tried :

 def custom__error(y_true, y_pred):
  # ---- y_pred
  yp = tf.nn.softmax( y_pred)
  bp = tf.argsort(yp,axis=-1,direction='DESCENDING',stable=False,name=None)
  cp = bp.to_numpy()
  xcp = cp[None,:10]
  # ---- y_true
  yt = tf.nn.softmax( y_true )
  bt = tf.argsort(yt,axis=-1,direction='DESCENDING',stable=False,name=None)
  ct = bt.to_numpy()
  xct = ct[None,:10]
  # ---- common
  count =  tf.sets.intersection(tf.convert_to_tensor(xcp),tf.convert_to_tensor(xct))
  return count

I don't know how to use tf.sets.intersection inside tensorflow backend function.

Can someone help me understand ?


The complete error

AttributeError                            Traceback (most recent call last)
<ipython-input-319-eed924909205> in <module>()
      4 print(optimizer.learning_rate.numpy())  # or print(optimizer.lr.numpy())
      5 model_loss=custom__loss(100,100,1,0.01)
----> 6 model.compile(loss=model_loss, optimizer=optimizer, metrics=['accuracy',custom__error])

11 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py in <listcomp>(.0)
   3798     return nest.pack_sequence_as(
   3799         self._outputs_structure,
-> 3800         [x._numpy() for x in outputs],  # pylint: disable=protected-access
   3801         expand_composites=True)
   3802 

AttributeError: 'Tensor' object has no attribute '_numpy'

I tried to return numpy array :

return count.to_numpy()

or with:

def custom__error(y_true, y_pred):
  # ---- y_pred
  yp = tf.nn.softmax( y_pred)
  bp = tf.argsort(yp,axis=-1,direction='DESCENDING',stable=False,name=None)
  cp = bp.to_numpy()
  xcp = cp[None,:10]
  # ---- y_true
  yt = tf.nn.softmax( y_true )
  bt = tf.argsort(yt,axis=-1,direction='DESCENDING',stable=False,name=None)
  ct = bt.to_numpy()
  xct = ct[None,:10]
  # ---- common
  count =  tf.sets.intersection(xcp,xct)
  return count

but got the same error:

<ipython-input-114-59d27aab97e1> in custom__error(y_true, y_pred)
      3   yp = tf.nn.softmax( y_pred)
      4   bp = tf.argsort(yp,axis=-1,direction='DESCENDING',stable=False,name=None)
----> 5   cp = bp.to_numpy()
      6   xcp = cp[None,:10]
      7   # ---- y_true

AttributeError: 'Tensor' object has no attribute 'to_numpy'

<ipython-input-91-16ca4acce397> in custom__error(y_true, y_pred)
     12   # ---- common
     13   count =  tf.sets.intersection(xcp,xct)
---> 14   return count.numpy()
     15 
     16 

AttributeError: 'SparseTensor' object has no attribute 'numpy'
Harvey
  • 135
  • 1
  • 10

1 Answers1

1

In this line:

model.compile(loss=model_loss, optimizer=optimizer, metrics=['accuracy',custom__error])

the custom__error function is expected to return a numpy array, whereas tf.insersection would give you Tensor's in this case because y_true and y_pred passed to tf.intersection are tensors themselves.

Hence you would first need to convert count to a numpy array before returning it.

This answer might help.


Edit:
count is SparseTensor, hence first convert it to a dense tensor with:

dcount = tf.sparse.to_dense(count) 

Then you need to check the mode in which tensorflow is running. You can it using this:

tf.executing_eagerly()
  • If this returns True:
    Eager mode active. You need to call .numpy() on the tensor to be converted.
  • If this returns False:
    Graph mode active. You need to call .eval() on the tensor to be converted.

If you like you can automate it for you:

if tf.executing_eagerly():
    return dcount.numpy()
else
    return dcount.eval()

Credit: TF 2.0 'Tensor' object has no attribute 'numpy' while using .numpy() although eager execution enabled by default


If you are using Tensorflow 1.x, you may need to enable eager execution manually. Check this answer for details.

Kashinath Patekar
  • 1,083
  • 9
  • 23
  • 1
    I have updated the answer. The method .to_numpy() does not exist, hence the error. The error *did* change. It was as different place, and for different reason. I hope the updated answer solves the issue for you, cheers! – Kashinath Patekar May 18 '20 at 18:00
  • in custom__error(y_true, y_pred) 12 # ---- common 13 count = tf.sets.intersection(xcp,xct) ---> 14 return count.numpy() 15 16 AttributeError: 'SparseTensor' object has no attribute 'numpy' – Harvey May 19 '20 at 16:56
  • Thanks for your help : TensorFlow 2.x selected,but got SparseTensor' object has no attribute 'numpy'. – Harvey May 19 '20 at 16:59
  • Then you would first need to convert the sparse tensor to dense tensor. (SparseTensor -> Tensor). A quick Google search should do the trick. To recap, original `count` (SparseTensor) => (dense) Tensor => numpy array – Kashinath Patekar May 19 '20 at 18:06
  • count = tf.sets.intersection(xcp,xct) dcount = tf.sparse.to_dense(count) return dcount.numpy() – Harvey May 20 '20 at 06:29
  • in custom__error(y_true, y_pred) 13 count = tf.sets.intersection(xcp,xct) 14 dcount = tf.sparse.to_dense(count) ---> 15 return dcount.numpy() 16 17 AttributeError: 'Tensor' object has no attribute 'numpy' – Harvey May 20 '20 at 06:30
  • Could you give a link to the colab notebook, if it is one? this seems unusual – Kashinath Patekar May 20 '20 at 06:33
  • https://colab.research.google.com/drive/14TC0Hgf_aKtSTwlZvUKMlVYZUdvUuVJv?usp=sharing – Harvey May 20 '20 at 10:19