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

Image augmentation #18

Merged
merged 29 commits into from
Nov 2, 2020
Merged

Conversation

ravinkohli
Copy link
Collaborator

Added:

  1. image augmentations
  2. ImageAugmenter that aggregates the various augmentations automatically and create a sequential
  3. ImageDataLoader that can add image augmenter to transforms

@@ -67,8 +67,8 @@ def get_hyperparameter_search_space(
@staticmethod
def get_properties(dataset_properties: Optional[Dict[str, Any]] = None) -> Dict[str, str]:
return {
'shortname': 'Preprocessing',
'name': 'Preprocessing Node',
'shortname': 'EarlyPreprocessing',
Copy link
Collaborator

Choose a reason for hiding this comment

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

haha my PR and your PR will class on this change. Depending on which get merged first, this will have to be updated

" fitted yet".format(self.__class__.__name__))
return self.augmenter
#
# def check_requirements(self, X: Dict[str, Any], y: Any = None) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this commented out :D?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm sorry I had copied first in case I need requirements. As augmenter has no requirements, it is not needed but I forgot to delete

for name in available_augmenters.keys():
preprocessor_configuration_space = available_augmenters[name].\
get_hyperparameter_search_space(dataset_properties)
cs.add_configuration_space(name, preprocessor_configuration_space)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I fail to understand something -- let us say we don't want cropping for this pipeline because it hurts performance. Is there the possibility to not have cropping? Like normally I will expect a 'no cropping' or something similar. Maybe I missed something :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So, the idea is for augmenters to have a probability of being applied as a hyperparameter. According to Lucas' comments, currently there is one just for RandomCutout. But it can be added for others as well.

Copy link
Owner

Choose a reason for hiding this comment

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

I think we want a switch for the more fancy augmentations, such as use_cutout, which is what APT did before too, and then have all the hyperparameters as conditionals on that switch. I would say those would be all but flips and zero_pad_and_crop

from autoPyTorch.pipeline.components.setup.augmentation.image.ImageAugmenter import ImageAugmenter


class TestImageAugmenter(unittest.TestCase):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a test that actually takes an image and apply a transformation, to make sure it properly happen? It can be that it takes a random transformation on a manually created 1,H,W,C numpy array and when applied we make sure some change happened. This will also prevent bugs on theimplementation

@@ -32,7 +32,7 @@ def get_components() -> Dict[str, autoPyTorchMetric]:
as choices
"""
components = OrderedDict()
components.update(_encoders)
components.update(_metrics)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a checker for the addition of new metrics? like a user-defined accuracy? Doesn't have to be in this PR, but create an issue for this?

Copy link
Collaborator Author

@ravinkohli ravinkohli Oct 26, 2020

Choose a reason for hiding this comment

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

Okay, but by checker you mean a test right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes!

Copy link
Collaborator

@franchuterivera franchuterivera left a comment

Choose a reason for hiding this comment

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

I left some comments that will likely request a change. Please take a look and see if they make sense

Copy link
Owner

@LMZimmer LMZimmer left a comment

Choose a reason for hiding this comment

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

Looking good, could you also add a resize as an augmentation?

for name in available_augmenters.keys():
preprocessor_configuration_space = available_augmenters[name].\
get_hyperparameter_search_space(dataset_properties)
cs.add_configuration_space(name, preprocessor_configuration_space)
Copy link
Owner

Choose a reason for hiding this comment

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

I think we want a switch for the more fancy augmentations, such as use_cutout, which is what APT did before too, and then have all the hyperparameters as conditionals on that switch. I would say those would be all but flips and zero_pad_and_crop

requirements.txt Outdated
imgaug~=0.4.0
Copy link
Owner

Choose a reason for hiding this comment

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

Lets just put this at >=0.4

# These can apply for both train/val/test, so no
# distinction is performed

if not X['is_small_preprocess']:
Copy link
Owner

Choose a reason for hiding this comment

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

Could you add documentation what this means?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah sure

Copy link
Owner

@LMZimmer LMZimmer left a comment

Choose a reason for hiding this comment

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

Just a few comments, once these are addressed I will merge it 👍

Dict[str, BaseImageAugmenter]: all BaseImageAugmenter components available
as choices
"""
# Error in implementation of CropToFixedSize augmenter in imgaug
Copy link
Owner

Choose a reason for hiding this comment

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

Is this fixed? Then we don't need the comment anymore

translate_percent_offset = UniformFloatHyperparameter('translate_percent_offset', lower=0, upper=0.99,
default_value=0.3)
shear = UniformIntegerHyperparameter('shear', lower=0, upper=45, default_value=30)
rotate = UniformIntegerHyperparameter('rotate', lower=0, upper=360, default_value=45)
Copy link
Owner

Choose a reason for hiding this comment

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

I would simplify this as follows:

Remove scale_min, translate_percent_min and hardcode them to 0.

scale_offset = UniformFloatHyperparameter('scale_offset', lower=0, upper=0.4, default_value=0.2)
translate_percent_offset = UniformFloatHyperparameter('translate_percent_offset', lower=0, upper=0.4, default_value=0.2)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So I had made a mistake in interpreting what scale means. So, if we have scale as 1, that would mean scaled to 100% of original size(i.e, no change) else with 0.5 then 50% of the image. So I think scale offset should be 0 to 0.4(therefore scale_min) and it should go from scale_min to 1 and that should mean we scale it to anything between 60%(1-0.4) and 100%(1)

Copy link
Owner

Choose a reason for hiding this comment

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

I would expect that if you specify the scaling percentage as e.g. (0, 0.4) that the augmentation scales the images from 60 % - 140 %, which it should. Could you double check that this is done now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hey Lucas, I checked and it is that whatever number we enter, its the percentage of zooming out(if greater than 1) or zooming in(if less than 1). So if we want something like 60-140%, we could have 1 - offset and 1+offset, or we could fix the offset and learn what to use as the centre point. Let me know what you think is more appropriate.

) -> ConfigurationSpace:

cs = ConfigurationSpace()
interpolation = CategoricalHyperparameter('interpolation', choices=['nearest', 'linear', 'area', 'cubic'],
Copy link
Owner

Choose a reason for hiding this comment

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

Let's fix this to one to reduce hyperparameters

image_augmenter = image_augmenter.set_hyperparameters(configuration=configuration)
X = dict(X_train=np.random.randint(0, 255, (8, 3, 16, 16), dtype=np.uint8), image_height=16, image_width=16)
for name, augmenter in image_augmenter.available_augmenters.items():
if not augmenter.use_augmenter:
Copy link
Owner

Choose a reason for hiding this comment

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

To test every augmenter, there should be a configuration that has use_augmenter==True for all augmenters right?

@@ -10,12 +10,10 @@
class TestImageAugmenter(unittest.TestCase):
def test_every_augmenter(self):
image_augmenter = ImageAugmenter()
configuration = image_augmenter.get_hyperparameter_search_space().sample_configuration()
configuration = image_augmenter.get_hyperparameter_search_space().get_default_configuration()
Copy link
Owner

Choose a reason for hiding this comment

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

Does the default have every augmentation? I guess then this is fine, but perhaps add a comment here that this is implicitly assumed for this test

@LMZimmer LMZimmer merged commit dd6caf3 into LMZimmer:development Nov 2, 2020
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.

3 participants