TensorFlow Equivalent Of PyTorch's Transforms.Normalize()
Solution 1:
The workaround that you mentioned seems ok. But using for...loop to compute normalization to each RGB channel for a single image can be a bit problematic when you deal with a large dataset in the data pipeline (generator or tf.data). But it's ok anyway. Here is the demonstration of your approach, and later we will provide two possible alternatives that might work for you easily.
from PIL import Image
from matplotlib.pyplot import imshow, subplot, title, hist
# load image (RGB)
img = Image.open('/content/9.jpg')
def normalize_image(image, mean, std):
for channel in range(3):
image[:,:,channel] = (image[:,:,channel] - mean[channel]) / std[channel]
return image
OP_approach = normalize_image(np.array(img) / 255.0,
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
Now, let's observe the transform properties afterward.
plt.figure(figsize=(25,10))
subplot(121); imshow(OP_approach); title(f'Normalized Image \n min-px: \
{OP_approach.min()} \n max-pix: {OP_approach.max()}')
subplot(122); hist(OP_approach.ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
The range of minimum and maximum pixel after normalization are (-2.1179039301310043, 2.6399999999999997) respectively.
Option 2
We can use the tf. keras...Normalization preprocessing layer to do the same. It takes two important arguments which are mean and, variance (square of the std).
from tensorflow.keras.experimental.preprocessing import Normalization
input_data = np.array(img)/255
layer = Normalization(mean=[0.485, 0.456, 0.406],
variance=[np.square(0.299),
np.square(0.224),
np.square(0.225)])
plt.figure(figsize=(25,10))
subplot(121); imshow(layer(input_data).numpy()); title(f'Normalized Image \n min-px: \
{layer(input_data).numpy().min()} \n max-pix: {layer(input_data).numpy().max()}')
subplot(122); hist(layer(input_data).numpy().ravel(), bins=50, density=True);\
title('Histogram - pixel distribution')
The range of minimum and maximum pixel after normalization are (-2.0357144, 2.64) respectively.
Option 3
This is more like subtracting the average mean and divide by the average std.
norm_img = ((tf.cast(np.array(img), tf.float32) / 255.0) - 0.449) / 0.226
plt.figure(figsize=(25,10))
subplot(121); imshow(norm_img.numpy()); title(f'Normalized Image \n min-px: \
{norm_img.numpy().min()} \n max-pix: {norm_img.numpy().max()}')
subplot(122); hist(norm_img.numpy().ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
The range of minimum and maximum pixel after normalization are (-1.9867257, 2.4380531) respectively. Lastly, if we compare to the pytorch way, there is not that much difference among these approaches.
import torchvision.transforms as transforms
transform_norm = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
norm_pt = transform_norm(img)
plt.figure(figsize=(25,10))
subplot(121); imshow(np.array(norm_pt).transpose(1, 2, 0));\
title(f'Normalized Image \n min-px: \
{np.array(norm_pt).min()} \n max-pix: {np.array(norm_pt).max()}')
subplot(122); hist(np.array(norm_pt).ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
The range of minimum and maximum pixel after normalization are (-2.117904, 2.64) respectively.




Post a Comment for "TensorFlow Equivalent Of PyTorch's Transforms.Normalize()"