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

Introduces a Random resized crop layer #203

Closed
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions keras_cv/layers/preprocessing/random_resized_crop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from keras import backend
Copy link
Contributor

Choose a reason for hiding this comment

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

lets also add a script to examples showing the outputs of this layer. Lets base it on the color degeneration example:

https://github.com/keras-team/keras-cv/blob/master/examples/layers/preprocessing/random_color_degeneration_demo.py

from keras.engine import base_layer
from keras.engine import base_preprocessing_layer
from keras.layers.preprocessing import preprocessing_utils as utils
from keras.utils import image_utils
from keras.utils import tf_utils
import numpy as np
import tensorflow as tf
from tensorflow.python.util.tf_export import keras_export
from tensorflow.tools.docs import doc_controls
Copy link
Contributor

Choose a reason for hiding this comment

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

@frostbyte012

  • keras should be imported from tensorflow, for example: from tensorflow.keras import ....
  • remove not-used packages, for ex. keras_export.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed! Thanks @innat

Copy link
Author

Choose a reason for hiding this comment

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

Sure @LukeWood and @innat sir! I'm removing the unwanted packages and also adding the correct format for keras import .


H_AXIS = -3
W_AXIS = -2


class RandomResizedCrop(base_layer.Layer):
Copy link
Contributor

Choose a reason for hiding this comment

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

lets subclass tf.keras.internal.layers.BaseImageAugmentationLayer instead of base_layer.Layer.

Check out
https://github.com/keras-team/keras-cv/blob/master/keras_cv/layers/preprocessing/random_shear.py

Copy link
Author

Choose a reason for hiding this comment

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

Done : Added a subclass tf.keras.internal.layers.BaseImageAugmentation.Layer in place of base_layer.Layer

'''
This layer is used to
Crop a random portion of image and resize it to a given size.
A crop of the original image is made: the crop has a random area (H * W) and a random aspect ratio.
This crop is finally resized to the given size.
This is popularly used to train the Inception networks.
'''

def __init__(self, height, width, seed=None, **kwargs):
base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomCrop').set(True)
LukeWood marked this conversation as resolved.
Show resolved Hide resolved
super(RandomResizedCrop, self).__init__(**kwargs, autocast=False, seed=seed,
LukeWood marked this conversation as resolved.
Show resolved Hide resolved
force_generator=True)
# Attribute to crop image
self.height = height
# Attribute to take the custom height
self.width = width
# Attribute to take the custom width
self.seed = seed
# Attribute to take random seed
Copy link
Contributor

Choose a reason for hiding this comment

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

It may not be needed to give obvious comments.


#Methoid for taking the inputs
def call(self, inputs, training=True):
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll need to override augment_image instead of call when subclassing BaseImageAugmentationLayer

Copy link
Author

Choose a reason for hiding this comment

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

sure sir working on it Asap!

Copy link
Author

@frostbyte012 frostbyte012 Apr 22, 2022

Choose a reason for hiding this comment

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

Done: Resolved it and applied augment_image

Copy link
Author

Choose a reason for hiding this comment

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

@LukeWood sir is the last commit all, correct? If not please let me know about it! Waiting to make the necessary changes. if required.

inputs = utils.ensure_tensor(inputs, dtype=self.compute_dtype)
if training:
input_shape = tf.shape(inputs)
h_diff = input_shape[H_AXIS] - self.height
w_diff = input_shape[W_AXIS] - self.width
return tf.cond(
tf.reduce_all((h_diff >= 0, w_diff >= 0)),
lambda: self._random_crop(inputs),
lambda: self._resize(inputs))
else:
return self._resize(inputs)

#Method for the random crop
def _random_crop(self, inputs):
input_shape = tf.shape(inputs)
h_diff = input_shape[H_AXIS] - self.height
w_diff = input_shape[W_AXIS] - self.width
dtype = input_shape.dtype
rands = self._random_generator.random_uniform([2], 0, dtype.max, dtype)
h_start = rands[0] % (h_diff + 1)
w_start = rands[1] % (w_diff + 1)
return tf.image.crop_to_bounding_box(inputs, h_start, w_start,
self.height, self.width)

# method for resizing the images
def _resize(self, inputs):
outputs = image_utils.smart_resize(inputs, [self.height, self.width])
Copy link
Contributor

Choose a reason for hiding this comment

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

This will perform the same resize on all images

Copy link
Author

@frostbyte012 frostbyte012 Mar 27, 2022

Choose a reason for hiding this comment

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

Done : called on import random
and used it to randomly resize height and width of these images, for further implementation of random crop.

# smart_resize will always output float32, so we need to re-cast.
return tf.cast(outputs, self.compute_dtype)

# Method for computing the output shape
def compute_output_shape(self, input_shape):
input_shape = tf.TensorShape(input_shape).as_list()
input_shape[H_AXIS] = self.height
input_shape[W_AXIS] = self.width
return tf.TensorShape(input_shape)

#Configuration Method
def get_config(self):
config = {
'height': self.height,
'width': self.width,
'seed': self.seed,
}
base_config = super(RandomResizedCrop, self).get_config()
return dict(list(base_config.items()) + list(config.items()))

# Method for Random Resizing of the inputs
def _random_resized_crop(self,inputs):
return self._resize(self,self._random_crop(self,inputs))