Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Equality operator not overloaded #9359

Closed
carlthome opened this issue Apr 21, 2017 · 18 comments

Comments

Projects
None yet
10 participants
@carlthome
Copy link
Contributor

commented Apr 21, 2017

It's unexpected and a gotcha that some comparison operators (>, <, <=, =>) are overloaded but not all (==, !=). Is there a particular reason for this? I think either all standard operators should be overloaded, or none at all.

In [1]: import tensorflow as tf

In [2]: tensor = tf.zeros((3,5))

In [3]: tensor > 0
Out[3]: <tf.Tensor 'Greater:0' shape=(3, 5) dtype=bool>

In [4]: tensor == 0
Out[4]: False

This is on TensorFlow 1.1.0rc2.

@drpngx

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2017

I think the reason is that we thought it might be confusing to have statements like if foo, which check for None.

@aselle may have some comment.

@carlthome

This comment has been minimized.

Copy link
Contributor Author

commented Apr 23, 2017

Surely for those cases it would be better with the less ambiguous if foo is None:

@drpngx

This comment has been minimized.

Copy link
Contributor

commented Apr 23, 2017

The google style guide mandates implicit comparisons, but not for integers. A lot of code has been written that way.

Whatever the case, reading the description again, it looks to me that case 4 doesn't make sense in the current state no matter what.

@shoyer

This comment has been minimized.

Copy link
Member

commented Apr 23, 2017

This may be a complication of fact that tensors can be used as keys in dictionaries, which I believe use == to find the matching object with the same hash:
https://docs.python.org/2/reference/datamodel.html#object.__hash__

if foo actually calls bool(foo) -> foo.__bool__(), so that's something different.

@gunan

This comment has been minimized.

Copy link
Member

commented Jun 16, 2017

Automatically closing due to lack of recent activity. Please update the issue when new information becomes available, and we will reopen the issue. Thanks!

@gunan gunan closed this Jun 16, 2017

@twangnh

This comment has been minimized.

Copy link

commented Feb 20, 2018

but how would you suggest to write the code if we want == operator?

@carlthome

This comment has been minimized.

Copy link
Contributor Author

commented Feb 20, 2018

tf.equal I guess? I wish this was reopened though.

@gunan

This comment has been minimized.

Copy link
Member

commented Feb 21, 2018

@alextp @josh11b @drpngx to check and see if we would like to reopen this. But it has been almost one year with no activity, so it seems to be very low priority.

@carlthome

This comment has been minimized.

Copy link
Contributor Author

commented Feb 21, 2018

I've seen several bugs caused by this inconsistency. I even managed to be tripped up by this myself just last week, and I would not be surprised if these bugs are very common across people's experiments, where the Python expression always evaluates to False and an implicit tf.convert_to_tensor on the expression just becomes a runtime constant.

@alextp

This comment has been minimized.

Copy link
Member

commented Feb 21, 2018

We cannot override == and != because that would make tensors no longer work as dictionary keys, which would break a lot of internal and external code :-/

@shoyer

This comment has been minimized.

Copy link
Member

commented Feb 21, 2018

Agreed with @alextp, this is unfortunately a non-starter.

The most obvious use of tensors as dictionary keys is placeholders in feed_dict.

@karandwivedi42

This comment has been minimized.

Copy link

commented Apr 4, 2018

I just spent more than an hour debugging this. :/

Strongly agree that the inconsistency is misleading (I saw some code with a <= b and modified it with a==b and always got 0).

@carlthome

This comment has been minimized.

Copy link
Contributor Author

commented Apr 5, 2018

This is an extremely tricky wart.

For TensorFlow 2.0 maybe tensors could stop being hashable and instead users would have to explicitly call e.g. tf.constant(9).hashable()? That would free up == and != for the expected use as overloaded operators for graph construction.

That's unfortunately the best I could come up with.

x = tf.placeholder(...)
feed_dict = {x.hashable(): np.array(...)}
@jeromerg

This comment has been minimized.

Copy link

commented Nov 7, 2018

Would it be possible to at least produce a warning?

@alextp

This comment has been minimized.

Copy link
Member

commented Nov 7, 2018

If we add a warning it'll trigger all the time for innocuous code since TF internally uses hash tables keyed by tensors in many places :-/

@elmirador

This comment has been minimized.

Copy link

commented Feb 26, 2019

Stumbled upon this issue when I found out tensor_x == 0 returns a False...
Well, here goes my time :(
Can't we at least warn people about the operator's inconsistent behavior? Maybe somewhere in the doc, suggest them to use tf functions instead.

@carlthome

This comment has been minimized.

Copy link
Contributor Author

commented Feb 26, 2019

It's String comparisons in Java all over again. 😟

@josh11b

This comment has been minimized.

Copy link
Member

commented Feb 26, 2019

We have recently been looking at this and been trying things to work around the hashable issue, but we haven't found anything that doesn't break a lot of code. In addition to the hashing issue, I've also seen problems with code like:

tensorflow/python/ops/embedding_ops.py, line 117, in _embedding_lookup_and_transform
if params is None or params in ((), []):

which is relying on Tensor.eq being the same as "is" when params is a Tensor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.