NaN perte lors de la formation de régression réseau

j'ai une matrice de données dans" un encodage à chaud " (tous les uns et les zéros) avec 260.000 lignes et 35 colonnes. J'utilise Keras pour former un réseau neuronal simple pour prédire une variable continue. Le code pour faire le réseau est le suivant:

model = Sequential()
model.add(Dense(1024, input_shape=(n_train,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(1))

sgd = SGD(lr=0.01, nesterov=True);
#rms = RMSprop()
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy'])
model.compile(loss='mean_absolute_error', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] )

cependant, pendant le processus d'entraînement, je vois la perte diminuer joliment, mais au milieu de la deuxième époque, il va à nan:

Train on 260000 samples, validate on 64905 samples
Epoch 1/3
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss:
 13.4925
Epoch 2/3
 88448/260000 [=========>....................] - ETA: 161s - loss: nan

j'ai essayé d'utiliser RMSProp au lieu de SGD , j'ai essayé le tanh au lieu de relu , j'ai essayé avec et sans abandon, en vain. J'ai essayé avec un modèle plus petit, i.e. avec seulement une couche cachée, et même problème (il devient nan à un point différent). Cependant, il fonctionne avec moins de caractéristiques, i.e. s'il n'y a que 5 colonnes, et donne de très bonnes prédictions. Il semble être il ya une sorte de débordement, mais je ne peux pas imaginer pourquoi, la perte n'est pas excessivement large.

Python version 2.7.11, tournant sur une machine linux, CPU seulement. Je l'ai testé avec la dernière version de Theano, et je reçois aussi Nans, donc j'ai essayé D'aller à Theano 0.8.2 et ont le même problème. Avec la dernière version de Keras a le même problème, et aussi avec la version 0.3.2.

26
demandé sur Seanny123 2016-05-15 02:04:30

6 réponses

régression avec les réseaux neuronaux est difficile à obtenir de travail parce que la sortie est illimitée, de sorte que vous êtes particulièrement enclin à la exploding gradients problème (la cause probable des nans).

historiquement, une solution clé à l'explosion des gradients était de réduire le taux d'apprentissage, mais avec l'avènement des algorithmes de taux d'apprentissage adaptatif par paramètre comme Adam, vous n'avez plus besoin de définir un taux d'apprentissage pour obtenir une bonne performance. Il est très peu de raisons d'utiliser SGD avec momentum plus sauf si vous êtes un fiend réseau neuronal et savoir comment ajuster le calendrier d'apprentissage.

Voici certaines choses que vous pourriez essayer:

  1. Normaliser vos sorties par quantile normalisation "des 151920920" ou z notation . Pour être rigoureux, calculez cette transformation sur les données de formation, pas sur l'ensemble des données. Par exemple, avec quantile la normalisation, si un exemple est dans le 60e percentile de l'ensemble de la formation, il obtient une valeur de 0.6. (Vous pouvez également décaler les valeurs normalisées quantile vers le bas de 0.5 de sorte que le 0e percentile est -0.5 et le 100e percentile est +0.5).

  2. ajouter la régularisation, soit en augmentant le taux d'abandon, soit en ajoutant les pénalités L1 et L2 aux pondérations. La régularisation L1 est analogue à la sélection des caractéristiques, et puisque vous avez dit que la réduction du nombre de caractéristiques à 5 donne une bonne performance, L1 peut aussi.

  3. si ceux-ci n'aident pas encore, réduisez la taille de votre réseau. Ce n'est pas toujours la meilleure idée, car elle peut nuire à la performance, mais dans votre cas, vous avez un grand nombre de neurones de première couche (1024) par rapport aux caractéristiques d'entrée (35), donc cela peut aider.

  4. augmenter la taille du lot de 32 à 128. 128 est assez standard, et pourrait potentiellement augmenter la stabilité de l'optimisation.

39
répondu 1'' 2016-05-15 19:06:55

La réponse en 1" est assez bonne. Toutefois, toutes les solutions semblent régler la question indirectement plutôt que directement. Je recommande d'utiliser la coupe par gradient, qui ne fera que couper les gradients qui sont au-dessus d'une certaine valeur.

dans Keras vous pouvez utiliser clipnorm=1 (voir https://keras.io/optimizers / ) pour simplement Clipper tous les gradients avec une norme supérieure à 1.

15
répondu pir 2016-11-26 23:07:01

j'ai déjà fait face au même problème. Je cherche et je trouve cette question et ses réponses. Toutes ces astuces mentionnées ci-dessus sont importantes pour la formation d'un réseau neuronal profond. J'ai tout essayé, mais J'ai toujours NAN.

je trouve aussi cette question ici. https://github.com/fchollet/keras/issues/2134 . J'ai cité l'auteur du résumé comme suit: "Je voulais le souligner afin qu'il soit archivé pour les autres qui pourraient éprouver ce problème à l'avenir. J'ai été je suis tombé sur ma fonction de perte Et je suis revenu avec une nan après avoir été si loin dans le processus d'entraînement. J'ai vérifié le relus, l'optimiseur, la perte de fonction, mon abandon en conformité avec les relus, la taille de mon réseau et de la forme du réseau. J'étais encore en train de subir une perte qui a fini par se transformer en nan et je me faisais tout à fait brillé.

puis j'ai compris. J'ai peut-être une mauvaise entrée. Il s'avère, l'une des images que je tenais à mon CNN (et faire méchant la normalisation sur) n'était rien d'autre que des 0. Je ne vérifiais pas ce cas quand j'ai soustrait la moyenne et normalisé par la déviation std et donc j'ai fini avec une matrice exemplaire qui n'était rien d'autre que celle de nan. Une fois que j'ai réparé ma fonction de normalisation, mon réseau s'entraîne maintenant parfaitement."

je suis d'accord avec le point de vue ci-dessus: l'entrée est sensible pour votre réseau. dans mon cas, j'utilise la valeur logarithmique de l'estimation de la densité comme entrée. La valeur absolue pourrait être très grand, ce qui peut entraîner NaN après plusieurs étapes de gradients. Je pense que la vérification des entrées est nécessaire. Tout d'abord , vous devez vous assurer que l'entrée ne comprend pas -inf ou inf , ou certains nombres extrêmement grands en valeur absolue.

12
répondu HenryZhao 2017-01-07 08:22:50

j'ai fait face à un problème très similaire, et c'est ainsi que je l'ai fait fonctionner.

la première chose que vous pouvez essayer est de changer votre activation en LeakyReLU au lieu d'utiliser Relu ou Tanh. La raison est que souvent, beaucoup de noeuds dans vos couches ont une activation de zéro, et la rétropogation ne met pas à jour les poids de ces noeuds parce que leur gradient est également zéro. C'est aussi ce qu'on appelle le problème de la "mort ReLU" (vous pouvez en lire plus à ce sujet ici: https://datascience.stackexchange.com/questions/5706/what-is-the-dying-relu-problem-in-neural-networks ).

pour ce faire, vous pouvez importer l'activation LeakyReLU en utilisant:

from keras.layers.advanced_activations import LeakyReLU

et l'incorporer dans vos couches comme ceci:

model.add(Dense(800,input_shape=(num_inputs,)))
model.add(LeakyReLU(alpha=0.1))

en outre, il est possible que la caractéristique de sortie (la variable continue que vous essayez de prédire) est un ensemble de données déséquilibré et a trop de 0s. Aller simple pour résoudre ce problème est d'utiliser le lissage. Vous pouvez le faire en ajoutant 1 au numérateur de tous vos valeurs dans cette colonne et en divisant chacune des valeurs dans cette colonne par 1/(moyenne de toutes les valeurs de cette colonne)

cela déplace essentiellement toutes les valeurs de 0 à une valeur supérieure à 0 (qui peut encore être très faible). Cela empêche la courbe de prédire 0s et de minimiser la perte (en faisant éventuellement NaN). Des valeurs plus petites sont plus fortement touchées que les grandes des valeurs, mais dans l'ensemble, la moyenne de l'ensemble de données reste la même.

3
répondu Arnav 2018-07-18 23:30:08

je perdais en tant que nan à la toute première époque, dès le début de l'entraînement. Solution aussi simple que de supprimer le nas des données d'entrée qui ont fonctionné pour moi (df.dropna ())

j'espère que cela aide quelqu'un rencontre le même problème

2
répondu Krithi07 2018-05-31 11:38:00

j'ai essayé toutes les suggestions sur cette page et beaucoup d'autres en vain. Nous importions des fichiers csv avec pandas, puis nous utilisions keras Tokenizer avec entrée de texte pour créer des vocabulaires et des matrices de vecteurs word. Après avoir remarqué que certains fichiers CSV conduisaient à Nan tandis que d'autres fonctionnaient, nous avons soudainement regardé l'encodage des fichiers et nous sommes rendus compte que les fichiers ascii ne fonctionnaient pas avec keras, conduisant à nan perte et précision de 0.0000e+00 ; cependant, les fichiers utf-8 et utf-16 étaient working ! Percée.

si vous effectuez une analyse textuelle et que vous perdez nan après avoir essayé ces suggestions, utilisez file -i {input} (linux) ou file -I {input} (osx) pour découvrir votre type de fichier. Si vous avez ISO-8859-1 ou us-ascii , essayez de convertir en utf-8 ou utf-16le . Je n'ai pas essayé la dernière, mais j'imagine que ça marcherait aussi. Espérons que cela aide quelqu'un très très frustré!

0
répondu Clay Coleman 2018-03-08 09:59:51