I have a batch of images for an ML tasks. The images are in a numpy array of the shape [N,C,H,W]
N - number of images
C - chanels (in my case 1)
H - height
W - width
I want to use the input images as a kind of activation map for a loss function. To do this I want to normalise each image individually between 0 and 1, using the following formulae:
zi = (xi – min(x)) / (max(x) – min(x))
I want to normalise each image individually to its own max and min, and not to the batch values. What is the most efficient way to do this whilst keeping the images in the batch?
CodePudding user response:
You can get the min / max over the C,H,W axes using amin(x, (1,2,3))
. In order to be able to broadcast you need to transpose first and then transpose back:
((x.T - np.amin(x, (1,2,3))) / (np.amax(x, (1,2,3)) - np.amin(x, (1,2,3)))).T
Example:
import numpy as np
np.random.seed(0)
n = 5
c = 1
h = 2
w = 3
x = np.random.randint(0, 255, (n, c, h, w))
Original array x:
array([[[[172, 47, 117],
[192, 67, 251]]],
[[[195, 103, 9],
[211, 21, 242]]],
[[[ 36, 87, 70],
[216, 88, 140]]],
[[[ 58, 193, 230],
[ 39, 87, 174]]],
[[[ 88, 81, 165],
[ 25, 77, 72]]]])
Normalize:
min = np.amin(x, (1,2,3))
max = np.amax(x, (1,2,3))
res = ((x.T - min) / (max - min)).T
Result:
array([[[[0.6127451 , 0. , 0.34313725],
[0.71078431, 0.09803922, 1. ]]],
[[[0.79828326, 0.40343348, 0. ],
[0.86695279, 0.05150215, 1. ]]],
[[[0. , 0.28333333, 0.18888889],
[1. , 0.28888889, 0.57777778]]],
[[[0.09947644, 0.80628272, 1. ],
[0. , 0.2513089 , 0.70680628]]],
[[[0.45 , 0.4 , 1. ],
[0. , 0.37142857, 0.33571429]]]])