0

So usually in single label classification, we use the following

correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(self.label, 1))

But I am working with multi label classification so I'd like to know how to do that where there are several ones in the label vector. So what I have so far is below

 a = tf.constant([0.2, 0.4, 0.3, 0.1])
 b = tf.constant([0,1.0,1,0])
 empty_tensor = tf.zeros([0])
 for index in range(b.get_shape()[0]):
     empty_tensor = tf.cond(tf.equal(b[index],tf.constant(1, dtype = 
     tf.float32)), lambda:  tf.concat([empty_tensor,tf.constant([index], 
     dtype = tf.float32)], axis = 0), lambda: empty_tensor)

 temp, _ = tf.setdiff1d([tf.argmax(a)], tf.cast(empty_tensor, dtype= tf.int64))
 output, _ = tf.setdiff1d([tf.argmax(a)], tf.cast(temp, dtype = tf.int64))

So this gives me the indice at which max(preds) happens and where there is a 1 in self.label. In the above example it gives [1] and if the argmax do not match, then I get [].

The issue that I have is that I do not how to proceed from there as I would like something like the following

correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(self.label, 1))
self.accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))

which is straightforward for single label classification.

Thanks a lot

Tom
  • 275
  • 2
  • 16
  • 1
    My question is more about how to code the count of corresponding ones (i.e, where the indices are the same) for the predictions and and the true labels. – Tom Mar 30 '18 at 23:23
  • I wouldn't call this a complete duplicate since the question is specifically for Tensorflow. The question title could, however, be changed into "Multilabel classification and accuracy in Tensorflow" to be more general and thus easier for others to find. – bantmen Mar 30 '18 at 23:28

1 Answers1

1

I don't think you can achieve this with softmax so I am assuming that you are using sigmoids for your preds. If you are using sigmoids, your outputs will be each (independently) be between 0 and 1. You can define a threshold for each, perhaps 0.5, and then convert your sigmoid preds into the label encoding (0's and 1's) by doing preds > 0.5.

If prediction is [0 1] and label is [1 1], do you want to report that as completely or partially wrong? I am going to assume the former. In that case, you would remove the tf.argmax call and instead check if the preds and label are exactly the same vectors, which would look like tf.reduce_all(tf.equal(preds, label), axis=0). For the latter, the code would look like tf.reduce_sum(tf.equal(preds, label), axis=0).

bantmen
  • 748
  • 6
  • 17
  • First of all, thanks a lot for the answer. And yes, ultimately this is what I will do. However, I would still have the same problem as before to count the occurrence of correct classifications, where I will have several ones in predictions and labels? – Tom Mar 30 '18 at 23:20
  • No problem and correct. If prediction is [0 1] and [1 1], do you want to report that as completely or partially wrong? I am going to assume the former. In that case, you would remove the tf.argmax call and instead check if the preds and self.label are exactly the same vectors, which would look like `tf.reduce_all(tf.equal(preds, label), axis=0)`. I'll add this to the answer. – bantmen Mar 30 '18 at 23:25
  • In that case, I would actually want to count the number of ones which match and the total number of ones in the labels. So I would have 1 and 2 as outputs. – Tom Mar 30 '18 at 23:32
  • Oops, I've missed a word; it should have been "If prediction is [0 1] and label is [1 1], ...". In that case, you want to use `tf.equal` followed by `tf.reduce_sum`. – bantmen Mar 30 '18 at 23:33
  • Thanks! that is what I was asking indeed. Although, after trying out your solutions, it seems that tf.reduce_sum needs to be casted first as it does not handle bool. tf.reduce_all fine with bools to check if all True or not. – Tom Mar 30 '18 at 23:43