ReLU vs Sigmoid im mnist Beispiel

8

BITTE BEACHTEN SIE: Ich versuche nicht, das folgende Beispiel zu verbessern. Ich weiß, dass Sie eine Genauigkeit von über 99% erreichen können. Der gesamte Code ist in Frage. Wenn ich diesen einfachen Code ausprobiert habe, erhalte ich eine Genauigkeit von 95%. Wenn ich einfach die Aktivierungsfunktion von Sigmoid auf Relu ändere, sinkt sie auf weniger als 50%. Gibt es einen theoretischen Grund dafür?

Ich habe das folgende Beispiel online gefunden:

from keras.datasets import mnist
from keras.models import Sequential 
from keras.layers.core import Dense, Activation
from keras.utils import np_utils

(X_train, Y_train), (X_test, Y_test) = mnist.load_data()

X_train = X_train.reshape(60000, 784)     
X_test = X_test.reshape(10000, 784)

Y_train = np_utils.to_categorical(Y_train, classes)     
Y_test = np_utils.to_categorical(Y_test, classes)

batch_size = 100      
epochs = 15

model = Sequential()     
model.add(Dense(100, input_dim=784)) 
model.add(Activation('sigmoid'))     
model.add(Dense(10)) 
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='sgd')

model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1)

score = model.evaluate(X_test, Y_test, verbose=1)
print('Test accuracy:', score[1])

Dies ergibt eine Genauigkeit von ca. 95%. Wenn ich jedoch das Sigmoid mit der ReLU ändere, erhalte ich eine Genauigkeit von weniger als 50%. Warum ist das so?

Benutzer
quelle
Vergleiche mit Keras ' eigenem Relu-Beispiel.
Emre
Ich möchte verstehen, warum in diesem Beispiel das Relu so viel schlechter abschneiden würde als das Sigmoid. Sie verwenden einen anderen Optimierer. Funktioniert sgd nicht gut mit relu?
Benutzer
Entweder ist Ihr Modell nicht konvergiert und / oder es passt über. Ich werde mich mehr der zweiten Option zuwenden, da in der Dokumentation Dropout (Regularisierung) verwendet wurde und Sie dies nicht getan haben. Sie können dieses Problem beheben, indem Sie die Lernkurve für die Test- und Trainingssätze zeichnen.
Emre
Die Frage ist einfach: Warum funktioniert es gut mit Sigmoid und nicht mit Relu? Keiner der Kommentare befasst sich überhaupt mit der Frage.
Benutzer
Was ist Ihre Trainingsgenauigkeit mit RELU?
Imran

Antworten:

4

Ich habe Ihren genauen Code genommen und ersetzt

model.add(Activation('sigmoid'))

durch

model.add(Activation('relu'))

und tatsächlich hatte ich das gleiche Problem wie Sie: nur 55% Genauigkeit, was schlecht ist ...

Lösung : Ich habe die eingegebenen Bildwerte von [0, 255] auf [0,1] neu skaliert und es hat funktioniert: 93% Genauigkeit mit ReLU! (inspiriert von https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py ):

from keras.datasets import mnist
from keras.models import Sequential 
from keras.layers.core import Dense, Activation
from keras.utils import np_utils

(X_train, Y_train), (X_test, Y_test) = mnist.load_data()

X_train = X_train.reshape(60000, 784)     
X_test = X_test.reshape(10000, 784)
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255

Y_train = np_utils.to_categorical(Y_train, 10)
Y_test = np_utils.to_categorical(Y_test, 10)

batch_size = 100
epochs = 15

model = Sequential()     
model.add(Dense(100, input_dim=784)) 
model.add(Activation('relu'))
model.add(Dense(10)) 
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='sgd')

model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1)

score = model.evaluate(X_test, Y_test, verbose=1)
print('Test accuracy:', score[1])

Ausgabe:

Testgenauigkeit: 0,934


Mögliche Erklärung: Wenn Sie eine Eingabe in [0, 255] verwenden, dann wenn Sie die gewichtete Summe für die Ebene : ist der Wert oft auch groß. Wenn oft groß ist (oder sogar wenn es oft> 0 ist), sagen wir etwa 100, dann ist , und wir verlieren den "nichtlinearen" Aspekt dieser Aktivierungsfunktion völlig! Anders gesagt: Wenn die Eingabe in [0, 255] ist, dann ist oft weit von 0 entfernt, und wir vermeiden völlig den Ort, an dem "interessante nichtlineare Dinge" vor sich gehen (um 0 ist die ReLU-Funktion nicht linear und sieht aus wie ) ... Wenn nun die Eingabe in [0,1] ist, dann ist die gewichtete SummeL.z=ein(L.- -1)w(L.)+b(L.)zzR.eL.U.(z)=zz__/z kann oft nahe bei 0 liegen: Vielleicht geht es manchmal unter 0 (da die Gewichte zufällig auf [-1, 1] initialisiert werden, ist es möglich!), manchmal höher als 0 usw. Dann findet mehr Aktivierung / Deaktivierung von Neuronen statt. Dies könnte eine mögliche Erklärung dafür sein, warum es mit der Eingabe in [0, 1] besser funktioniert.

Basj
quelle
Vielen Dank für Ihre Mühe (+1). Meine Frage ist jedoch, warum das so ist. Was ist die theoretische Interpretation?
Benutzer
Ihr Argument scheint vernünftig. Wenn Sie dem Text Ihrer Antwort einen kurzen Kommentar hinzufügen möchten (Sie müssen die Kommentare also nicht lesen), werde ich Ihre Antwort akzeptieren.
Benutzer
@user Es ist geschafft!
Basj
1

Mit der ReLu-Aktivierungsfunktion habe ich eine Genauigkeit von ca. 98% erreicht. Ich habe die folgende Architektur verwendet:

  1. vollständig verbundene Schicht mit 300 versteckten Einheiten
  2. ReLu-Aktivierung
  3. vollständig verbundene Schicht mit 10 versteckten Einheiten
  4. Softmax-Schicht
  5. Ausgabe-Clipping 1e-10 bis 0,999999, um Protokoll (0) und Wert größer als 1 zu vermeiden
  6. Kreuzentropieverlust

Ich denke, Sie sollten Ausgabe-Clipping hinzufügen und dann trainieren, hoffen, dass das gut funktioniert.

Yash Khare
quelle
Vielen Dank. Ihre Antwort scheint zu bestätigen, was @Basj in seinen Kommentaren darüber sagt, warum relu nicht konvergiert, während sigmoid ist. +1 beantwortet aber immer noch nicht meine Frage warum. Ich denke, die Kommentare in der anderen Antwort erklären das.
Benutzer
-1

Denn mit MNIST versuchen Sie, anhand von Wahrscheinlichkeiten Vorhersagen zu treffen.

Die Sigmoidfunktion quetscht den Wert zwischen und . Dies hilft bei der Auswahl der wahrscheinlichsten Ziffer, die mit dem Etikett übereinstimmt.x01

Die ReLU-Funktion zerquetscht nichts. Wenn der Wert kleiner als , ist die Ausgabe . Wenn es mehr als , ist die Antwort der Wert selbst. Es werden keine Wahrscheinlichkeiten erstellt.x000x

Ehrlich gesagt, ich bin überrascht, dass Sie mehr als 10% erhalten haben, wenn Sie es anschließen.

Daleadil
quelle
1
Ich denke, er meint, er hat die Aktivierung der verborgenen Schicht von Sigmoid auf RELU geändert, was kein Problem sein sollte, solange die Ausgangsschicht noch Softmax hat.
Imran
1
@ Daleadil wie Imran sagte, kann die versteckte Schicht Relu als Aktivierungsfunktion haben, dies hat nichts mit Wahrscheinlichkeit zu tun
Benutzer