Normalizing pixel Values in PyTorch

Viewed 1010

I am currently working with the CORnet-Z neural network and I am training it on an alternative version of the ImageNet image dataset.

I looked through the code and noticed this image value normalization method:

normalize = torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                             std=[0.229, 0.224, 0.225])
...

And then implemented later in the train, val, and test class:

torchvision.transforms.Compose([
    torchvision.transforms.RandomResizedCrop(256),
    torchvision.transforms.RandomHorizontalFlip(),
    torchvision.transforms.ToTensor(),
    normalize]))

I was wondering if I could rewrite this to just take the RGB pixel values and divide them by 255 to have a scale of 0-1 to work with.

According to the torchvision.transforms documentation this is not an implemented approach.

3 Answers

What you found in the code is statistics standardization, you're looking to normalize the input. These are two different operations but can be carried out with the same operator: under torchvision.transforms by the name of Normalize. It applies a shift-scale on the input:

Normalize a tensor image with mean and standard deviation. This transform does not support PIL Image. Given mean: (mean[1],...,mean[n]) and std: (std[1],..,std[n]) for n channels, this transform will normalize each channel of the input torch.*Tensor i.e., output[channel] = (input[channel] - mean[channel]) / std[channel].

>>> normalize = T.Normalize(mean=0, std=255)

Your transformation pipeline is then:

>>> T.Compose([T.RandomResizedCrop(256),
               T.RandomHorizontalFlip(),
               T.ToTensor(),
               normalize]))

where torchvivision.transforms is imported as T.

Why not just use a lambda? (corrected to use transforms.Lambda)

data_transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Lambda(lambda t: t/255)  # Scale pixel values to 0..1
    ])

You will have to write a custom transform. If you want to divide each pixel by 255 you can do below:

import torch
from torchvision import transforms, datasets
import numpy as np

# Custom Trranform
class custom_normalize(object):
    def __init__(self, n):
      self.n = n

    def __call__(self, tensor):        
        return tensor/self.n

data_transform = transforms.Compose([
        transforms.ToTensor(),
        custom_normalize(255)
    ])

# Some dummy data
x_images = np.random.randint(0,255, size=(4,4,3)).astype(np.float32)
data_transform(x_images)

output:

tensor([[[0.5922, 0.6275, 0.3098, 0.9765],
         [0.0235, 0.3098, 0.0510, 0.9686],
         [0.0275, 0.0706, 0.4275, 0.2863],
         [0.4275, 0.6196, 0.1843, 0.7333]],

        [[0.2235, 0.8000, 0.1647, 0.5608],
         [0.2941, 0.7412, 0.8275, 0.0706],
         [0.3765, 0.5804, 0.8196, 0.6902],
         [0.0000, 0.8784, 0.0353, 0.2941]],

        [[0.4157, 0.1294, 0.4745, 0.4275],
         [0.0902, 0.9882, 0.7137, 0.9255],
         [0.7725, 0.2824, 0.2314, 0.4353],
         [0.7451, 0.0235, 0.1725, 0.6745]]])
Related