Randomize augmentation in dataset class

Is it possible to randomize the augmentation in the Dataset class?

def __init__(self, subdict, num_labels, params=None, isTransform=None, isplot=None):
    """
    :param subdict: dictionary of 3D MR images e.g. ['img_sub'] = '/user/318_T1w.nii.gz'
    :param num_labels: number of segmentation labels
    """
    self.subdict = subdict
    self.num_labels = num_labels
    self.img_subs = subdict['img_subs']
    self.img_files = subdict['img_files']
    self.seg_subs = subdict['seg_subs']
    self.seg_files = subdict['seg_files']
    self.isTransfom = isTransform
    self.isplot = isplot
    self.params = params

def __getitem__(self, index):      
    sub_name = self.img_subs[index]
    if self.isTransfom:                         
        img, seg = self.imaugment(imgnp, segnp) 

def imaugment(self, X, Y):                                             
    """                                                                
    Preprocess the tuple (image, mask) and then apply if selected:      
        augmentation techniques adapted from Keras ImageDataGenerator  
        elastic deformation                                            
    """                                                                
    if Y is not None and X.shape != Y.shape:                           
        raise ValueError("image and mask should have the same size")   
    if self.params["augmentation"][0] == True:                         
        X, Y = random_transform(X, Y, **self.params["random_deform"])  
    if self.params["augmentation"][1] == True:                         
        X, Y = deform_pixel(X, Y, **self.params["e_deform_p"])         
    if self.params["augmentation"][2] == True:                         
        X, Y = deform_grid(X, Y, **self.params["e_deform_g"])          
    return X, Y                                                        

This way, I can only choose True/False, which entirely turns the augmentation on or off for the whole dataset.
What I want to augment some index/sample and not to others.

Thanks for the help.

You could use transforms.RandomApply and to randomly use the provided transformations.

Hello @ptrblck
I am using a python dictionary that has parameters for imaugment method in the data.Dataset class.
The params is as below:

    params = {}
    params["augmentation"] = [1, 1, 1]  # , 1, 1]
    params["only"] = None
    params["e_deform_p"] = dict()
    params["e_deform_g"] = dict()
    params["random_deform"] = dict()
    params["random_deform"]['height_shift_range'] = 0.1  # 0.1
    params["random_deform"]['width_shift_range'] = 0.1  # 0.1
    params["random_deform"]['depth_shift_range'] = None  # ?
    params["random_deform"]['rotation_range_alpha'] = 5
    params["random_deform"]['rotation_range_beta'] = None
    params["random_deform"]['rotation_range_gamma'] = None
    params["random_deform"]["horizontal_flip"] = True
    params["random_deform"]["vertical_flip"] = True 
    params["random_deform"]["z_flip"] = False
    # Add elastic deformations
    params["e_deform_p"]["alpha"] = 5
    params["e_deform_p"]["sigma"] = 2
    params["e_deform_g"]["sigma"] = 5  # 10
    params["e_deform_g"]["points"] = 3

I pass the params to the dataset and imaugment method is performed on image and mask.
With RandomApply as you’ve mentioned:

    transforms = transforms.RandomApply(params, p=0.3)
    dataSet = Seg_aug(train_dict, num_labels=9, params=transforms, isTransform=True, isplot=True)
    tl = DataLoader(dataSet, batch_size=10, shuffle=True, num_workers=1)
    x, y, z = next(iter(tl))

I am getting the following error:
TypeError: 'RandomApply' object is not subscriptable
Is there ways to implement imaugment based on p=0.5(50%) of the images+masks with params?

RandomApply expects a sequence or nn.ModuleList of transformations as given in the docs, while params is a dict as you’ve mentioned, so it won’t be compatible.
In case you want to use this params dict I guess you could manually apply these transformations randomly in the __getitem__ of your Dataset by sampling a random number and then applying the corresponding transformation on the data.

1 Like

Hi, @ptrblck
I could manage to randomize the transforms/augmentations from dataset with a probability input.
Thanks for the help.