I am getting odd images despite printing the transform the data is using:
-- 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:
but when I use this instead:
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:
why don’t both have the 8 and 8 padding on both sides I expect?
cross:
ptrblck
November 18, 2022, 5:58am
3
Answered on GitHib : 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 .
ptrblck
November 19, 2022, 12:46am
5
I don’t think the docs are confusing and explain which operations are applied as described here:
opened 01:00AM - 18 Nov 22 UTC
### 🐛 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
as a side note @ptrblck do you think doing this transform makes sense?
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),
])
ptrblck
November 22, 2022, 7:35pm
7
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.
edgarriba
(Edgar Riba)
December 10, 2022, 8:03am
8
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