web-dev-qa-db-fra.com

Pourquoi devrions-nous normaliser les données pour l'apprentissage en profondeur dans Keras?

Je testais certaines architectures de réseau dans Keras pour classer l'ensemble de données MNIST. J'en ai implémenté un qui est similaire à LeNet.

Il me semble que dans les exemples que j'ai trouvés sur Internet, il y a une étape de normalisation des données. Par exemple:

X_train /= 255

J'ai effectué un test sans cette normalisation et il me semble que les performances (précision) du réseau ont diminué (en gardant le même nombre d'époques). Pourquoi est-ce arrivé?

Si j'augmente le nombre d'époques, la précision peut-elle atteindre le même niveau atteint par le modèle formé à la normalisation?

Donc, la normalisation affecte la précision, ou seulement la vitesse d'entraînement?

Le code source complet de mon script de formation est ci-dessous:

from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dense
from keras.datasets import mnist
from keras.utils import np_utils
from keras.optimizers import SGD, RMSprop, Adam
import numpy as np
import matplotlib.pyplot as plt
from keras import backend as k


def build(input_shape, classes):
    model = Sequential()

    model.add(Conv2D(20, kernel_size=5, padding="same",activation='relu',input_shape=input_shape))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    model.add(Conv2D(50, kernel_size=5, padding="same", activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    model.add(Flatten())
    model.add(Dense(500))
    model.add(Activation("relu"))

    model.add(Dense(classes))
    model.add(Activation("softmax"))

    return model


NB_Epoch = 4 # number of epochs
BATCH_SIZE = 128 # size of the batch
VERBOSE = 1 # set the training phase as verbose
OPTIMIZER = Adam() # optimizer
VALIDATION_SPLIT=0.2 # percentage of the training data used for 
evaluating the loss function
IMG_ROWS, IMG_COLS = 28, 28 # input image dimensions
NB_CLASSES = 10 # number of outputs = number of digits
INPUT_SHAPE = (1, IMG_ROWS, IMG_COLS) # shape of the input

(X_train, y_train), (X_test, y_test) = mnist.load_data()

k.set_image_dim_ordering("th")

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

X_train = X_train[:, np.newaxis, :, :]
X_test = X_test[:, np.newaxis, :, :]
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

y_train = np_utils.to_categorical(y_train, NB_CLASSES)
y_test = np_utils.to_categorical(y_test, NB_CLASSES)

model = build(input_shape=INPUT_SHAPE, classes=NB_CLASSES)
model.compile(loss="categorical_crossentropy", 
optimizer=OPTIMIZER,metrics=["accuracy"])

history = model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=NB_Epoch, verbose=VERBOSE, validation_split=VALIDATION_SPLIT)

model.save("model2")

score = model.evaluate(X_test, y_test, verbose=VERBOSE)
print('Test accuracy:', score[1])
6
Zaratruta

La normalisation est un concept générique qui ne se limite pas uniquement à l'apprentissage en profondeur ou à Keras.

Pourquoi normaliser?

Permettez-moi de prendre un exemple de régression logistique simple qui sera facile à comprendre et à expliquer la normalisation. Supposons que nous essayons de prédire si un client devrait recevoir un prêt ou non. Parmi les nombreuses variables indépendantes disponibles, considérons simplement Age et Income. Soit l'équation de la forme:

Y = weight_1 * (Age) + weight_2 * (Income) + some_constant

Pour des raisons d'explication, laissez Age être généralement dans la plage de [0,120] et supposons que Income dans la plage de [10000, 100000]. L'échelle de Age et Income est très différente. Si vous les considérez tels quels, alors les poids weight_1 et weight_2 peuvent se voir attribuer des poids biaisés. weight_2 pourrait apporter plus d'importance à Income en tant que fonctionnalité qu'à ce que weight_1 donne de l'importance à Age. Pour les mettre à l'échelle à un niveau commun, nous pouvons les normaliser. Par exemple, nous pouvons ramener tous les âges dans une fourchette de [0,1] et tous les revenus dans une fourchette de [0,1]. Nous pouvons maintenant dire que Age et Income ont la même importance en tant que fonctionnalité.

La normalisation augmente-t-elle toujours la précision?

Apparemment, non. Il n'est pas nécessaire que la normalisation augmente toujours la précision. Cela peut ou non, vous ne savez jamais vraiment jusqu'à ce que vous implémentiez. Encore une fois, cela dépend à quel stade de votre formation vous appliquez la normalisation, si vous appliquez la normalisation après chaque activation, etc.

À mesure que la plage des valeurs des entités se réduit à une plage particulière en raison de la normalisation, il est facile d'effectuer des calculs sur une plage de valeurs plus petite. Donc, généralement, le modèle est entraîné un peu plus rapidement.

En ce qui concerne le nombre d'époques, la précision augmente généralement avec le nombre d'époques à condition que votre modèle ne commence pas à être trop ajusté.


Une très bonne explication pour la normalisation/normalisation et les termes associés est ici .

13
Shridhar R Kulkarni

En un mot, la normalisation réduit la complexité du problème que votre réseau tente de résoudre. Cela peut potentiellement augmenter la précision de votre modèle et accélérer la formation. Vous amenez les données sur la même échelle et réduisez la variance. Aucun des poids du réseau n'est gaspillé à effectuer une normalisation pour vous, ce qui signifie qu'ils peuvent être utilisés plus efficacement pour résoudre la tâche réelle à accomplir.

6
pietz