# Why isn't RandomCrop inserting the padding in pytorch?

**URL:** <https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244>\
**Category:** vision\
**Created:** [November 17, 2022, 8:57pm UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244 "2022-11-17T20:57:46Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brando\_Miranda](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/brando_miranda/32/14355_2.png) [@Brando\_Miranda](https://discuss.pytorch.org/u/Brando_Miranda)\
**Post date:** [November 17, 2022, 8:57pm UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/1 "2022-11-17T20:57:46Z")

</div>

I am getting odd images despite printing the transform the data is using:

```auto
-- splits[i]='train'
taskset=<learn2learn.data.task_dataset.TaskDataset object at 0x7fbc38345880>
taskset.dataset.dataset.datasets[0].dataset.transform=Compose(
    ToPILImage()
    RandomCrop(size=(84, 84), padding=8)
    ColorJitter(brightness=[0.6, 1.4], contrast=[0.6, 1.4], saturation=[0.6, 1.4], hue=None)
    RandomHorizontalFlip(p=0.5)
    ToTensor()
    Normalize(mean=[0.47214064400000005, 0.45330829125490196, 0.4099612805098039], std=[0.2771838538039216, 0.26775040952941176, 0.28449041290196075])
)

```

but the padding is missing:  
[![enter image description here](https://i.stack.imgur.com/Pqb4B.png)](https://i.stack.imgur.com/Pqb4B.png)

but when I use this instead:

```auto
    train_data_transform = Compose([
        RandomResizedCrop((size - padding*2, size - padding*2), scale=scale, ratio=ratio),
        Pad(padding=padding),
        ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),
        RandomHorizontalFlip(),
        ToTensor(),
        Normalize(mean=mean, std=std),
    ])

```

it seems to work:  
[![enter image description here](https://i.stack.imgur.com/U5Gcw.png)](https://i.stack.imgur.com/U5Gcw.png)  
why don’t **both** have the 8 and 8 padding on both sides I expect?

* * *

cross:

- [Do we really need mini-imagenet padding to be 8? What just having it be 84 without the 8? · Issue #376 · learnables/learn2learn · GitHub](https://github.com/learnables/learn2learn/issues/376)

- [machine learning - Why isn't RandomCrop inserting the padding in pytorch? - Stack Overflow](https://stackoverflow.com/questions/74482017/why-isnt-randomcrop-inserting-the-padding-in-pytorch)

---

<div class="post-metadata">

**Author:** ![Brando\_Miranda](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/brando_miranda/32/14355_2.png) [@Brando\_Miranda](https://discuss.pytorch.org/u/Brando_Miranda)\
**Post date:** [November 18, 2022, 1:02am UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/2 "2022-11-18T01:02:23Z")

</div>

I think this is a bug in pytorch: [Padding for RandomCrop does not match description in documentation · Issue #89253 · pytorch/pytorch · GitHub](https://github.com/pytorch/pytorch/issues/89253)

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [November 18, 2022, 5:58am UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/3 "2022-11-18T05:58:43Z")

</div>

Answered on [GitHib](https://github.com/pytorch/pytorch/issues/89253#issuecomment-1319583306): it’s expected to see the padding in on corner/edge since the padding is applied before the tensor/image is cropped as seen [here](https://github.com/pytorch/vision/blob/d710f3d1edc06afa244468cb96603ba6dbd4d9d5/torchvision/transforms/transforms.py#L664-L675).

---

<div class="post-metadata">

**Author:** ![Brando\_Miranda](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/brando_miranda/32/14355_2.png) [@Brando\_Miranda](https://discuss.pytorch.org/u/Brando_Miranda)\
**Post date:** [November 19, 2022, 12:27am UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/4 "2022-11-19T00:27:17Z")

</div>

Docs are super confusing

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [November 19, 2022, 12:46am UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/5 "2022-11-19T00:46:08Z")

</div>

I don’t think the docs are confusing and explain which operations are applied as described here:

> <https://github.com/pytorch/pytorch/issues/89253#issuecomment-1320708337>
>
> \### 🐛 Describe the bug
> 
> RandomCrop does not behave as expected. It should add …padding to all sides according to the docs but only puts it at the bottom:
> 
> I discovered & confirmed that by doing it on cifar. But note this NOT what \[the docs say for RandomCrop\](https://pytorch.org/vision/stable/generated/torchvision.transforms.RandomCrop.html):
> \> Optional padding on each border of the image. Default is None. If a single int is provided this is used to pad all borders.
> 
> it says something very similar \[to pad\](https://pytorch.org/vision/main/generated/torchvision.transforms.Pad.html#torchvision.transforms.Pad):
> \> Padding on each border. If a single int is provided this is used to pad all borders.
> 
> \`\`\`
> def check\_padding\_random\_crop\_cifar\_pure\_torch():
> # -
> import sys
> print(f'python version: {sys.version=}')
> import torch
> print(f'{torch.\_\_version\_\_=}')
> # -
> from uutils.plot.image\_visualization import visualize\_pytorch\_tensor\_img
> from torchvision.transforms import RandomCrop
> 
> # - for determinism
> import random
> random.seed(0)
> import torch
> torch.manual\_seed(0)
> import numpy as np
> np.random.seed(0)
> 
> # -
> from pathlib import Path
> root = Path('~/data/').expanduser()
> import torch
> import torchvision
> # - test tensor imgs
> from torchvision.transforms import Resize
> from torchvision.transforms import Pad
> from torchvision.transforms import ToTensor
> from torchvision.transforms import Compose
> 
> # -- see if pad doubles length
> print(f'--- test padding doubles length with Pad(...)')
> transform = Compose(\[Resize((32, 32)), Pad(padding=4), ToTensor()\])
> train = torchvision.datasets.CIFAR100(root=root, train=True, download=True,
> transform=transform,
> target\_transform=lambda data: torch.tensor(data, dtype=torch.long))
> transform = Compose(\[Resize((32, 32)), Pad(padding=8), ToTensor()\])
> test = torchvision.datasets.CIFAR100(root=root, train=True, download=True,
> transform=transform,
> target\_transform=lambda data: torch.tensor(data, dtype=torch.long))
> # - test padding doubles length
> from torch.utils.data import DataLoader
> loader = DataLoader(train)
> x, y = next(iter(loader))
> print(f'{x\[0\].size()=}')
> assert x\[0\].size(2) == 32 + 4 \* 2
> assert x\[0\].size(2) == 32 + 8
> visualize\_pytorch\_tensor\_img(x\[0\], show\_img\_now=True)
> #
> loader = DataLoader(test)
> x, y = next(iter(loader))
> print(f'{x\[0\].size()=}')
> assert x.size(2) == 32 + 8 \* 2
> assert x.size(2) == 32 + 16
> visualize\_pytorch\_tensor\_img(x\[0\], show\_img\_now=True)
> 
> # -- see if RandomCrop also puts the pad
> print(f'--- test RandomCrop indeed puts padding')
> transform = Compose(\[Resize((32, 32)), RandomCrop(28, padding=8), ToTensor()\])
> train = torchvision.datasets.CIFAR100(root=root, train=True, download=True,
> transform=transform,
> target\_transform=lambda data: torch.tensor(data, dtype=torch.long))
> transform = Compose(\[Resize((32, 32)), RandomCrop(28), ToTensor()\])
> test = torchvision.datasets.CIFAR100(root=root, train=True, download=True,
> transform=transform,
> target\_transform=lambda data: torch.tensor(data, dtype=torch.long))
> # - test that the padding is there visually
> from torch.utils.data import DataLoader
> loader = DataLoader(train)
> x, y = next(iter(loader))
> print(f'{x\[0\].size()=}')
> assert x\[0\].size(2) == 28
> visualize\_pytorch\_tensor\_img(x\[0\], show\_img\_now=True)
> #
> loader = DataLoader(test)
> x, y = next(iter(loader))
> print(f'{x\[0\].size()=}')
> assert x.size(2) == 28
> visualize\_pytorch\_tensor\_img(x\[0\], show\_img\_now=True
> \`\`\`
> 
> \### Versions
> 
> \`\`\`
> (meta\_learning) brandomiranda~/diversity-for-predictive-success-of-meta-learning ❯ wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect\_env.py
> \# For security purposes, please check the contents of collect\_env.py before running it.
> python collect\_env.py
> \--2022-11-17 17:00:22-- https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect\_env.py
> Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ...
> Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
> HTTP request sent, awaiting response... 200 OK
> Length: 17278 (17K) \[text/plain\]
> Saving to: ‘collect\_env.py’
> 
> collect\_env.py 100%\[=======================================================================================================================================================================================================================================================================================================================================\>\] 16.87K --.-KB/s in 0s      
> 
> 2022-11-17 17:00:23 (48.3 MB/s) - ‘collect\_env.py’ saved \[17278/17278\]
> 
> zsh: command not found: #
> Collecting environment information...
> PyTorch version: 1.9.1
> Is debug build: False
> CUDA used to build PyTorch: None
> ROCM used to build PyTorch: N/A
> 
> OS: macOS 12.6 (x86\_64)
> GCC version: Could not collect
> Clang version: 14.0.0 (clang-1400.0.29.102)
> CMake version: Could not collect
> Libc version: N/A
> 
> Python version: 3.9.7 (default, Sep 16 2021, 08:50:36) \[Clang 10.0.0 \] (64-bit runtime)
> Python platform: macOS-10.16-x86\_64-i386-64bit
> Is CUDA available: False
> CUDA runtime version: No CUDA
> CUDA\_MODULE\_LOADING set to: N/A
> GPU models and configuration: No CUDA
> Nvidia driver version: No CUDA
> cuDNN version: No CUDA
> HIP runtime version: N/A
> MIOpen runtime version: N/A
> Is XNNPACK available: True
> 
> Versions of relevant libraries:
> \[pip3\] numpy==1.23.1
> \[pip3\] pytorch-transformers==1.2.0
> \[pip3\] torch==1.9.1
> \[pip3\] torchaudio==0.12.1
> \[pip3\] torchmeta==1.8.0
> \[pip3\] torchtext==0.13.1
> \[pip3\] torchvision==0.10.1
> \[conda\] mkl 2021.4.0 hecd8cb5\_637  
> \[conda\] mkl-service 2.4.0 py39h9ed2024\_0  
> \[conda\] nomkl 3.0 0  
> \[conda\] numpy 1.21.4 pypi\_0 pypi
> \[conda\] numpy-base 1.23.1 py39hbda7086\_0  
> \[conda\] pytorch-transformers 1.2.0 pypi\_0 pypi
> \[conda\] torch 1.9.1 pypi\_0 pypi
> \[conda\] torchaudio 0.12.1 pypi\_0 pypi
> \[conda\] torchmeta 1.8.0 pypi\_0 pypi
> \[conda\] torchtext 0.13.1 pypi\_0 pypi
> \[conda\] torchvision 0.10.1 pypi\_0 pypi
> 
> \`\`\`
> 
> pytorch forum: https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244
> SO: https://stackoverflow.com/questions/74482017/why-isnt-randomcrop-inserting-the-padding-in-pytorch

---

<div class="post-metadata">

**Author:** ![Brando\_Miranda](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/brando_miranda/32/14355_2.png) [@Brando\_Miranda](https://discuss.pytorch.org/u/Brando_Miranda)\
**Post date:** [November 22, 2022, 7:30pm UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/6 "2022-11-22T19:30:47Z")

</div>

as a side note @ptrblck do you think doing this transform makes sense?

```auto
    train_data_transform = Compose([
        RandomResizedCrop((size, size), scale=scale, ratio=ratio),
        RandomCrop(size=size, padding=padding),
        ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),
        RandomHorizontalFlip(),
        ToTensor(),
        Normalize(mean=mean, std=std),
    ])

```

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [November 22, 2022, 7:35pm UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/7 "2022-11-22T19:35:42Z")

</div>

It’s hard to tell if this transformation would work for your use case.  
The `RandomCrop` transformation will basically add the padding border to the already cropped image (coming from `RandomResizedCrop`) and will then return a new crop in the same shape as the input from the padded image.  
Without knowing about your use case and dataset, I would not expect to see a huge difference between this approach and a transformation which drops the `RandomCrop` transformation, but in any case you should try both and compare their performance.

---

<div class="post-metadata">

**Author:** ![edgarriba](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/edgarriba/32/57_2.png) [@edgarriba](https://discuss.pytorch.org/u/edgarriba)\
**Post date:** [December 10, 2022, 8:03am UTC](https://discuss.pytorch.org/t/why-isnt-randomcrop-inserting-the-padding-in-pytorch/166244/8 "2022-12-10T08:03:26Z")

</div>

Alternatively you can check Kornia that includes more functionality with examples, differentiability, serialise the sampled parameters and compute the inverse of the operation.

[https://kornia.readthedocs.io/en/latest/augmentation.module.html#kornia.augmentation.RandomCrop](https://kornia.readthedocs.io/en/latest/augmentation.module.html#kornia.augmentation.RandomCrop)
