-
Notifications
You must be signed in to change notification settings - Fork 74k
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
Inconsistant behavior of Conv2D between eager mode and tracing #57664
Comments
@Co1lin Thank you! |
Hi! Thanks for the reply! Although I used keras, the issue seems to be in the tracing part of TensorFlow. Because I can get the same issue without keras by the following code. import tensorflow as tf
class MyModule(tf.Module):
def __init__(self):
self.kernel = tf.random.normal((2,2,2,1))
@tf.function
def __call__(self, x):
return tf.raw_ops.Conv2D(input=x, filter=self.kernel, strides=[1,1,1,1], padding='VALID')
if __name__ == '__main__':
model = MyModule()
tf.config.run_functions_eagerly(True)
x = tf.random.normal([2, 1, 2, 2])
print(model(x)) # tf.Tensor([], shape=(2, 0, 1, 1), dtype=float32)
tf.config.run_functions_eagerly(False)
x = tf.random.normal([2, 1, 2, 2])
print(model(x)) # ValueError when tracing
model.__call__.get_concrete_function(x) # Same error if we call this instead of the last line Raising this ValueError in tracing / graph execution mode may be reasonable, but I think the behavior of eager running should be the same. |
@tiruk007 I know if we use |
If you remove the tf.function when you use run_functions_eagerly(False), both tracing produces the same result. Below is the modified code and the output.
|
This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Thank you. |
Closing as stale. Please reopen if you'd like to work on this further. |
Hi @sachinprasadhs ! I understand I can use the workaround for this inconsistency, but for development, I think whether setting running functions eagerly or not should have consistent and expected behaviors because it's better to let the graph execution mode work the same as the eager mode, so that it's transparent for users. In this case, it's quite common to add import tensorflow as tf
class MyModule(tf.Module):
def __init__(self):
self.kernel = tf.random.normal((2,2,2,1))
@tf.function
def __call__(self, x):
print(f'{tf.config.functions_run_eagerly() = }') # False
return tf.raw_ops.Conv2D(input=x, filter=self.kernel, strides=[1,1,1,1], padding='VALID')
if __name__ == '__main__':
model = MyModule()
x = tf.random.normal([2, 1, 2, 2])
print(model(x)) # ValueError But this will throw the In short, I think the two modes should have the same behavior, so please reopen this issue, and I'm sorry for the late reply. |
This is likely because we do shape inference in graph mode (but not eager mode), which is attempting to compute the output shape, catching the negative dimension, and sending the error. In eager mode, we skip shape inference and jump straight to the kernel, which was written generically to handle empty outputs. We could either change the shape inference function to produce an empty tensor instead of erroring on negative output shape, or we can change the kernel to check the shape and throw the same error as the shape inference function. My preference is probably the first option. But then we need to ensure all backends/devices (XLA, CPU, GPU, oneDNN) can consistently handle empty outputs. |
Click to expand!
Issue Type
Bug
Source
binary
Tensorflow Version
2.11.0-dev20220910
Custom Code
No
OS Platform and Distribution
No response
Mobile device
No response
Python version
No response
Bazel version
No response
GCC/Compiler version
No response
CUDA/cuDNN version
No response
GPU model and memory
No response
Current Behaviour?
If the input to Conv2D is too small, in graph execution mode, a ValueError will be raised when tracing. However, if we only use eager mode to run, it will output a tensor with dim = 0. So there's an inconsistency under two modes.
If we only create a conv layer and directly use it to compute something, it works well as the eager mode.
I think the behavior should be consistent in all modes.
Standalone code to reproduce the issue
Relevant log output
The text was updated successfully, but these errors were encountered: