Randomize augmentation in dataset class

username: banikr
cooked: <p>Is it possible to randomize the augmentation in the <code>Dataset</code> class?</p>
<pre><code class="lang-auto">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                                                        
</code></pre>
<p>This way, I can only choose True/False, which entirely turns the augmentation on or off for the whole dataset.<br>
What I want to augment some index/sample and not to others.</p>
<p>Thanks for the help.</p>

username: ptrblck
cooked: <p>You could use <a href="https://pytorch.org/vision/stable/transforms.html#torchvision.transforms.RandomApply"><code>transforms.RandomApply</code></a> and to randomly use the provided transformations.</p>

username: banikr
cooked: <p>Hello <a class="mention" href="/u/ptrblck">@ptrblck</a><br>
I am using a python dictionary that has parameters for <code>imaugment</code> method in the <code>data.Dataset</code> class.<br>
The <code>params</code> is as below:</p>
<pre><code class="lang-auto">    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
</code></pre>
<p>I pass the params to the dataset and <code>imaugment</code> method is performed on image and mask.<br>
With <code>RandomApply</code> as you’ve mentioned:</p>
<pre><code class="lang-auto">    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))
</code></pre>
<p>I am getting the following error:<br>
<code>TypeError: 'RandomApply' object is not subscriptable</code><br>
Is there ways to implement imaugment based on p=0.5(50%) of the images+masks with params?</p>

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

username: banikr
cooked: <p>Hi, <a class="mention" href="/u/ptrblck">@ptrblck</a><br>
I could manage to randomize the transforms/augmentations from dataset with a probability input.<br>
Thanks for the help.</p>