Vielleicht eine zu allgemeine Frage, aber kann jemand erklären, was dazu führen würde, dass ein Faltungs-Neuronales Netz auseinander geht?
Besonderheiten:
Ich verwende das iris_training-Modell von Tensorflow mit einigen meiner eigenen Daten und bekomme es immer wieder
FEHLER: Tensorfluss: Modell divergiert mit Verlust = NaN.
Zurück verfolgen...
tensorflow.contrib.learn.python.learn.monitors.NanLossDuringTrainingError: NaN-Verlust während des Trainings.
Traceback entstand mit Zeile:
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")
Ich habe versucht, den Optimierer anzupassen, eine Null für die Lernrate zu verwenden und keinen Optimierer zu verwenden. Alle Einblicke in Netzwerkschichten, Datengröße usw. sind willkommen.
python
tensorflow
machine-learning
keras
theano
Kostenlose URL
quelle
quelle
tf.losses.sparse_softmax_cross_entropy(y, logits)
anstelle meiner eigenen Implementierung von Safe Softmax mittf.nn.Softmax
Antworten:
Es gibt viele Dinge, die ich gesehen habe, wie ein Modell auseinander geht.
Zu hohe Lernrate. Sie können oft feststellen, ob dies der Fall ist, wenn der Verlust zuzunehmen beginnt und dann ins Unendliche abweicht.
Ich bin mit dem DNNClassifier nicht vertraut, aber ich vermute, dass er die kategoriale Cross-Entropy-Cost-Funktion verwendet. Dies beinhaltet das Protokoll der Vorhersage, das divergiert, wenn sich die Vorhersage Null nähert. Aus diesem Grund fügen die Leute der Vorhersage normalerweise einen kleinen Epsilon-Wert hinzu, um diese Divergenz zu verhindern. Ich vermute, dass der DNNClassifier dies wahrscheinlich tut oder den Tensorflow opp dafür verwendet. Wahrscheinlich nicht das Problem.
Andere numerische Stabilitätsprobleme können auftreten, z. B. die Division durch Null, wobei das Hinzufügen des Epsilons hilfreich sein kann. Eine andere, weniger offensichtliche, wenn die Quadratwurzel, deren Ableitung, beim Umgang mit Zahlen mit endlicher Genauigkeit divergieren kann, wenn sie nicht richtig vereinfacht wird. Ich bezweifle erneut, dass dies beim DNNClassifier der Fall ist.
Möglicherweise haben Sie ein Problem mit den Eingabedaten. Rufen Sie
assert not np.any(np.isnan(x))
die Eingabedaten auf, um sicherzustellen, dass Sie die Nan nicht einführen. Stellen Sie außerdem sicher, dass alle Zielwerte gültig sind. Stellen Sie schließlich sicher, dass die Daten ordnungsgemäß normalisiert sind. Sie möchten wahrscheinlich die Pixel im Bereich [-1, 1] und nicht [0, 255] haben.Die Beschriftungen müssen im Bereich der Verlustfunktion liegen. Wenn Sie also eine logarithmisch basierte Verlustfunktion verwenden, dürfen alle Beschriftungen nicht negativ sein (wie von evan pu und den Kommentaren unten angegeben).
quelle
tf.keras.utils.normalize(data)
war nützlich, um die Daten zu normalisieren.Wenn Sie für Kreuzentropie trainieren, möchten Sie Ihrer Ausgabewahrscheinlichkeit eine kleine Zahl wie 1e-8 hinzufügen.
Da log (0) eine negative Unendlichkeit ist, ist die Ausgabeverteilung sehr verzerrt, wenn Ihr Modell ausreichend trainiert ist. Nehmen wir zum Beispiel an, ich mache eine Ausgabe mit 4 Klassen. Am Anfang sieht meine Wahrscheinlichkeit so aus
0.25 0.25 0.25 0.25
aber gegen Ende wird die Wahrscheinlichkeit wahrscheinlich so aussehen
1.0 0 0 0
Und Sie nehmen eine Kreuzentropie dieser Verteilung, alles wird explodieren. Die Lösung besteht darin, allen Begriffen künstlich eine kleine Zahl hinzuzufügen, um dies zu verhindern.
quelle
categorical_crossentropy
Verlustfunktion von Keras. Implementiert sie dies bereits?Wenn Sie Ganzzahlen als Ziele verwenden, stellen Sie sicher, dass diese bei 0 nicht symmetrisch sind.
Verwenden Sie also nicht die Klassen -1, 0, 1. Verwenden Sie stattdessen 0, 1, 2.
quelle
In meinem Fall habe ich NAN erhalten, als ich entfernte Ganzzahl-ETIKETTEN gesetzt habe. dh:
Verwenden Sie daher kein sehr weit entferntes Etikett.
BEARBEITEN Sie können den Effekt im folgenden einfachen Code sehen:
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 )
Das Ergebnis zeigt die NANs nach dem Hinzufügen des Labels 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
quelle
Wenn Sie weitere Informationen zum Fehler erhalten möchten und der Fehler in den ersten Iterationen auftritt, empfehlen wir Ihnen, das Experiment im Nur-CPU-Modus (keine GPUs) auszuführen. Die Fehlermeldung wird viel spezifischer sein.
Quelle: https://github.com/tensorflow/tensor2tensor/issues/574
quelle
Regularisierung kann helfen. Für einen Klassifizierer gibt es einen guten Fall für die Regularisierung von Aktivitäten, unabhängig davon, ob es sich um einen binären Klassifizierer oder einen Klassifizierer mit mehreren Klassen handelt. Für einen Regressor ist eine Kernel-Regularisierung möglicherweise besser geeignet.
quelle
Ich möchte einige (flache) Gründe einstecken, die ich wie folgt erlebt habe:
Hoffentlich hilft das.
quelle
Der Grund
nan
,inf
oder-inf
kommt oft aus der Tatsache , dassdivision by 0.0
in TensorFlow nicht durch Null Ausnahme in einer Abteilung führt. Es könnte in einem Ergebnisnan
,inf
oder-inf
„Wert“. In Ihren Trainingsdaten0.0
und möglicherweise in Ihrer Verlustfunktion kann es vorkommen, dass Sie einedivision by 0.0
.a = tf.constant([2., 0., -2.]) b = tf.constant([0., 0., 0.]) c = tf.constant([1., 1., 1.]) print((a / b) + c)
Die Ausgabe ist der folgende Tensor:
tf.Tensor([ inf nan -inf], shape=(3,), dtype=float32)
Das Hinzufügen eines kleinen
eplison
(z. B.1e-5
) reicht oft aus. Zusätzlich wird seit TensorFlow 2 die Operationtf.math.division_no_nan
definiert.quelle
Obwohl die meisten Punkte bereits diskutiert werden. Aber ich möchte noch einmal einen Grund für NaN hervorheben, der fehlt.
tf.estimator.DNNClassifier( hidden_units, feature_columns, model_dir=None, n_classes=2, weight_column=None, label_vocabulary=None, optimizer='Adagrad', activation_fn=tf.nn.relu, dropout=None, config=None, warm_start_from=None, loss_reduction=losses_utils.ReductionV2.SUM_OVER_BATCH_SIZE, batch_norm=False )
Standardmäßig ist die Aktivierungsfunktion "Relu". Es ist möglich, dass die Zwischenschicht einen negativen Wert erzeugt und "Relu" ihn in die 0 umwandelt, wodurch das Training allmählich unterbrochen wird.
Ich habe beobachtet, dass "LeakyRelu" solche Probleme lösen kann.
quelle