DeepForest icon indicating copy to clipboard operation
DeepForest copied to clipboard

Improved zoom augmentations through albumentations.

Open bw4sz opened this issue 1 year ago • 4 comments

One of the core challenges of machine learning for airborne biodiversity observation is trying to generalize across sensors and acquisition conditions. Given low data sizes, data augmentations are crucial for good generalization across resolutions, focal views and object size.

A quick search of albumentations suggests hits a few existing classes that should be useful:

https://huggingface.co/spaces/qubvel-hf/albumentations-demo?transform=Downscale

https://albumentations.ai/docs/api_reference/augmentations/crops/transforms/#albumentations.augmentations.crops.transforms.RandomSizedBBoxSafeCrop

https://huggingface.co/spaces/qubvel-hf/albumentations-demo?transform=RandomSizedBBoxSafeCrop

https://albumentations.ai/docs/api_reference/augmentations/geometric/transforms/#albumentations.augmentations.geometric.transforms.PadIfNeeded

Checklist

  • [ ] Implement augmentations in their own module, not within preprocessing. Currently lives inline https://github.com/weecology/DeepForest/blob/80cb7d80f5c51d19930205cf6b8878c7640dfa1e/deepforest/dataset.py#L35

  • [ ] Allow the user to choose the augmentations either through the config file. Careful to allow defaults to remain unchanged and sets reasonable defaults if not specified in existing config files.

  • [ ] Make a doc page showing example augmentations

Optional

  • [ ] Compare training with augmentations and without when predicting across resolutions.

bw4sz avatar Aug 07 '24 17:08 bw4sz

Hi @bw4sz, should I remove the following function from the deepforest/dataset.py?

def get_transform(augment):
    """Albumentations transformation of bounding boxs."""
    if augment:
        transform = A.Compose(
            [A.HorizontalFlip(p=0.5), ToTensorV2()],
            bbox_params=A.BboxParams(format='pascal_voc', label_fields=["category_ids"]))

    else:
        transform = A.Compose([ToTensorV2()],
                              bbox_params=A.BboxParams(format='pascal_voc',
                                                       label_fields=["category_ids"]))

    return transform

And replace it with get_augmentations?

Om-Doiphode avatar Aug 14 '24 11:08 Om-Doiphode

Sure, but i'd keep calling it transforms since that it is what it is, and the user wouldn't need to always do augmentation (validation), basically the A.compose statement with optional augmentations. maybe something like

def get_transform(augmentations=None):
    """Albumentations transformation of bounding boxes.
   Args:
        augmentations (str): Name of albumentations augmentation, e.g. "Downscale". For information see albumentations transforms (link). 
   """
  ...

Then loop through the named augmentations and generate them? Having users specify a string that finds a function is always a bit annoying, but its not too many to create if statements.

bw4sz avatar Aug 14 '24 14:08 bw4sz

Hi @bw4sz, the get_transform function will take the augmentations from the deepforest_config.yml file right? Not through the function parameter list right?

Om-Doiphode avatar Aug 15 '24 03:08 Om-Doiphode

The general philosophy is to have a config argument, and then allow the user to overwrite it specifying an arg directly.

bw4sz avatar Aug 19 '24 14:08 bw4sz