it-swarm.com.de

So implementieren Sie die Softmax-Funktion in Python

Aus der tiefen Lernklasse von Udacity ist der Softmax von y_i einfach das Exponential, geteilt durch die Summe des Exponentials des gesamten Y-Vektors:

 enter image description here

Wobei S(y_i) die Softmax-Funktion von y_i und e das Exponential ist und j das Nein ist. von Spalten im Eingabevektor Y.

Ich habe folgendes versucht:

import numpy as np

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

scores = [3.0, 1.0, 0.2]
print(softmax(scores))

was gibt zurück:

[ 0.8360188   0.11314284  0.05083836]

Die vorgeschlagene Lösung war jedoch:

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    return np.exp(x) / np.sum(np.exp(x), axis=0)

das erzeugt die gleiche Ausgabe wie die erste Implementierung, obwohl die erste Implementierung explizit die Differenz jeder Spalte und des Maximums übernimmt und dann durch die Summe dividiert.

Kann jemand mathematisch zeigen, warum? Ist einer richtig und der andere falsch?

Ist die Implementierung hinsichtlich Code und zeitlicher Komplexität ähnlich? Was ist effizienter?

180
alvas

Sie sind beide korrekt, aber aus Sicht der numerischen Stabilität wird Ihre bevorzugt.

Du beginnst mit

e ^ (x - max(x)) / sum(e^(x - max(x))

Indem wir die Tatsache verwenden, dass a ^ (b - c) = (a ^ b)/(a ​​^ c) gilt, haben wir

= e ^ x / (e ^ max(x) * sum(e ^ x / e ^ max(x)))

= e ^ x / sum(e ^ x)

Welches ist, was die andere Antwort sagt. Sie können max (x) durch eine beliebige Variable ersetzen, und dies würde ausfallen.

99

(Nun ... viel Verwirrung hier, sowohl in der Frage als auch in den Antworten ...)

Zunächst sind die beiden Lösungen (d. H. Ihre und die vorgeschlagene) nicht äquivalent; sie happen sollen nur für den Sonderfall von 1-D-Score-Arrays gleichwertig sein. Sie hätten es entdeckt, wenn Sie auch das 2-D-Score-Array aus dem Beispiel des Udacity-Quiz ausprobiert hätten.

In Bezug auf die Ergebnisse ist der einzige tatsächliche Unterschied zwischen den beiden Lösungen der axis=0 Streit. Um zu sehen, ob dies der Fall ist, versuchen wir Ihre Lösung (your_softmax) und eines, bei dem der einzige Unterschied das Argument axis ist:

import numpy as np

# your solution:
def your_softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

# correct solution:
def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0) # only difference

Wie gesagt, für ein 1-D-Score-Array sind die Ergebnisse in der Tat identisch:

scores = [3.0, 1.0, 0.2]
print(your_softmax(scores))
# [ 0.8360188   0.11314284  0.05083836]
print(softmax(scores))
# [ 0.8360188   0.11314284  0.05083836]
your_softmax(scores) == softmax(scores)
# array([ True,  True,  True], dtype=bool)

Dennoch sind hier die Ergebnisse für das 2-D-Score-Array, das im Udacity-Quiz als Testbeispiel angegeben wurde:

scores2D = np.array([[1, 2, 3, 6],
                     [2, 4, 5, 6],
                     [3, 8, 7, 6]])

print(your_softmax(scores2D))
# [[  4.89907947e-04   1.33170787e-03   3.61995731e-03   7.27087861e-02]
#  [  1.33170787e-03   9.84006416e-03   2.67480676e-02   7.27087861e-02]
#  [  3.61995731e-03   5.37249300e-01   1.97642972e-01   7.27087861e-02]]

print(softmax(scores2D))
# [[ 0.09003057  0.00242826  0.01587624  0.33333333]
#  [ 0.24472847  0.01794253  0.11731043  0.33333333]
#  [ 0.66524096  0.97962921  0.86681333  0.33333333]]

Die Ergebnisse sind unterschiedlich - das zweite ist in der Tat identisch mit dem im Udacity-Quiz erwarteten, bei dem alle Spalten tatsächlich 1 ergeben, was beim ersten (falschen) Ergebnis nicht der Fall ist.

Die ganze Aufregung galt also einem Implementierungsdetail - dem Argument axis. Nach der numpy.sum Dokumentation :

Die Standardeinstellung axis = None summiert alle Elemente des Eingabearrays

während hier wollen wir zeilenweise summieren, daher axis=0. Bei einem 1-D-Array sind die Summe der (einzigen) Zeile und die Summe aller Elemente identisch, daher erhalten Sie in diesem Fall dasselbe Ergebnis ...

Abgesehen von dem Problem axis ist Ihre Implementierung (d. H. Ihre Wahl, zuerst das Maximum zu subtrahieren) tatsächlich besser als die vorgeschlagene Lösung! Tatsächlich ist dies die empfohlene Methode zur Implementierung der Softmax-Funktion - siehe hier zur Begründung (numerische Stabilität, auf die auch in einigen Antworten oben hingewiesen wird).

86
desertnaut

Also, das ist wirklich ein Kommentar zu Desertnauts Antwort, aber aufgrund meines guten Rufs kann ich noch nichts dazu sagen. Wie er darauf hingewiesen hat, ist Ihre Version nur korrekt, wenn Ihre Eingabe aus einem einzigen Sample besteht. Wenn Ihre Eingabe aus mehreren Beispielen besteht, ist dies falsch. Die Lösung von Desertnaut ist jedoch auch falsch. Das Problem ist, dass er einmal eine 1-dimensionale Eingabe und dann eine 2-dimensionale Eingabe vornimmt. Lass mich dir das zeigen.

import numpy as np

# your solution:
def your_softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

# desertnaut solution (copied from his answer): 
def desertnaut_softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0) # only difference

# my (correct) solution:
def softmax(z):
    assert len(z.shape) == 2
    s = np.max(z, axis=1)
    s = s[:, np.newaxis] # necessary step to do broadcasting
    e_x = np.exp(z - s)
    div = np.sum(e_x, axis=1)
    div = div[:, np.newaxis] # dito
    return e_x / div

Nehmen wir ein Beispiel für Desertnauts:

x1 = np.array([[1, 2, 3, 6]]) # notice that we put the data into 2 dimensions(!)

Dies ist die Ausgabe:

your_softmax(x1)
array([[ 0.00626879,  0.01704033,  0.04632042,  0.93037047]])

desertnaut_softmax(x1)
array([[ 1.,  1.,  1.,  1.]])

softmax(x1)
array([[ 0.00626879,  0.01704033,  0.04632042,  0.93037047]])

Sie können sehen, dass die Desernauts-Version in dieser Situation fehlschlägt. (Es wäre nicht möglich, wenn die Eingabe nur eine Dimension wie np.array ([1, 2, 3, 6]) wäre.

Wir verwenden jetzt 3 Samples, da dies der Grund ist, warum wir eine zweidimensionale Eingabe verwenden. Das folgende x2 ist nicht dasselbe wie das Beispiel von desernauts. 

x2 = np.array([[1, 2, 3, 6],  # sample 1
               [2, 4, 5, 6],  # sample 2
               [1, 2, 3, 6]]) # sample 1 again(!)

Diese Eingabe besteht aus einer Charge mit 3 Proben. Probe eins und drei sind jedoch im Wesentlichen gleich. Wir erwarten jetzt 3 Reihen von Softmax-Aktivierungen, wobei die erste die gleiche wie die dritte und auch die Aktivierung von x1 sein sollte!

your_softmax(x2)
array([[ 0.00183535,  0.00498899,  0.01356148,  0.27238963],
       [ 0.00498899,  0.03686393,  0.10020655,  0.27238963],
       [ 0.00183535,  0.00498899,  0.01356148,  0.27238963]])


desertnaut_softmax(x2)
array([[ 0.21194156,  0.10650698,  0.10650698,  0.33333333],
       [ 0.57611688,  0.78698604,  0.78698604,  0.33333333],
       [ 0.21194156,  0.10650698,  0.10650698,  0.33333333]])

softmax(x2)
array([[ 0.00626879,  0.01704033,  0.04632042,  0.93037047],
       [ 0.01203764,  0.08894682,  0.24178252,  0.65723302],
       [ 0.00626879,  0.01704033,  0.04632042,  0.93037047]])

Ich hoffe, Sie können sehen, dass dies nur bei meiner Lösung der Fall ist.

softmax(x1) == softmax(x2)[0]
array([[ True,  True,  True,  True]], dtype=bool)

softmax(x1) == softmax(x2)[2]
array([[ True,  True,  True,  True]], dtype=bool)

Außerdem sind hier die Ergebnisse der TensorFlows-Softmax-Implementierung aufgeführt:

import tensorflow as tf
import numpy as np
batch = np.asarray([[1,2,3,6],[2,4,5,6],[1,2,3,6]])
x = tf.placeholder(tf.float32, shape=[None, 4])
y = tf.nn.softmax(x)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(y, feed_dict={x: batch})

Und das Ergebnis:

array([[ 0.00626879,  0.01704033,  0.04632042,  0.93037045],
       [ 0.01203764,  0.08894681,  0.24178252,  0.657233  ],
       [ 0.00626879,  0.01704033,  0.04632042,  0.93037045]], dtype=float32)
44
ChuckFive

Ich würde sagen, dass beide zwar mathematisch korrekt sind, was die Implementierung angeht, aber die erste ist besser. Bei der Berechnung von Softmax können die Zwischenwerte sehr groß werden. Das Teilen von zwei großen Zahlen kann numerisch instabil sein. Diese Notizen (von Stanford) erwähnen einen Normalisierungstrick, der im Wesentlichen das ist, was Sie tun. 

31
Shagun Sodhani

sklearn bietet auch die Implementierung von softmax an

from sklearn.utils.extmath import softmax
import numpy as np

x = np.array([[ 0.50839931,  0.49767588,  0.51260159]])
softmax(x)

# output
array([[ 0.3340521 ,  0.33048906,  0.33545884]]) 
20
Roman Orac

Aus mathematischer Sicht sind beide Seiten gleich. 

Und Sie können das leicht beweisen. Lassen Sie uns m=max(x). Nun liefert Ihre Funktion softmax einen Vektor, dessen i-te Koordinate gleich ist

 enter image description here

beachten Sie, dass dies für alle m funktioniert, da für alle (auch komplexen) Zahlen e^m != 0

  • vom Standpunkt der rechnerischen Komplexität sind sie auch gleichwertig und beide laufen in O(n) time, wobei n die Größe eines Vektors ist. 

  • vom numerischen Stabilitäts Standpunkt aus gesehen wird die erste Lösung bevorzugt, da e^x sehr schnell wächst und sogar für ziemlich kleine Werte von x überläuft. Durch Abzug des Maximalwerts kann dieser Überlauf beseitigt werden. Um das Zeug, von dem ich sprach, praktisch zu erleben, versuchen Sie x = np.array([1000, 5]) in beide Funktionen einzubeziehen. Eine gibt die richtige Wahrscheinlichkeit zurück, die zweite wird mit nan überlaufen.

  • nicht auf die Frage bezogen, aber Ihre Lösung funktioniert nur für Vektoren (Udacity-Quiz möchte, dass Sie sie auch für Matrizen berechnen). Um dies zu beheben, müssen Sie sum(axis=0) verwenden.

10
Salvador Dali

Hier erfahren Sie, warum sie - max verwendet haben. 

Von dort:

"Wenn Sie in der Praxis Code zum Berechnen der Softmax-Funktion schreiben, können die Zwischenterme aufgrund der Exponentialwerte sehr groß sein. Das Teilen großer Zahlen kann numerisch instabil sein.

9
Sadegh Salehi

EDIT. Ab Version 1.2.0 enthält Scipy als Sonderfunktion Softmax: 

https://scipy.github.io/devdocs/generated/scipy.special.softmax.html

Ich habe eine Funktion geschrieben, die den Softmax auf einer beliebigen Achse anwendet:

def softmax(X, theta = 1.0, axis = None):
    """
    Compute the softmax of each element along an axis of X.

    Parameters
    ----------
    X: ND-Array. Probably should be floats. 
    theta (optional): float parameter, used as a multiplier
        prior to exponentiation. Default = 1.0
    axis (optional): axis to compute values along. Default is the 
        first non-singleton axis.

    Returns an array the same size as X. The result will sum to 1
    along the specified axis.
    """

    # make X at least 2d
    y = np.atleast_2d(X)

    # find axis
    if axis is None:
        axis = next(j[0] for j in enumerate(y.shape) if j[1] > 1)

    # multiply y against the theta parameter, 
    y = y * float(theta)

    # subtract the max for numerical stability
    y = y - np.expand_dims(np.max(y, axis = axis), axis)

    # exponentiate y
    y = np.exp(y)

    # take the sum along the specified axis
    ax_sum = np.expand_dims(np.sum(y, axis = axis), axis)

    # finally: divide elementwise
    p = y / ax_sum

    # flatten if X was 1D
    if len(X.shape) == 1: p = p.flatten()

    return p

Das Abziehen des Maximums, wie von anderen Benutzern beschrieben, ist eine gute Praxis. Ich habe einen ausführlichen Beitrag darüber geschrieben hier .

7
Nolan Conaway

Eine prägnantere Version ist:

def softmax(x):
    return np.exp(x) / np.exp(x).sum(axis=0)

Um eine alternative Lösung zu bieten, sollten Sie die Fälle in Betracht ziehen, in denen Ihre Argumente extrem groß sind, so dass exp(x) (im negativen Fall) oder im positiven Fall überlaufen würde. Hier möchten Sie so lange wie möglich im Protokollspeicherbereich bleiben und nur am Ende potenzieren, wo Sie sich darauf verlassen können, dass das Ergebnis sich gut benimmt.

import scipy.special as sc
import numpy as np

def softmax(x: np.ndarray) -> np.ndarray:
    return np.exp(x - sc.logsumexp(x))
4
PikalaxALT

Ich würde vorschlagen, dies-

def softmax(z): z_norm=np.exp(z-np.max(z,axis=0,keepdims=True)) return(np.divide(z_norm,np.sum(z_norm,axis=0,keepdims=True)))

Es funktioniert sowohl für Stochastik als auch für den Batch . Weitere Informationen finden Sie unter __. https://medium.com/@ravish1729/analysis-of-softmax-function-ad058d6a564d

1

Hier ist eine verallgemeinerte Lösung unter Verwendung von Numpy und Vergleich der Korrektheit mit Tensorflow und Scipy:

Datenaufbereitung:

import numpy as np

np.random.seed(2019)

batch_size = 1
n_items = 3
n_classes = 2
logits_np = np.random.Rand(batch_size,n_items,n_classes).astype(np.float32)
print('logits_np.shape', logits_np.shape)
print('logits_np:')
print(logits_np)

Ausgabe:

logits_np.shape (1, 3, 2)
logits_np:
[[[0.9034822  0.3930805 ]
  [0.62397    0.6378774 ]
  [0.88049906 0.299172  ]]]

Softmax mit Tensorflow:

import tensorflow as tf

logits_tf = tf.convert_to_tensor(logits_np, np.float32)
scores_tf = tf.nn.softmax(logits_np, axis=-1)

print('logits_tf.shape', logits_tf.shape)
print('scores_tf.shape', scores_tf.shape)

with tf.Session() as sess:
    scores_np = sess.run(scores_tf)

print('scores_np.shape', scores_np.shape)
print('scores_np:')
print(scores_np)

print('np.sum(scores_np, axis=-1).shape', np.sum(scores_np,axis=-1).shape)
print('np.sum(scores_np, axis=-1):')
print(np.sum(scores_np, axis=-1))

Ausgabe:

logits_tf.shape (1, 3, 2)
scores_tf.shape (1, 3, 2)
scores_np.shape (1, 3, 2)
scores_np:
[[[0.62490064 0.37509936]
  [0.4965232  0.5034768 ]
  [0.64137274 0.3586273 ]]]
np.sum(scores_np, axis=-1).shape (1, 3)
np.sum(scores_np, axis=-1):
[[1. 1. 1.]]

Softmax mit scipy:

from scipy.special import softmax

scores_np = softmax(logits_np, axis=-1)

print('scores_np.shape', scores_np.shape)
print('scores_np:')
print(scores_np)

print('np.sum(scores_np, axis=-1).shape', np.sum(scores_np, axis=-1).shape)
print('np.sum(scores_np, axis=-1):')
print(np.sum(scores_np, axis=-1))

Ausgabe:

scores_np.shape (1, 3, 2)
scores_np:
[[[0.62490064 0.37509936]
  [0.4965232  0.5034768 ]
  [0.6413727  0.35862732]]]
np.sum(scores_np, axis=-1).shape (1, 3)
np.sum(scores_np, axis=-1):
[[1. 1. 1.]]

Softmax mit numpy ( https://nolanbconaway.github.io/blog/2017/softmax-numpy ):

def softmax(X, theta = 1.0, axis = None):
    """
    Compute the softmax of each element along an axis of X.

    Parameters
    ----------
    X: ND-Array. Probably should be floats.
    theta (optional): float parameter, used as a multiplier
        prior to exponentiation. Default = 1.0
    axis (optional): axis to compute values along. Default is the
        first non-singleton axis.

    Returns an array the same size as X. The result will sum to 1
    along the specified axis.
    """

    # make X at least 2d
    y = np.atleast_2d(X)

    # find axis
    if axis is None:
        axis = next(j[0] for j in enumerate(y.shape) if j[1] > 1)

    # multiply y against the theta parameter,
    y = y * float(theta)

    # subtract the max for numerical stability
    y = y - np.expand_dims(np.max(y, axis = axis), axis)

    # exponentiate y
    y = np.exp(y)

    # take the sum along the specified axis
    ax_sum = np.expand_dims(np.sum(y, axis = axis), axis)

    # finally: divide elementwise
    p = y / ax_sum

    # flatten if X was 1D
    if len(X.shape) == 1: p = p.flatten()

    return p


scores_np = softmax(logits_np, axis=-1)

print('scores_np.shape', scores_np.shape)
print('scores_np:')
print(scores_np)

print('np.sum(scores_np, axis=-1).shape', np.sum(scores_np, axis=-1).shape)
print('np.sum(scores_np, axis=-1):')
print(np.sum(scores_np, axis=-1))

Ausgabe:

scores_np.shape (1, 3, 2)
scores_np:
[[[0.62490064 0.37509936]
  [0.49652317 0.5034768 ]
  [0.64137274 0.3586273 ]]]
np.sum(scores_np, axis=-1).shape (1, 3)
np.sum(scores_np, axis=-1):
[[1. 1. 1.]]
0
mrgloom

Ziel war es, mit Numpy und Tensorflow ähnliche Ergebnisse zu erzielen. Die einzige Änderung gegenüber der ursprünglichen Antwort ist der axis-Parameter für np.sum api.

Anfänglicher Ansatz : axis=0 - Dies liefert jedoch keine beabsichtigten Ergebnisse, wenn die Abmessungen N sind.

Geänderter Ansatz : axis=len(e_x.shape)-1 - Summe immer auf der letzten Dimension. Dies liefert ähnliche Ergebnisse wie die Softmax-Funktion von Tensorflow.

def softmax_fn(input_array):
    """
    | **@author**: Prathyush SP
    |
    | Calculate Softmax for a given array
    :param input_array: Input Array
    :return: Softmax Score
    """
    e_x = np.exp(input_array - np.max(input_array))
    return e_x / e_x.sum(axis=len(e_x.shape)-1)
0
kingspp

Ich brauchte etwas, das mit der Ausgabe einer dichten Schicht aus Tensorflow kompatibel ist. 

Die Lösung von @desertnaut funktioniert in diesem Fall nicht, weil ich Datenstapel habe. Daher kam ich mit einer anderen Lösung, die in beiden Fällen funktionieren sollte:

def softmax(x, axis=-1):
    e_x = np.exp(x - np.max(x)) # same code
    return e_x / e_x.sum(axis=axis, keepdims=True)

Ergebnisse:

logits = np.asarray([
    [-0.0052024,  -0.00770216,  0.01360943, -0.008921], # 1
    [-0.0052024,  -0.00770216,  0.01360943, -0.008921]  # 2
])

print(softmax(logits))

#[[0.2492037  0.24858153 0.25393605 0.24827873]
# [0.2492037  0.24858153 0.25393605 0.24827873]]

Ref: Tensorflow softmax

0

Jeder scheint seine Lösung zu posten, also werde ich meine posten:

def softmax(x):
    e_x = np.exp(x.T - np.max(x, axis = -1))
    return (e_x / e_x.sum(axis=0)).T

Ich erhalte genau dieselben Ergebnisse wie die von sklearn importierten:

from sklearn.utils.extmath import softmax
0
Julian

Ich möchte etwas mehr Verständnis für das Problem hinzufügen. Hier ist es richtig, max des Arrays zu subtrahieren. Wenn Sie jedoch den Code in dem anderen Beitrag ausführen, werden Sie feststellen, dass Sie keine richtige Antwort erhalten, wenn das Array 2D- oder höhere Dimensionen hat.

Hier gebe ich Ihnen einige Vorschläge:

  1. Um das Maximum zu erreichen, versuchen Sie es entlang der x-Achse, Sie erhalten ein 1D-Array.
  2. Formen Sie Ihr maximales Array in die ursprüngliche Form um.
  3. Np.exp liefert einen exponentiellen Wert.
  4. Führen Sie np.sum entlang der Achse aus.
  5. Holen Sie sich die endgültigen Ergebnisse.

Folgen Sie dem Ergebnis und Sie erhalten die richtige Antwort durch Vektorisierung. Da es sich um die Hausaufgaben des Colleges handelt, kann ich den genauen Code hier nicht posten, aber ich würde gerne mehr Vorschläge machen, wenn Sie nicht verstehen.

0
Hao Xu

In den obigen Antworten bereits ausführlich beantwortet. max wird abgezogen, um einen Überlauf zu vermeiden. Ich füge hier eine weitere Implementierung in Python3 hinzu.

import numpy as np
def softmax(x):
    mx = np.amax(x,axis=1,keepdims = True)
    x_exp = np.exp(x - mx)
    x_sum = np.sum(x_exp, axis = 1, keepdims = True)
    res = x_exp / x_sum
    return res

x = np.array([[3,2,4],[4,5,6]])
print(softmax(x))
0
Debashish

Der Zweck der Softmax-Funktion besteht darin, das Verhältnis der Vektoren beizubehalten, anstatt die Endpunkte mit einem Sigmoid zu quetschen, wenn die Werte sättigen (d. H. Zu +/- 1 (tanh) oder von 0 zu 1 (logistisch) tendieren). Dies liegt daran, dass dadurch mehr Informationen über die Änderungsrate an den Endpunkten erhalten bleiben, und ist daher eher für neuronale Netze mit 1-aus-N-Ausgangscodierung anwendbar (dh wenn wir die Endpunkte zusammengedrückt haben, wäre es schwieriger, die 1 zu unterscheiden.) -of-N-Ausgabeklasse, da wir nicht sagen können, welche die "größte" oder "kleinste" ist, weil sie zerquetscht wurden.); Außerdem wird die Gesamtsumme der Summe auf 1 gesetzt, und der klare Gewinner wird näher an 1 liegen, während andere Zahlen, die nahe beieinander liegen, 1/p ergeben, wobei p die Anzahl der Ausgangsneuronen mit ähnlichen Werten ist.

Der Grund für das Subtrahieren des Maximalwerts vom Vektor besteht darin, dass bei Exponenten möglicherweise sehr hohe Werte erhalten werden, die den Float auf den Maximalwert ausschneiden, was zu einem Gleichstand führt, was in diesem Beispiel nicht der Fall ist. Dies wird zu einem GROSSEN Problem, wenn Sie den Maximalwert subtrahieren, um eine negative Zahl zu erhalten. Dann haben Sie einen negativen Exponenten, der die Werte schnell verkleinert und das Verhältnis ändert. Dies ist das Ergebnis der Frage des Posters und die falsche Antwort.

Die Antwort von Udacity ist SCHWERTIG ineffizient. Das erste, was wir tun müssen, ist, e ^ y_j für alle Vektorkomponenten zu berechnen, DIESE WERTE ZU BEWAHREN, sie dann zusammenzufassen und zu dividieren. Wo Udacity vermasselt ist, berechnen sie ZWEIMAL !!! Hier ist die richtige Antwort:

def softmax(y):
    e_to_the_y_j = np.exp(y)
    return e_to_the_y_j / np.sum(e_to_the_y_j, axis=0)
0
user2356685
import tensorflow as tf
import numpy as np

def softmax(x):
    return (np.exp(x).T / np.exp(x).sum(axis=-1)).T

logits = np.array([[1, 2, 3], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]])

sess = tf.Session()
print(softmax(logits))
print(sess.run(tf.nn.softmax(logits)))
sess.close()
0
King

Um die numerische Stabilität aufrechtzuerhalten, sollte max (x) abgezogen werden. Im Folgenden finden Sie den Code für die Softmax-Funktion.

def softmax (x):

if len(x.shape) > 1:
    tmp = np.max(x, axis = 1)
    x -= tmp.reshape((x.shape[0], 1))
    x = np.exp(x)
    tmp = np.sum(x, axis = 1)
    x /= tmp.reshape((x.shape[0], 1))
else:
    tmp = np.max(x)
    x -= tmp
    x = np.exp(x)
    tmp = np.sum(x)
    x /= tmp


return x
0
Rahul Ahuja