2017-04-13 1 views
0

Ich benutze Keras, und die letzte Schicht verwendet eine 'Softmax' Aktivierungsfunktion. Wenn ich jedoch die Wahrscheinlichkeiten vorhersage und summiere, bekomme ich nicht 1. Warum ist das?Warum ist die Summe von model.predict (x) kleiner als 1 mit softmax und LSTM?

N.B. : Ich bin wirklich weit von 1:

>>> m 
<keras.models.Sequential object at 0x1083fdf60> 
>>> m.layers[-1].activation 
<function softmax at 0x1092bfea0> 
>>> X.shape 
(1940, 10, 48) 
>>> m.input 
<tf.Tensor 'lstm_1_input:0' shape=(?, 10, 48) dtype=float32> 
>>> model.predict(X)[:10].sum(axis=-1) 
array([ 0.46206102, 0.43193966, 0.4252567 , 0.44023705, 0.46344867, 
     0.48820126, 0.50369406, 0.49789378, 0.46433908, 0.44102359], dtype=float32) 
>>> y=model.predict(X) 
>>> y[0] 
array([ 0.00000000e+00, 6.10233226e-04, 0.00000000e+00, 
     0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 
     0.00000000e+00, 0.00000000e+00, 1.12394022e-03, 
     0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 
     0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 
     0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 
     0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 
     0.00000000e+00, 1.55960268e-04, 0.00000000e+00, 
     4.60170895e-01], dtype=float32) 

EDIT: ich mit einem einfachen Code getestet

import numpy as np 
from keras.models import * 
from keras.layers import * 
m = Sequential() 
m.add(LSTM(3, input_shape=(3,2), activation='softmax')) 
print(m.predict(np.random.rand(5,3,2)).sum(axis=-1)) 

Und ich bekomme Ergebnisse wie

[ 0.50027865 0.49804032 0.49545377 0.50514281 0.50069857] 

OKAY, so mit Dense und SimpleRNN, ich bekomme fast 1. Das Problem könnte einfach sein, dass die Aktivierung nicht dasselbe Verhalten bei wiederkehrenden Layern hat, da GRU die gleichen Probleme hat. Ich fragte auf GitHub: https://github.com/fchollet/keras/issues/6255

Antwort

1

@joelthchao sagte auf GitHub (https://github.com/fchollet/keras/issues/6255):

Aktivierung hier direkt auf jeder versteckten Einheit gelten wird. Wir werden LSTM jedoch nicht auf diese Weise verwenden. Normalerweise tun wir es von:

m.add(LSTM(hidden_unit, input_shape=(3,2))) 
m.add(Dense(3, activation='softmax')) 

Schließlich habe ich logischer gefunden zu verwenden:

m.add(Lambda(K.softmax)) 
1

Nach dem Aufbau sollte die Softmax-Vorhersage zu eins summieren. In der Praxis werden sie jedoch aufgrund der Grenzen der Maschinengenauigkeit möglicherweise nicht zu genau einer Summe addiert. Wie weit von 1 sind Ihre kumulativen Wahrscheinlichkeiten?

Ich habe das Beispiel mnist_mlp.py im Verzeichnis Keras example/mit Theano als Backend ausgeführt. Dann habe ich die Testsatzwahrscheinlichkeiten mit dem trainierten Modell vorhergesagt. Die Wahrscheinlichkeiten summieren sich erwartungsgemäß zu fast eins.

y_pred = model.predict(x_test) 
y_sum = y_pred.sum(axis=1) 
print('Min={}, Max={}, Range={}'.format(y_sum.min(),y_sum.max(),y_sum.max()-y_sum.min())) 
# Min=0.9999999403953552, Max=1.0000001192092896, Range=1.7881393432617188e-07 

Der beobachtete Bereich liegt in der gleichen Größenordnung wie Maschinen epsilon für 32-Bit-schwimmt.

import numpy as np 
print(np.finfo(np.float32).eps) 
#1.19209e-07 

, die mit der Verwendung von

 "floatx": "float32", 

in meiner ~/.keras/keras.hjson Datei konsistent ist. Wenn Sie zusätzliche Genauigkeit benötigen, können Sie "float32" in "float64" ändern.

+0

Sorry, sollte ich genau bereiter sein können! Ich bin sehr weit von 1 ... – Labo

+0

@Labo Könnte es ein Unterlauf/Überlauf-Problem sein? Diese [link] (https://stats.stackexchange.com/questions/149663/robust-softmax-solutions-for-theano) auf robuste softmax Lösung kann relevant sein. – dhinckley

+0

Ich hatte Überläufe in Keras, und es verursacht im Allgemeinen "Nan" als Werte erscheinen. Ich habe keine Ahnung, was hier vor sich geht. – Labo

Verwandte Themen