Klicken Sie hier für Keras 'Lotterie ab dem Nichts [http://qiita.com/Ishotihadus/items/6ecf5684c2cbaaa6a5ef]
Letztes Mal hat einen groben Datensatz erstellt und grob trainiert.
Die Eingabe hat 5 Dimensionen und jedes Element ist größer oder gleich 0 und kleiner als 1. Die Ausgabe ist eindimensional, -1, wenn die Summe der Eingabeelemente 2,5 oder weniger beträgt, 1, wenn sie größer als 2,5 ist. Führen Sie die sogenannte "Zwei-Klassen-Klassifizierung" durch.
Der Datensatz wurde wie folgt erstellt. Der Ausgang ist 0 oder 1 und wird dann mit 2 zu -1 multipliziert (er wird zu -1 oder 1).
data = np.random.rand(250,5)
labels = (np.sum(data, axis=1) > 2.5) * 2 - 1
Das Modell war wie folgt. Für die Aktivierungsfunktion haben wir tanh verwendet, das einen Wertebereich von -1 bis 1 hat, und für den Verlust haben wir den Scharnierverlust verwendet, der gut für das Vorzeichen ist.
model = Sequential([Dense(20, input_dim=5, activation='tanh'), Dense(1, activation='tanh')])
model.compile('adam', 'hinge', metrics=['accuracy'])
Wie in Teil 1 erwähnt, setzt das sequentielle Modell einfach Pfeile auf jeden Knoten der aktuellen Ebene von allen Knoten der vorherigen Ebene. Es ist ein Bild, das zieht. Sicher, es funktioniert immer noch als neuronales Netzwerk, aber es ist ein bisschen uninteressant.
Die funktionale API löst dieses Problem. Sie können ziemlich komplizierte Dinge tun, z. B. die Ausgabe von zwei neuronalen Netzen eingeben oder Schichten gemeinsam nutzen.
Erstellen wir ein neuronales Netzwerk mit der gleichen Form wie beim letzten Mal. Da es die gleiche Form hat, scheint es bedeutungslos, es zu machen, aber das ist Übung.
Die funktionale API lautet einfach "Sie können die Verbindung der Pfeile durcheinander bringen". Im sequentiellen Modell konnte dies nur in Form von A → B → C erfolgen. Aber mit der funktionalen API
A ↘ C → D → E ↗ B
Sie werden in der Lage sein, so etwas zu tun. Ich werde es diesmal nicht tun.
Erstens ist die Eingabeebene.
from keras.layers import Input, Dense
from keras.models import Model
inputs = Input(shape=(5,))
Diese Ebene heißt Input, aber leider gibt es keine Dokumentation.
shape
repräsentiert die Dimension der Eingabe.
Die Notation (5,)
fühlt sich wie etwas an, das Sie über Python nicht wissen, aber es ist nur ein Tupel (wie ein Array), das nur das Element 5 enthält. Es sieht so aus, als gäbe es aufgrund des Kommas mehrere Elemente, aber es gibt nur ein Element. Es ist, weil es nicht von einer Zahl ohne Komma zu unterscheiden ist, aber ich denke, es ist wirklich eine verdammte Notation. Python gefällt das nicht.
x = Dense(20, activation='tanh')(inputs)
Eine Schicht mit 20 Knoten und Eingängen.
Dicht bedeutet "dicht", aber ich denke, es ist in diesem Sinne dicht, weil es alle Pfeile von allen Knoten in der vorherigen Ebene zu allen Knoten in dieser Ebene zieht.
predictions = Dense(1, activation='tanh')(x)
Dies entspricht fast der verborgenen Ebene. Keine Erklärung erforderlich.
Was bedeutet funktional?
Wenn Sie genau hinschauen, können Sie sehen, dass Dense
diese Instanz als Funktion aufruft.
Die Dokumentation besagt, dass das Aufrufen einer Layer-Instanz als Funktion einen Tensor zurückgibt.
Erstens ist ein neuronales Netzwerk ungefähr ein Tensorprodukt (oder auf einfachere Weise ein Matrixprodukt). Das Multiplizieren des Eingabevektors mit einer Matrix und das anschließende Multiplizieren mit einer Matrix ... ist in erster Linie die Essenz. Das Durchlaufen einer einzelnen Ebene entspricht in etwa dem Ausführen einer einzelnen Matrix. Das Bild der Multiplikation der Matrix (Tensor) wird mit dem Funktionsaufruf verglichen.
Wenn eine Funktion aufgerufen wird, wird der Eingangstensor mit der angegebenen Bedeutung transformiert und erneut als Tensor ausgegeben. Ich denke, es ist leicht zu verstehen, wenn Sie es mit dieser Art von Bild aufnehmen.
Ich sage nichts genau, also ist es das.
Übrigens gibt in erster Linie nur die Ebene "Eingabe" einen Tensor zurück (Sie benötigen also keinen Funktionsaufruf).
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
data = np.random.rand(250,5)
labels = (np.sum(data, axis=1) > 2.5) * 2 - 1
inputs = Input(shape=(5,))
x = Dense(20, activation='tanh')(inputs)
predictions = Dense(1, activation='tanh')(x)
model = Model(input=inputs, output=predictions)
model.compile('adam', 'hinge', metrics=['accuracy'])
model.fit(data, labels, nb_epoch=150, validation_split=0.2)
test = np.random.rand(200, 5)
predict = np.sign(model.predict(test).flatten())
real = (np.sum(test, axis=1) > 2.5) * 2 - 1
print(sum(predict == real) / 200.0)
Abgesehen davon, wie man es schreibt, ist es genau das gleiche wie Teil 2, daher denke ich, dass es fast die gleiche Genauigkeit haben wird.
Recommended Posts