web-dev-qa-db-de.com

Numerisch stabiler Softmax

Gibt es eine numerisch stabile Möglichkeit, die Softmax-Funktion unten zu berechnen? Ich erhalte Werte, die zu Nans in Neural-Netzwerkcode werden.

np.exp(x)/np.sum(np.exp(y))
6
Abhishek Bhatia

Das softmax exp ( x )/sum (exp ( x )) ist tatsächlich numerisch gut. Es hat nur positive Ausdrücke, so dass wir uns keine Sorgen um den Bedeutungsverlust machen müssen, und der Nenner ist mindestens so groß wie der Zähler, so dass das Ergebnis garantiert zwischen 0 und 1 liegt.

Der einzige Unfall, der passieren könnte, ist ein Über- oder Unterfluss in den Exponentialen. Ein Überlauf eines einzelnen oder eines Unterlaufs aller Elemente von x macht die Ausgabe mehr oder weniger unbrauchbar.

Es ist jedoch leicht, dagegen zu schützen, indem Sie die Identität softmax ( x ) = softmax ( x + c) verwenden, die für jeden Skalar c gilt: Subtrahieren von max ( x ) von x hinterlässt einen Vektor, der nur nicht positive Einträge enthält, wodurch ein Überlauf ausgeschlossen wird und mindestens ein Element, das null ist, einen verschwindenden Nenner ausschließt (Unterlauf in einigen, aber nicht allen Einträgen ist harmlos).

Anmerkung: Theoretisch sind katastrophale Unfälle in der Summe möglich, aber Sie würden eine lächerliche Anzahl von Begriffen benötigen und lächerlich unglücklich sein. Numpy verwendet auch die paarweise Summation, die ziemlich robust ist.

23
Paul Panzer

Die Softmax-Funktion ist anfällig für zwei Probleme: overflow und underflow

Überlauf : Tritt auf, wenn sehr große Zahlen approximiert als infinity sind.

Underflow : Es tritt auf, wenn sehr kleine Zahlen (nahe Null in der Zahlenzeile) angenähert (d. H. Gerundet) als zero sind.

Um diese Probleme bei der Softmax-Berechnung zu bekämpfen, besteht ein üblicher Trick darin, den Eingabevektor um subtrahieren des maximalen Elements von allen Elementen zu verschieben. Definieren Sie für den Eingabevektor xz wie folgt:

z = x-max(x)

Und dann den Softmax des neuen (stabilen) Vektors z


Beispiel:

In [266]: def stable_softmax(x):
     ...:     z = x - max(x)
     ...:     numerator = np.exp(z)
     ...:     denominator = np.sum(numerator)
     ...:     softmax = numerator/denominator
     ...:     return softmax
     ...: 

In [267]: vec = np.array([1, 2, 3, 4, 5])

In [268]: stable_softmax(vec)
Out[268]: array([ 0.01165623,  0.03168492,  0.08612854,  0.23412166,  0.63640865])

In [269]: vec = np.array([12345, 67890, 99999999])

In [270]: stable_softmax(vec)
Out[270]: array([ 0.,  0.,  1.])

Weitere Informationen finden Sie in KapitelNumerical ComputationinDeep Learningbook.

2
kmario23

Es ist nichts falsch daran, die Softmax-Funktion wie in Ihrem Fall zu berechnen. Das Problem scheint von explodierenden Gradienten oder solchen Problemen mit Ihren Trainingsmethoden zu kommen. Konzentrieren Sie sich auf diese Punkte, indem Sie entweder " Abschneidewerte " oder "" die richtige Anfangsverteilung der Gewichte "wählen.

1

Danke Paul Panzers Erklärung, aber ich frage mich, warum wir max (x) subtrahieren müssen. Daher habe ich detailliertere Informationen gefunden und hoffe, dass es für die Leute hilfreich ist, die die gleiche Frage wie ich haben. Siehe Abschnitt "Was ist mit dieser maximalen Subtraktion?" Im folgenden Linkartikel.

https://nolanbconaway.github.io/blog/2017/softmax-numpy

1
Alumi Lu