Albumentation transformations for train and test dataset

Hi!
I am trying to port my training pipeline to fast.ai , where i use albumentation transformations.
Here’s my problem:
I have two data augmentation pipelines in albumentations

train_augs = A.Compose([ ... ]) # for train dataset
valid_augs = A.Compose([ ... ]) # for valid dataset

train_augs contain RandomResizedCrop, {other transformations}, Normalization and ToTensorV2 albumentations transformations.
valid_augs contain Resize, Normalization and ToTensorV2 albumentations transformations.

Let’s say the create the pipeline given below :

class AlbumentationsTransform(Transform):
    def __init__(self, aug): self.aug = aug
    def encodes(self, img: PILImage):
        aug_img = self.aug(image=np.array(img))['image']
        return PILImage.create(aug_img)

# assume i am creating a datablock from a pandas dataframe stored in df
def get_x: ...
def get_y: ...

tfm = AlbumentationsTransform(tfm)

dblock = DataBlock(blocks=(ImageBlock, CategoryBlock), 
                   splitter=ColSplitter(),
                   get_x=get_x,
                   get_y=get_y,
                   item_tfms=[RandomResizedCrop(size=(320, 320)), tfm])

dls = dblock.dataloaders(df)

So, my questions are these:

  • Will the transformation applied to the data be same as the ones splecified in the train_augs and valid_augs ?
  • If i am not wrong tfm will only be applied to the train data. For the valid data will RandomResizedCrop or Resize will applied ?
  • How would i go about if I wan to apply RandomResizedCrop to train data and Resize to validation data in the above pipeline ?

Thanks …

I actually just did this today :slight_smile: here’s the solution:

class AlbumentationsTransform(RandTransform):
    split_idx,order=None,2
    def __init__(self, train_aug, valid_aug): store_attr()
    
    def before_call(self, b, split_idx):
        self.idx = split_idx
    
    def encodes(self, img: PILImage):
        if self.idx == 0:
            aug_img = self.train_aug(image=np.array(img))['image']
        else:
            aug_img = self.valid_aug(image=np.array(img))['image']
        return PILImage.create(aug_img)

train_aug and valid_aug should be composed albumentation transforms

1 Like

A few key notes: normalize with fastai, not albumentations. We rely on getting back a PILImage so anything that adjusts the data values to a float shouldn’t be done here

So, this should go to item_tfms then. And also if i have resize augments in the albumentations pipeline i belive i dont have to call fast.ai Resize separetely ?

That is entirely correct. Here is a complete and valid pipeline I’ve trained with:

def get_train_aug(): return albumentations.Compose([
            albumentations.RandomResizedCrop(256,256),
            albumentations.Transpose(p=0.5),
            albumentations.HorizontalFlip(p=0.5),
            albumentations.VerticalFlip(p=0.5),
            albumentations.ShiftScaleRotate(p=0.5),
            albumentations.HueSaturationValue(
                hue_shift_limit=0.2, 
                sat_shift_limit=0.2, 
                val_shift_limit=0.2, 
                p=0.5
            ),
            albumentations.RandomBrightnessContrast(
                brightness_limit=(-0.1,0.1), 
                contrast_limit=(-0.1, 0.1), 
                p=0.5
            ),
            albumentations.CoarseDropout(p=0.5),
            albumentations.Cutout(p=0.5)
])

def get_valid_aug(): return albumentations.Compose([
    albumentations.CenterCrop(256,256, p=1.),
    albumentations.Resize(256,256)
], p=1.)

item_tfms = AlbumentationsTransform(get_train_aug(), get_valid_aug())

batch_tfms = [Normalize.from_stats(*imagenet_stats)]
4 Likes

This helped a lot … :blush::blush:
Thank you so much !
Exactly what i was looking for

Hey, thanks for sharing! :slight_smile:
Are the hue/sat/val shift_limits in percent you specify? is 0.2 equal to 20%? - I was confused when I wanted to apply a change e.g. to hue in a range of .95-1.05 based on a uniform distribution (being equal to 95%-105%).

On the albumentations website they have hue_shift_limits with integers…