-
Notifications
You must be signed in to change notification settings - Fork 330
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
frostbyte012
wants to merge
13
commits into
keras-team:master
from
frostbyte012:random_resized_crop_branch
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
bb442c9
build : Add random_resized_crop.py to implement RandomResizedCrop Layer
frostbyte012 e19e665
build : Add a new random resized crop layer for the random resizing o…
frostbyte012 56680d5
fix : Made the necessary changes for Implementing the Random Resized …
frostbyte012 113b6f7
fix : Add a subclass tf.keras.internal.layers.BaseImageAugmentationLa…
frostbyte012 a7373b8
build : Add subclass tf.keras.internal.layers.BaseImageAugmentationLayer
frostbyte012 fbf7642
fix : Use tf.random and applied get_random_transformation API from Ba…
frostbyte012 1eec92a
fix : Use augment_image instead of call for subclassing BaseImageAugm…
frostbyte012 4bf8af7
fix : use correct importing format for keras library
frostbyte012 9273df4
fix : remove obvious comments
frostbyte012 be11a7c
fix : remove the constants declared outside the class
frostbyte012 664fbf3
fix : remove the H_AXIS and W_AXIS outside the class
frostbyte012 330d4ec
Merge branch 'master' of https://github.com/frostbyte012/keras-cv int…
frostbyte012 9462864
build : a demo framework for random_resized_crop made
frostbyte012 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import tensorflow as tf | ||
from keras.layers.preprocessing import preprocessing_utils as utils | ||
from keras.utils import image_utils | ||
|
||
@tf.keras.utils.register_keras_serializable(package="keras_cv") | ||
class RandomResizedCrop(tf.keras.internal.layers.BaseImageAugmentationLayer): | ||
''' | ||
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): | ||
super().__init__(seed=seed,**kwargs) | ||
self.height = height | ||
self.width = width | ||
self.seed = seed | ||
|
||
#Method for taking the inputs | ||
def augment_image(self, inputs, training=True): | ||
frostbyte012 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inputs = utils.ensure_tensor(inputs, dtype=self.compute_dtype) | ||
if training: | ||
input_shape = tf.shape(inputs) | ||
h_diff = input_shape[-3] - self.height | ||
w_diff = input_shape[-2] - 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[-3] - self.height | ||
w_diff = input_shape[-2] - 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): | ||
self.new_height,self.new_width=self.get_random_transformation() | ||
outputs = image_utils.smart_resize(inputs, [self.new_height, self.new_width]) | ||
# 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[-3] = self.height | ||
input_shape[-2] = 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())) | ||
|
||
def get_random_transformation(self, image=None, label=None, bounding_box=None): | ||
x = self._get_shear_amount(self.height) | ||
|
||
y = self._get_shear_amount(self.width) | ||
|
||
return (x, y) | ||
|
||
def _get_shear_amount(self, constraint): | ||
if constraint is None: | ||
return None | ||
|
||
negate = tf.random_uniform((), 0, self.constraint, dtype=tf.float32) > 0.5 | ||
negate = tf.cond(negate, lambda: -1.0, lambda: 1.0) | ||
|
||
return negate * self._random_generator.random_uniform( | ||
(), constraint[0], constraint[1] | ||
) | ||
|
||
# Method for Random Resizing of the inputs | ||
def _random_resized_crop(self,inputs): | ||
return self._resize(self,self._random_crop(self,inputs)) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import tensorflow as tf | ||
|
||
from keras_cv.layers import preprocessing | ||
|
||
|
||
class RandomResizedCropTest(tf.test.TestCase): | ||
def test_aggressive_shear_fills_at_least_some_pixels(self): | ||
img_shape = (50, 50, 3) | ||
xs = tf.stack( | ||
[2 * tf.ones(img_shape), tf.ones(img_shape)], | ||
axis=0, | ||
) | ||
xs = tf.cast(xs, tf.float32) | ||
|
||
fill_value = 0.0 | ||
layer = preprocessing.RandomResizedCrop( | ||
height=3, width=5, seed=0) | ||
xs = layer(xs) | ||
|
||
# Some pixels should be replaced with fill value | ||
self.assertTrue(tf.math.reduce_any(xs[0] == fill_value)) | ||
self.assertTrue(tf.math.reduce_any(xs[0] == 2.0)) | ||
self.assertTrue(tf.math.reduce_any(xs[1] == fill_value)) | ||
self.assertTrue(tf.math.reduce_any(xs[1] == 1.0)) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be
__internal__
.