Course 4, Week 3, Part 1: yolo_filter_boxes function problem

I have a problem with the first function in Week3 assignment. I always get an error and I have no idea what I did wrong. The error is copied below. Can anyone help please, thanks!

TypeError Traceback (most recent call last)
in
3 boxes = tf.random.normal([19, 19, 5, 4], mean=1, stddev=4, seed = 1)
4 box_class_probs = tf.random.normal([19, 19, 5, 80], mean=1, stddev=4, seed = 1)
----> 5 scores, boxes, classes = yolo_filter_boxes(boxes, box_confidence, box_class_probs, threshold = 0.5)
6 print("scores[2] = " + str(scores[2].numpy()))
7 print("boxes[2] = " + str(boxes[2].numpy()))

in yolo_filter_boxes(boxes, box_confidence, box_class_probs, threshold)
33 # Step 3: Create a filtering mask based on ā€œbox_class_scoresā€ by using ā€œthresholdā€. The mask should have the
34 # same dimension as box_class_scores, and be True for the boxes you want to keep (with probability >= threshold) (ā‰ˆ 1 line)
ā€”> 35 filtering_mask = tf.math.greater_equal(box_class_scores,threshold)
36
37 # Step 4: Apply the mask to box_class_scores, boxes and box_classes (ā‰ˆ 3 lines)

/opt/conda/lib/python3.7/site-packages/tensorflow/python/ops/gen_math_ops.py in greater_equal(x, y, name)
4053 _result = pywrap_tfe.TFE_Py_FastPathExecute(
4054 _ctx._context_handle, tld.device_name, ā€œGreaterEqualā€, name,
ā†’ 4055 tld.op_callbacks, x, y)
4056 return _result
4057 except _core._NotOkStatusException as e:

TypeError: Cannot convert 0.5 to EagerTensor of dtype int64

The problem is in the tf.math.greater_equal call you are doing to compare a tensor elementwise with a scalar value. It is trying to do the analog of numpy ā€œbroadcastingā€ to convert the second argument into a tensor of the same type and shape as the first argument. But for some reason, it looks like your box_class_scores is of type int64, which causes it to throw that error. How could that happen? You can check it like this:

print(f"box_class_scores.shape {box_class_scores.shape}")
print(f"box_class_scores.dtype {box_class_scores.dtype}")

When I added those lines to my routine and ran the same test cell you are running, hereā€™s what I got:

box_class_scores.shape (19, 19, 5)
box_class_scores.dtype <dtype: 'float32'>

What do you see when you try that?

1 Like

I guess this line should fix the problem ā†’ filtering_mask = (box_class_scores >= threshold)

I got the following lines:

box_class_scores.shape (19, 19)
box_class_scores.dtype <dtype: ā€˜int64ā€™>

I guess I have the dimensions wrong.

1 Like

I solved the problem. Thanks!

Itā€™s great to hear that you found the solution under your own power. Iā€™m actually kind of curious how you got the box class scores to have an integer value. I would have thought they would naturally end up as floating point.

Update: Later in this thread, we see an example of how to cause that: by using the wrong input tensor in the reduce_sum to compute box_class_scores.

Hey, I am having the same shape issues as you had: box_class_scores.shape (19, 19), how did you solve this problem? (I did use axis =-1, but the recommended functions keeps shrinking the dimensions)

Hi, @XiaoXiaLiang!

Well, where does box_class_scores get generated? It depends on the value of box_scores, right? So maybe box_scores is the wrong shape. Debugging is always ā€œone step at a timeā€. I added some more print statements like the ones that @gasperpavlic and I were talking about earlier and hereā€™s what I get when I run the test cell for yolo_filter_boxes:

box_scores.shape (19, 19, 5, 80)
box_scores.dtype <dtype: 'float32'>
box_class_scores.shape (19, 19, 5)
box_class_scores.dtype <dtype: 'float32'>
scores[2] = 9.270486
boxes[2] = [ 4.6399336  3.2303846  4.431282  -2.202031 ]
classes[2] = 8
scores.shape = (1789,)
boxes.shape = (1789, 4)
classes.shape = (1789,)
 All tests passed!

What shape do you see for box_scores?

Hello, I like to thank you for taking the time to help me. It is very kind of you.

Shapes and data types:

box_scores.shape (19, 19, 5, 80)
box_scores.dtype <dtype: ā€˜float32ā€™>

box_classes.shape (19, 19, 5)
box_classes.dtype <dtype: 'int64'>

box_class_scores.shape (19, 19)
box_class_scores.dtype <dtype: ā€˜int64ā€™>

We can see here box_classes have the wrong shape and the data type is int64. This is because the tf.math.argmax() has saved the max value index in each of the 5 filters instead of the max value probability. I am unfamiliar with Keras and I am not sure how to solve this without adding a few lines of code to this function.

Maybe I have used the functions wrong!?

{moderator edit - solution code removed}

I used the wrong tensor in tf.math.argmax(). Thank you!

I think you mean that you used the wrong tensor in the reduce_max call, but Iā€™m glad to hear that you found the solution.

4 Likes

You have the roles of arg_max and reduce_max reversed in computing box_classes and box_class_scores. arg_max is used to pick the classes, right?

Yes I reversed them because previously I was getting this output which is still 4-dimensional instead of 3-dimensional.

box_classes = tf.math.argmax(box_scores, axis=-1)
box_class_scores = tf.math.reduce_max(box_scores, axis=-1, keepdims=True)
print(f"box_class_scores.shape {box_class_scores.shape}")
print(f"box_class_scores.dtype {box_class_scores.dtype}")

box_scores.shape (19, 19, 5, 80)
box_scores.dtype <dtype: ā€˜float32ā€™>
box_class_scores.shape (19, 19, 5, 1)
box_class_scores.dtype <dtype: ā€˜float32ā€™>

Have you considered that maybe the problem is using keepdims in the way you did? Try it without that and see what happens.

I also have prints to show the shapes in my code. Hereā€™s what I get when I run the test block for that function:

box_scores.shape (19, 19, 5, 80)
box_scores.dtype <dtype: 'float32'>
box_classes.shape (19, 19, 5)
box_classes.dtype <dtype: 'int64'>
box_class_scores.shape (19, 19, 5)
box_class_scores.dtype <dtype: 'float32'>
scores[2] = 9.270486
boxes[2] = [ 4.6399336  3.2303846  4.431282  -2.202031 ]
classes[2] = 8
scores.shape = (1789,)
boxes.shape = (1789, 4)
classes.shape = (1789,)
 All tests passed!
1 Like

Yes it is working for me now, thank you so much.

Sir,what is the correct one?

Hello everyone i still get this error can @paulinpaloalto please help me?

TypeError Traceback (most recent call last)
in
4 boxes = tf.random.normal([19, 19, 5, 4], mean=1, stddev=4, seed = 1)
5 box_class_probs = tf.random.normal([19, 19, 5, 80], mean=1, stddev=4, seed = 1)
----> 6 scores, boxes, classes = yolo_filter_boxes(boxes, box_confidence, box_class_probs, threshold = 0.5)
7 print("scores[2] = " + str(scores[2].numpy()))
8 print("boxes[2] = " + str(boxes[2].numpy()))

in yolo_filter_boxes(boxes, box_confidence, box_class_probs, threshold)
36 # same dimension as box_class_scores, and be True for the boxes you want to keep (with probability >= threshold)
37 ## (ā‰ˆ 1 line)
ā€”> 38 filtering_mask = (box_class_scores >= threshold)
39 # Step 4: Apply the mask to box_class_scores, boxes and box_classes
40 ## (ā‰ˆ 3 lines)

/opt/conda/lib/python3.7/site-packages/tensorflow/python/ops/gen_math_ops.py in greater_equal(x, y, name)
4053 _result = pywrap_tfe.TFE_Py_FastPathExecute(
4054 _ctx._context_handle, tld.device_name, ā€œGreaterEqualā€, name,
ā†’ 4055 tld.op_callbacks, x, y)
4056 return _result
4057 except _core._NotOkStatusException as e:

TypeError: Cannot convert 0.5 to EagerTensor of dtype int64

That means your box_class_scores tensor has the wrong contents down in yolo_filter_boxes. A common mistake is to mix up the definition of box_classes and box_class_scores.

Did you compare your results to what I showed above:

1 Like

Thanks @paulinpaloalto yes your are right i made mistake in box_class_scores i given wrong function, i cleared the test cases , in fact i completed the whole assignment with 100/100.Thanks for the help sir

Hello @paulinpaloalto, I followed some direction from the original post above in order to figure out what might be my own mistake; however, Iā€™m still stuck.

This is what I did: box_classes = tf.math.argmax(box_scores, axis=-1)
box_class_scores = tf.math.reduce_max(box_scores, axis=-1, keepdims=False)
filtering_mask = tf.math.greater_equal(box_class_scores, threshold)

And how I applied the mask to scores: boxes = tf.boolean_mask(scores, filtering_mask)
The rest is pretty similar.
I am getting the following error:


I donā€™t actually know what I did wrong

Could you please provide an assistance.

Sorry, I figured out what was the problem, I solved it. I didnā€™t apply the mask well to boxes. I had to wear my glasses.