Data augmentation (transferring to different locations)

username: Niki
cooked: <p>Hi, I am looking for applying data augmentation on CIFAR-10, in the way that each image takes different places, let’s say one in the right corner top, another one in the left corner bottom, … I am not sure this is a correct approach, first creating a box around each image by using padding then start transferring images there? I wonder using <code>transforms.RandomAffine</code> is okay for transferring in this way? if so why “translate”, option in that, has to be between 0 and 1?</p>
<p>Thank you,</p>

username: ptrblck
cooked: <p>Would you like to crop the input image at these different positions?<br>
If so, <a href="https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.FiveCrop">torchvsion.transforms.FiveCrop</a> (or <code>TenCrop</code>) might be usable.</p>
<p>The <code>translate</code> argument is defined as:</p>
<blockquote>
<p><strong>translate</strong>  ( <em>tuple</em> <em>,</em>  <em>optional</em> ) – tuple of maximum absolute fraction for horizontal and vertical translations. For example translate=(a, b), then horizontal shift is randomly sampled in the range -img_width * a &lt; dx &lt; img_width * a and vertical shift is randomly sampled in the range -img_height * b &lt; dy &lt; img_height * b. Will not translate by default.</p>
</blockquote>
<p>which means it’s used as the relative translation using the image width and height.</p>

username: Niki
cooked: <aside class="quote no-group" data-username="ptrblck" data-post="2" data-topic="66988">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p><a href="https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.FiveCrop" rel="noopener nofollow ugc">torchvsion.transforms.FiveCrop</a></p>
</blockquote>
</aside>
<p>Thank you for your response, <a class="mention" href="/u/ptrblck">@ptrblck</a>.</p>
<p>To make sure that I understand it properly, you mean replacing</p>
<pre><code class="lang-auto">transform_train = transforms.Compose([
            transforms.RandomCrop(32, padding=4),        
            transforms.RandomRotation(15),              
            transforms.RandomHorizontalFlip(),           
            transforms.ToTensor(),                     
            normalize_transform,                          
        ])
</code></pre>
<p>with</p>
<pre><code class="lang-auto">transform_train = transforms.Compose([
            transforms.FiveCrop (40),
            transforms.Lambda(lambda crops: torch.stack([ToTensor()(crop) for crop in crops])) 
            transforms.RandomRotation(15),              
            transforms.RandomHorizontalFlip(),           
            normalize_transform,                          
        ])
</code></pre>
<p>and model(input) in training procedure should be changed to:</p>
<pre><code class="lang-auto">result = model(input.view(-1, c=3, h=40, w=40)) # fuse batch size and ncrops
result_avg = result.view(bs=128, ncrops=5, -1).mean(1) # avg over crops
</code></pre>
<p>and the result_avg will be used for calculating loss function, prediction?</p>
<p>This generates extra data to train in different locations, and the size should be increased for that (let say from 32 to 40) to see some difference?</p>

username: ptrblck
cooked: <p>I think your new transformation won’t work, as you are trying to apply image transformations (e.g. <code>RandomRotation</code>) on tensors.</p>
<p>Instead you could apply <code>FiveCrop</code>, loop over each cropped image, and apply the rotation to it.</p>
<p>I’m not sure what size you are referring to in the last sentence. CIFAR-10 images have a spatial size of <code>32x32</code>. You could of course pad them to <code>40x40</code> and check, if that helps.</p>

username: Niki
cooked: <p>Thank you, <a class="mention" href="/u/ptrblck">@ptrblck</a>.</p>