Hi I am wondering when it comes to normalising images across each of the channels, do you use the same scaling factors that is used for training for testing set as well or separate ones. In traditional ML problems using scikit-learn, the usual procedure is normalise the training data and apply the same scaler for testing data
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle = True)
scaler = MinMaxScaler()
X_train_norm = scaler.fit_transform(X_train)
X_test_norm = scaler.transform(X_test)
However when using deep learning I am wondering whether the same procedure is used for image data
For example
import torch
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
# Resize Images to (3,150,150) and convert to torch tensors which gives values between 0 and 1 instead of 0 and 255. So need to divide by 255
train_transforms = transforms.Compose([
transforms.Resize((150,150)),
transforms.ToTensor(),
])
test_transforms = transforms.Compose([
transforms.Resize((150,150)),
transforms.ToTensor(),
])
train_datasets = ImageFolder(root = "data/dogs-vs-cats/concise_dataset/train", transform = train_transforms)
test_datasets = ImageFolder(root = "data/dogs-vs-cats/concise_dataset/test", transform = test_transforms)
# just a function to get mean of the mean and std for each channel across the entire train and test sets separately
def get_mean_and_std(dataset):
mean_values = torch.zeros(len(dataset),3)
std_values = torch.zeros(len(dataset),3)
for idx, (img, lab) in enumerate(dataset):
mean_values[idx, :] = img.mean(dim = [1,2])
std_values[idx, :] = img.std(dim = [1,2])
print(f"mean of entire dataset : {mean_values.mean(dim = 0)}")
print(f"std of entire dataset : {std_values.mean(dim = 0)}")
get_mean_and_std(train_datasets)
# mean of entire dataset : tensor([0.4854, 0.4515, 0.4143])
# std of entire dataset : tensor([0.2233, 0.2178, 0.2185])
get_mean_and_std(test_datasets)
# mean of entire dataset : tensor([0.4902, 0.4571, 0.4188])
# std of entire dataset : tensor([0.2257, 0.2203, 0.2207])
Now apply these means and standard deviations separately for training and testing data.
train_transforms = transforms.Compose([
transforms.Resize((150,150)),
transforms.ToTensor(),
transforms.Normalize(mean = [0.4854, 0.4515, 0.4143], std = [0.2233, 0.2178, 0.2185])
])
test_transforms = transforms.Compose([
transforms.Resize((150,150)),
transforms.ToTensor(),
transforms.Normalize(mean = [0.4902, 0.4571, 0.4188], std = [0.2257, 0.2203, 0.2207])
])
or should I apply the same mean and std of train set to the test set?
test_transforms = transforms.Compose([
transforms.Resize((150,150)),
transforms.ToTensor(),
transforms.Normalize(mean = [0.4854, 0.4515, 0.4143], std = [0.2233, 0.2178, 0.2185])
])