Chong Sun
Chong Sun

Reputation: 67

Input to tensorflow in_top_k should be rank 1 or rank 2?

I try to experiment with in_top_k function to see what exactly this function is doing. But I found some really confusing behavior.

First I coded as follows

import numpy as np
import tensorflow as tf

target = tf.constant(np.random.randint(2, size=30).reshape(30,-1), dtype=tf.int32, name="target")
pred = tf.constant(np.random.rand(30,1), dtype=tf.float32, name="pred")
result = tf.nn.in_top_k(pred, target, 1)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    targetVal = target.eval()
    predVal = pred.eval()
    resultVal = result.eval()

Then it generates the following error:

ValueError: Shape must be rank 1 but is rank 2 for 'in_top_k/InTopKV2' (op: 'InTopKV2') with input shapes: [30,1], [30,1], [].

Then I changed my code to

import numpy as np
import tensorflow as tf
target = tf.constant(np.random.randint(2, size=30), dtype=tf.int32, name="target")
pred = tf.constant(np.random.rand(30,1).reshape(-1), dtype=tf.float32, name="pred")
result = tf.nn.in_top_k(pred, target, 1)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    targetVal = target.eval()
    predVal = pred.eval()
    resultVal = result.eval()

But now the error becomes

ValueError: Shape must be rank 2 but is rank 1 for 'in_top_k/InTopKV2' (op: 'InTopKV2') with input shapes: [30], [30], [].

So should the input be rank 1 or rank 2?

Upvotes: 1

Views: 1003

Answers (1)

xdurch0
xdurch0

Reputation: 10474

For in_top_k, the targets need to be rank 1 (class indices) and the predictions rank 2 (scores for each class). This can be seen from the docs easily.
This means that the two error messages actually complain about different inputs each time (targets the first time and predictions the second time), which funnily enough isn't mentioned in the messages at all... Either way, the following snippet should be more like it:

import numpy as np
import tensorflow as tf

target = tf.constant(np.random.randint(2, size=30), dtype=tf.int32, name="target")
pred = tf.constant(np.random.rand(30,1), dtype=tf.float32, name="pred")
result = tf.nn.in_top_k(pred, target, 1)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    targetVal = target.eval()
    predVal = pred.eval()
    resultVal = result.eval()

Here, we basically combine the "best of both snippets": Predictions from the first one and targets from the second one. However, the way I understand the docs, even for binary classification we need two values for the predictions, one for each class. So something like

import numpy as np
import tensorflow as tf

target = tf.constant(np.random.randint(2, size=30), dtype=tf.int32, name="target")
pred = tf.constant(np.random.rand(30,1), dtype=tf.float32, name="pred")
pred = tf.concat((1-pred, pred), axis=1)
result = tf.nn.in_top_k(pred, target, 1)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    targetVal = target.eval()
    predVal = pred.eval()
    resultVal = result.eval()

Upvotes: 1

Related Questions