web-dev-qa-db-fra.com

Apprentissage en profondeur des raisons de perte de nan

Peut-être une question trop générale, mais est-ce que quelqu'un peut expliquer ce qui ferait diverger un réseau de neurones convolutionnels?

Détails:

J'utilise le modèle iris_training de Tensorflow avec certaines de mes propres données et continue à recevoir

ERREUR: tensorflow: le modèle a divergé avec perte = NaN.

Traceback ...

tensorflow.contrib.learn.python.learn.monitors.NanLossDuringTrainingError: perte de NaN pendant l'entraînement.

Traceback d'origine avec ligne:

 tf.contrib.learn.DNNClassifier(feature_columns=feature_columns,
                                        hidden_units=[300, 300, 300],
                                        #optimizer=tf.train.ProximalAdagradOptimizer(learning_rate=0.001, l1_regularization_strength=0.00001),                                                          
                                        n_classes=11,
                                        model_dir="/tmp/iris_model")

J'ai essayé d'ajuster l'optimiseur, d'utiliser un taux d'apprentissage égal à zéro et de ne pas utiliser d'optimiseur. Toute information sur les couches réseau, la taille des données, etc. est appréciée.

32
Zroach

J'ai vu beaucoup de choses faire diverger un modèle.

  1. Taux d'apprentissage trop élevé. Vous pouvez souvent dire si c'est le cas si la perte commence à augmenter puis diverge à l'infini. 

  2. Je ne connais pas bien le DNNClassifier, mais je suppose qu'il utilise la fonction de coût catégorique en entropie croisée. Cela implique de prendre le journal de la prédiction qui diverge à mesure que la prédiction approche de zéro. C'est pourquoi les gens ajoutent généralement une petite valeur epsilon à la prédiction pour éviter cette divergence. Je suppose que DNNClassifier le fait probablement ou utilise l’opp tensorflow pour cela. Probablement pas le problème.

  3. D'autres problèmes de stabilité numérique peuvent exister, tels que la division par zéro, où l'ajout d'epsilon peut aider. Une autre solution moins évidente si la racine carrée du dérivé peut diverger si elle n’est pas correctement simplifiée s’agissant des nombres à précision finie. Encore une fois, je doute que ce soit le problème dans le cas de DNNClassifier.

  4. Vous pouvez avoir un problème avec les données d'entrée. Essayez d'appeler assert not np.any(np.isnan(x)) sur les données d'entrée pour vous assurer que vous n'introduisez pas le nan. Assurez-vous également que toutes les valeurs cibles sont valides. Enfin, assurez-vous que les données sont correctement normalisées. Vous voulez probablement avoir les pixels dans la plage [-1, 1] et non dans [0, 255].

  5. Les étiquettes doivent appartenir à la fonction de perte. Par conséquent, si vous utilisez une fonction de perte logarithmique, toutes les étiquettes doivent être non négatives (comme indiqué par evan pu et les commentaires ci-dessous).

52
chasep255

Si vous vous entraînez à l'entropie croisée, vous souhaitez ajouter un petit nombre comme 1e-8 à votre probabilité de sortie.

Comme log (0) est un infini négatif, lorsque votre modèle sera suffisamment entraîné, la distribution de sortie sera très asymétrique, par exemple, si je fais une sortie à 4 classes, ma probabilité au début est la suivante:

0.25 0.25 0.25 0.25

mais vers la fin de la probabilité sera probablement ressembler

1.0 0 0 0

Et vous prenez une entropie croisée de cette distribution, tout va exploser. Le correctif consiste à ajouter artificiellement un petit nombre à tous les termes pour éviter cela.

7
Evan Pu

Si vous utilisez des entiers comme cibles, assurez-vous qu'ils ne sont pas symétriques à 0. 

C'est-à-dire, n'utilisez pas les classes -1, 0, 1. Utilisez à la place 0, 1, 2.

2
yper

Si vous souhaitez collecter plus d'informations sur l'erreur et si l'erreur se produit dans les premières itérations, je vous suggère d'exécuter le test en mode CPU uniquement (sans GPU). Le message d'erreur sera beaucoup plus spécifique. 

Source: https://github.com/tensorflow/tensor2tensor/issues/574

1
Kevin Johnsrude

Dans mon cas, j'ai obtenu NAN lors de la définition d'étiquettes entières distantes. c'est à dire:

  • Les étiquettes [0..100] la formation était ok,
  • Etiquettes [0..100] plus une étiquette supplémentaire 8000, puis j'ai des NAN.

Donc, n'utilisez pas une étiquette très éloignée.

EDITVous pouvez voir l’effet dans le code simple suivant:

from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np

X=np.random.random(size=(20,5))
y=np.random.randint(0,high=5, size=(20,1))

model = Sequential([
            Dense(10, input_dim=X.shape[1]),
            Activation('relu'),
            Dense(5),
            Activation('softmax')
            ])
model.compile(optimizer = "Adam", loss = "sparse_categorical_crossentropy", metrics = ["accuracy"] )

print('fit model with labels in range 0..5')
history = model.fit(X, y, epochs= 5 )

X = np.vstack( (X, np.random.random(size=(1,5))))
y = np.vstack( ( y, [[8000]]))
print('fit model with labels in range 0..5 plus 8000')
history = model.fit(X, y, epochs= 5 )

Le résultat affiche les NAN après avoir ajouté l'étiquette 8000:

fit model with labels in range 0..5
Epoch 1/5
20/20 [==============================] - 0s 25ms/step - loss: 1.8345 - acc: 0.1500
Epoch 2/5
20/20 [==============================] - 0s 150us/step - loss: 1.8312 - acc: 0.1500
Epoch 3/5
20/20 [==============================] - 0s 151us/step - loss: 1.8273 - acc: 0.1500
Epoch 4/5
20/20 [==============================] - 0s 198us/step - loss: 1.8233 - acc: 0.1500
Epoch 5/5
20/20 [==============================] - 0s 151us/step - loss: 1.8192 - acc: 0.1500
fit model with labels in range 0..5 plus 8000
Epoch 1/5
21/21 [==============================] - 0s 142us/step - loss: nan - acc: 0.1429
Epoch 2/5
21/21 [==============================] - 0s 238us/step - loss: nan - acc: 0.2381
Epoch 3/5
21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
Epoch 4/5
21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
Epoch 5/5
21/21 [==============================] - 0s 188us/step - loss: nan - acc: 0.2381
1
Guido