web-dev-qa-db-fra.com

Numpy - normaliser la matrice de pixels RVB

J'ai un tableau numpy avec la forme (34799, 32, 32, 3)ce qui signifie (num examples, width, height, channels).

Maintenant, je normalise les données d'image avec le code suivant:

def normalize(x):
    return (x - 128) / 128

X_train_norm = normalize(X_train)

Mais le résultat ne semble pas correct, la valeur de X_train[0][0][0] est [28 25 24], mais la sortie de X_train_norm[0][0][0] est [1.21875 1.1953125 1.1875].

J'utilise le code de test suivant:

test = np.array([[[[28, 25, 24]]]])
print ((test - 128) / 128)

production:

[[[[-0.78125   -0.8046875 -0.8125   ]]]]

Pourquoi la fonction normalize obtient le mauvais résultat?

8
jetta

Je pense que les images sont chargées comme un tableau numpy rempli de uint8 Octets avec des valeurs comprises entre 0 Et 255.

Si vous effectuez une soustraction sur un uint8 De telle sorte que le résultat soit négatif, un bouclage se produit. Comme 123 - 128 == 251, Puis vous le divisez par 128. Par exemple:

>>> np.array([28,25,24], dtype=np.uint8) - 128
array([156, 153, 152], dtype=uint8)

puis nous obtenons le rapport:

>>> (np.array([28,25,24], dtype=np.uint8) - 128)/128
array([1.21875  , 1.1953125, 1.1875   ])

Pour le résoudre, vous pouvez utiliser .astype(..):

def normalize(x):
    return (x.astype(float) - 128) / 128

Notez que cela n'a rien à voir avec le fait que vous utilisez une fonction, si vous aviez utilisé l'expression avec le tableau d'origine, vous auriez eu le résultat même.

5
Willem Van Onsem

Comme le code est actuellement écrit, si x a dtype uint8 (ce qui semble avoir), la soustraction aura lieu en uint8, mais la division se fait en float.

La façon la plus simple de résoudre ce problème est de forcer la soustraction à se produire dans les flottants en laissant 128 être un flottant

def normalize(x):
    return (x - 128.0) / 128
5
Jonas Adler