Einfache lineare Regression in Keras

11

Nachdem ich mir diese Frage angesehen habe: Beim Versuch, die lineare Regression mit Keras zu emulieren , habe ich versucht, mein eigenes Beispiel nur zu Studienzwecken zu erstellen und meine Intuition zu entwickeln.

Ich habe einen einfachen Datensatz heruntergeladen und eine Spalte verwendet, um eine andere vorherzusagen. Die Daten sehen folgendermaßen aus:

Fernsehdaten

Jetzt habe ich gerade ein einfaches Keras-Modell mit einer einzelnen linearen Ebene mit einem Knoten erstellt und darauf einen Gradientenabstieg ausgeführt:

from keras.layers import Input, Dense
from keras.models import Model

inputs = Input(shape=(1,))
preds = Dense(1,activation='linear')(inputs)

model = Model(inputs=inputs,outputs=preds)
sgd=keras.optimizers.SGD()
model.compile(optimizer=sgd ,loss='mse',metrics=['mse'])
model.fit(x,y, batch_size=1, epochs=30, shuffle=False)

Wenn ich das Modell so laufen lasse, verliere ich nanin jeder Epoche.

Link zum Jupyter-Notizbuch

Also habe ich beschlossen, Dinge auszuprobieren und bekomme nur dann ein anständiges Modell, wenn ich eine lächerlich kleine Lernrate verwende sgd=keras.optimizers.SGD(lr=0.0000001) :

Fernsehdaten angepasst

Warum passiert das jetzt? Muss ich die Lernrate für jedes Problem, mit dem ich konfrontiert bin, manuell so einstellen? Mache ich hier etwas falsch Das soll das einfachste Problem sein, oder?

Vielen Dank!

Felipe Almeida
quelle

Antworten:

11

Dies liegt wahrscheinlich daran, dass keine Normalisierung durchgeführt wurde. Neuronale Netze reagieren sehr empfindlich auf nicht normalisierte Daten.

Eine gewisse Intuition: Wenn wir versuchen, unser mehrdimensionales globales Minimum zu finden (wie im stochastischen Gradientenabstiegsmodell), "zieht" jedes Merkmal in jeder Iteration mit einer gewissen Kraft (der Länge des Vektors) in seine Dimension (Vektorrichtung) ). Wenn die Daten nicht normalisiert sind, kann ein kleiner Wertschritt für Spalte A eine große Änderung in Spalte B verursachen.

Ihr Code hat dies mit Ihrer sehr niedrigen Lernrate bewältigt, was den Effekt auf jede Spalte "normalisierte", jedoch einen verzögerten Lernprozess verursachte, der viel mehr Epochen zum Abschluss erforderte.

Fügen Sie diesen Normalisierungscode hinzu:

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
x = sc.fit_transform(x)
y = sc.fit_transform(y)

Und lassen Sie einfach den Lernratenparameter (lr) fallen - lassen Sie ihn mit Bedacht einen automatischen Wert für Sie auswählen. Ich habe das gleiche gewünschte Diagramm wie Sie jetzt :)

mork
quelle
Sieht ordentlich aus ... das einzige, was ich nicht mag, ist, dass ich diese Standardisierung auf ähnliche Weise anwenden muss, um Eingaben zu testen, und dann wird die Ausgabe, die ich erhalte, auch in einem anderen Satz von Einheiten insgesamt sein.
Felipe Almeida
2
Das ist richtig @Felipe Almeida, das Ausgabeergebnis sollte zurück "umgekehrt" werden, aber dies ist normalerweise in die Bibliotheken integriert. Werfen Sie einen Blick auf inverse_transform scikit-learn.org/stable/modules/generated/… und einige andere Vorverarbeitungsmethoden scikit-learn.org/stable/modules/preprocessing.html
mork
2

Normalisierung ist wichtiger, wenn Sie mehr als eine abhängige Variable haben. Wenn Sie sich das Streudiagramm ansehen, sehen Sie Ausreißer. Ein neuronales Netz ohne versteckte Schichten ist dasselbe wie ein lineares Regressionsmodell. Somit passt es die beste Linie an, um den Abstand der Residuen zu minimieren. Entfernen Sie Ausreißer und es wird angemessener aussehen.

Samuel Sherman
quelle