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

Converted to keras core external attention #529

Merged

Conversation

anas-rz
Copy link
Contributor

@anas-rz anas-rz commented Jul 18, 2023

Update imports
Remove TensorFlow Addons Dependency
Convert TensorFlow ops in functional component to keras_core ops

Attached git-diff
Colab Notebook
eanet_keras_core.diff.txt

@google-cla
Copy link

google-cla bot commented Jul 18, 2023

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Contributor

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

"""
## Setup
"""
import keras_core as keras
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the example is TF-only, start by setting the backend using os


def call(self, images):
batch_size = tf.shape(images)[0]
patches = tf.image.extract_patches(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every TF call except this one can be converted to ops. This will make the example less TF dependent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe extract patches can be implemented by a convolution, no? It's a convolution with identity kernel. Maybe we could do that and make the example backend-agnostic.

Alternatively, maybe we can add a cross-backend extract_patches function in ops.image (implemented using convolution for other backends). Actually, this is a better solution, since this method comes up a lot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can create a PR for it.
Another workaround: For this example can I use frameworks like einops for creating patches?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using a conv.

@anas-rz anas-rz requested a review from fchollet July 20, 2023 14:58
@anas-rz
Copy link
Contributor Author

anas-rz commented Jul 20, 2023

I have found this easy way to extract patches. Can you please elaborate/refer some example of using conv. As far as I understand, conv uses reduce sum of a filter. Is there any 'do nothing' filter for convolution that can be used for upsampling?

@fchollet
Copy link
Contributor

Your way is fine. Conv is likely faster on GPU though. It could be worth trying both if we add the op to the API (just for this example we can keep your way since it's concise).

Is there any 'do nothing' filter for convolution that can be used for upsampling?

"Do nothing" is just an identity kernel. There is no "sum" operation, it's a matmul. It turns into a sum if your kernel is all ones.

@anas-rz
Copy link
Contributor Author

anas-rz commented Jul 22, 2023

Here's the initial 'code' version I have got for extracting patches and it is working. Thank you for guidance. Will create a PR for adding this to cross-backend ops.

import tensorflow as tf
input_image = tf.random.uniform((1, 224, 224, 3))
patch_h, patch_w = 14, 14
channels_in = 3
out_dim = 588
kernel = tf.eye(patch_h * patch_w * channels_in, out_dim)
kernel = tf.reshape(kernel, (14, 14, 3, 588))
out_conv_layer = tf.nn.conv2d(input_image, kernel, 14, 'VALID')
out_tf = tf.image.extract_patches(input_image, [1, 14, 14, 1], [1, 14, 14, 1], [1, 1, 1, 1], "VALID")
check = tf.equal(out_conv_layer, out_tf)
print(np.unique(check))```

@fchollet
Copy link
Contributor

Thanks! extract_patches will be a great addition to the ops.image API.

Should we wait for this feature before revisiting this example?

@anas-rz
Copy link
Contributor Author

anas-rz commented Jul 22, 2023

Sure. That'll be better.

@anas-rz anas-rz changed the title Converted to keras core external attention Converted to keras core patch extraction Jul 22, 2023
@anas-rz anas-rz changed the title Converted to keras core patch extraction Converted to keras core external attention Jul 22, 2023
Copy link
Contributor

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@fchollet fchollet merged commit 3c90346 into keras-team:main Jul 24, 2023
@anas-rz anas-rz deleted the Converted-to-Keras-Core-external_attention branch July 24, 2023 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants