J'ai un tableau d'images numpy en trois dimensions ( CIFAR-10 dataset ). La forme du tableau d'images est comme ci-dessous:
a = np.random.Rand(32, 32, 3)
Avant de procéder à un apprentissage approfondi, je souhaite normaliser les données pour obtenir de meilleurs résultats. Avec un tableau 1D, je sais que nous pouvons faire une normalisation min max comme ceci:
v = np.random.Rand(6)
(v - v.min())/(v.max() - v.min())
Out[68]:
array([ 0.89502294, 0. , 1. , 0.65069468, 0.63657915,
0.08932196])
Cependant, quand il s'agit d'un tableau 3D, je suis totalement perdu. Plus précisément, j'ai les questions suivantes:
J'apprécie ton aide!
EDIT: Il s’avère que j’ai besoin de travailler avec un tableau 4D Numpy de forme (202, 32, 32, 3)
, de sorte que la première dimension serait l’index de l’image et les 3 dernières dimensions l’image réelle. Ce sera formidable si quelqu'un peut me fournir le code pour normaliser un tel tableau 4D. Merci!
EDIT 2: Merci au code de @ Eric ci-dessous, je l'ai compris:
x_min = x.min(axis=(1, 2), keepdims=True)
x_max = x.max(axis=(1, 2), keepdims=True)
x = (x - x_min)/(x_max-x_min)
En supposant que vous travailliez avec des données d'image de forme (W, H, 3)
, vous devriez probablement normaliser séparément sur chaque canal (axis=2
) séparément, comme indiqué dans l'autre réponse.
Vous pouvez le faire avec:
# keepdims makes the result shape (1, 1, 3) instead of (3,). This doesn't matter here, but
# would matter if you wanted to normalize over a different axis.
v_min = v.min(axis=(0, 1), keepdims=True)
v_max = v.max(axis=(0, 1), keepdims=True)
(v - v_min)/(v_max - v_min)
Pour répondre à cette question, nous avons probablement besoin de plus d'informations sur vos données, mais en général, lorsque vous parlez d'images 3 canaux, par exemple, nous normaliserions l'utilisation des valeurs min et max par canal. cela signifie que nous effectuerions la normalisation trois fois - une fois par canal ... Voici un exemple:
img = numpy.random.randint(0, 100, size=(10, 10, 3)) # Generating some random numbers
img = img.astype(numpy.float32) # converting array of ints to floats
img_a = img[:, :, 0]
img_b = img[:, :, 1]
img_c = img[:, :, 2] # Extracting single channels from 3 channel image
# The above code could also be replaced with cv2.split(img) << which will return 3 numpy arrays (using opencv)
# normalizing per channel data:
img_a = (img_a - numpy.min(img_a)) / (numpy.max(img_a) - numpy.min(img_a))
img_b = (img_b - numpy.min(img_b)) / (numpy.max(img_b) - numpy.min(img_b))
img_c = (img_c - numpy.min(img_c)) / (numpy.max(img_c) - numpy.min(img_c))
# putting the 3 channels back together:
img_norm = numpy.empty((10, 10, 3), dtype=numpy.float32)
img_norm[:, :, 0] = img_a
img_norm[:, :, 1] = img_b
img_norm[:, :, 2] = img_c
Edit: Je viens de penser qu’une fois que vous avez les données d’un canal (image 32x32 par exemple), vous pouvez simplement utiliser:
from sklearn.preprocessing import normalize
img_a_norm = normalize(img_a)
Eh bien, c’est une grosse question. Si vous avez besoin de fonctions telles que min et max, utilisez les versions Numpy. L'indexation, par exemple, est réalisée à l'aide de séparateurs d'axe - comme vous pouvez le constater dans l'exemple ci-dessus. Veuillez également consulter la documentation de Numpy sur ndarray @ https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html Pour en savoir plus. ils ont vraiment un ensemble incroyable d’outils pour les tableaux à n dimensions.
Il y a différentes approches ici. Vous pouvez soit décider de normaliser l’ensemble du lot d’images, soit normaliser chaque image. Pour ce faire, vous pouvez soit utiliser la moyenne d'une seule image, soit la moyenne de l'ensemble du lot d'images, soit utiliser une moyenne fixe d'un autre jeu de données, par exemple vous pouvez utiliser la valeur moyenne ImageNet
.
Si vous voulez faire la même chose que tf.image.per_image_standardization
de Tensorflow, vous devez normaliser chaque image avec la moyenne de cette image. Donc, vous parcourez toutes les images et effectuez la normalisation de tous les axes dans une seule image, comme ceci:
import math
import numpy as np
from PIL import Image
# open images
image_1 = Image.open("your_image_1.jpg")
image_2 = Image.open("your_image_2.jpg")
images = [image_1, image_2]
images = np.array(images)
standardized_images = []
# standardize images
for image in images:
mean = image.mean()
stddev = image.std()
adjusted_stddev = max(stddev, 1.0/math.sqrt(image.size))
standardized_image = (image - mean) / adjusted_stddev
standardized_images.append(standardized_image)
standardized_images = np.array(standardized_images)