Ich hatte die Möglichkeit, das mehrschichtige Perceptron in Python zu kratzen, also lasse ich es.
Das Folgende ist ein Beispiel, wenn die exklusive logische Summe (XOR) mit einem mehrschichtigen Perzeptron trainiert wird. Wenn Sie Pech haben, konvergiert das Lernen nicht, aber wenn Sie es wiederholen, werden Sie feststellen, dass es richtig gemacht wird.
Das Bild von Perceptron, das dieses Mal aufgenommen wurde, ist so.
Dies ist das eigentliche Programm.
perceptron.py
import numpy as np
#Vektorisiert(Wird für jedes Element der Liste verarbeitet)Sigmaid-Funktion
@np.vectorize
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
# [0,0,0]Oder[[0,0,0]]Eine Liste des Formulars[[0],[0],[0]]Funktion zum Konvertieren in das Format
def verticalize(row):
return np.reshape(row, (1, len(row)))
#Lernrate
rho = 1
#Eingabedaten
#Diese Daten erschöpfen alle Eingabemuster
x = np.array([[0, 0, -1], [0, 1, -1], [1, 0, -1], [1, 1, -1]])
#Lehrerdaten
# 0,Die Ausgabe von 1 entspricht dem Index
#Wo 1 steht, ist die Bedeutung des richtigen Antwortetiketts
y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]])
#Bestimmen Sie das Gewicht nach dem Zufallsprinzip
w1 = np.random.randn(3, 2)
w2 = np.random.randn(3, 2)
#Dieses Mal werden wir zwei Neuronen der Ausgangsschicht vorbereiten und sie auf ein Klassifizierungsproblem mit zwei Klassen reduzieren, ob die Ausgabe 0 oder 1 ist.
#Dies ermöglicht die Anwendung allgemeiner mehrschichtiger Perzeptronberechnungen.
#Wenn Sie es 50.000 Mal wiederholen, scheint es genug zu konvergieren. Lassen Sie uns dies also so oft lernen
for i in range(50000):
# x(Eingabedaten)Ist m*n Matrix.
#Jede Zeile repräsentiert ein Datenelement und jede Spalte repräsentiert ein Feature
#Nehmen Sie jeweils eine Zeile heraus und aktualisieren Sie das Gewicht(Online lernen)
for p in range(len(x)):
#Ändern Sie x vertikal für die Matrixberechnung
# [[x1], [x2], [b1]]Fühle mich wie
xp = verticalize(x[p])
yp = y[p]
#Das Matrixprodukt aus Eingabedaten und Gewichten von der Eingabeebene zur verborgenen Ebene wird durch die Sigmoidfunktion geleitet
#Dieses Ergebnis ist der Ausgabewert jedes Neurons in der verborgenen Schicht
g1 = sigmoid(xp @ w1)
#Fügen Sie dem obigen Ergebnis einen Bias-Term hinzu und ordnen Sie ihn vertikal an
# [[h1],[h2],[b2]]Fühle mich wie
#Bias Begriff ist immer-Ausgabe 1
g1 = verticalize(np.hstack((g1[0], [-1])))
#Versteckte Ebenenausgabe+Vorspannungsausgabe und Matrixprodukt der Gewichte von der Ausgabeschicht zur verborgenen Schicht durch Sigmoidfunktion
#Dieses Ergebnis ist der Ausgabewert jedes Neurons in der Ausgabeschicht
g2 = sigmoid(g1 @ w2)
#Berechnen Sie den Gewichtsfehler von der verborgenen Schicht zur Ausgabeschicht mit der Methode der Fehlerrückübertragung
eps_out = (g2 - yp) * g2 * (1 - g2)
#Berechnen Sie den Gewichtsfehler von der verborgenen Schicht zur Eingabeebene mit der Methode der Fehlerrückübertragung
#Der Bias-Term wird in der Berechnung gemischt. Löschen Sie ihn daher.
eps_hidden = np.delete(np.sum(eps_out*w2, axis=1)*g1*(1 - g1), -1, 1)
#Gewichtsaktualisierung
w2 -= rho * g1.T @ eps_out
w1 -= rho * xp.T @ eps_hidden
#Überprüfen Sie das Ergebnis(Prognose)
#Berechnen Sie nur die Vorwärtsbewegung und sehen Sie den Ausgabewert
for p in range(len(x)):
xp = verticalize(x[p])
yp = y[p]
g1 = sigmoid(xp @ w1)
g1 = verticalize(np.hstack((g1[0], [-1])))
g2 = sigmoid(g1 @ w2)
#Überprüfen Sie den Ausgabewert der Ausgabeebene
print(g2[0])
#Ausgabe des Index mit dem höchsten Wert in der Ausgabeebene
#Ich habe gelernt, anhand des Index zu klassifizieren, damit dies die Klasse bestimmen kann
print(np.argmax(g2))
Die Punkte sind die vektorisierte Sigmoidfunktion und der @ -Operator, der np.dot entspricht. Jetzt können Sie es ordentlich implementieren, ohne zu verschachteln.
Wenn Sie die Gewichtsschicht entsprechend ändern, können Sie meiner Meinung nach vielseitig sein.
Ich finde es sieht ziemlich gut aus.
Wenn Sie den Kommentar weglassen, sieht es so aus.
perceptron.py
import numpy as np
@np.vectorize
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def verticalize(row):
return np.reshape(row, (1, len(row)))
rho = 1
x = np.array([[0, 0, -1], [0, 1, -1], [1, 0, -1], [1, 1, -1]])
y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]])
w1 = np.random.randn(3, 2)
w2 = np.random.randn(3, 2)
for i in range(50000):
for p in range(len(x)):
xp = verticalize(x[p])
yp = y[p]
g1 = sigmoid(xp @ w1)
g1 = verticalize(np.hstack((g1[0], [-1])))
g2 = sigmoid(g1 @ w2)
eps_out = (g2 - yp) * g2 * (1 - g2)
eps_hidden = np.delete(np.sum(eps_out*w2, axis=1)*g1*(1 - g1), -1, 1)
w2 -= rho * g1.T @ eps_out
w1 -= rho * xp.T @ eps_hidden
for p in range(len(x)):
xp = verticalize(x[p])
yp = y[p]
g1 = sigmoid(xp @ w1)
g1 = verticalize(np.hstack((g1[0], [-1])))
g2 = sigmoid(g1 @ w2)
print(g2[0])
print(np.argmax(g2))
Verwenden wir scikit-learn! (Das kann ich nicht sagen, weil es ein Universitätsproblem ist)
Ich habe auch etwas geschrieben, das als Klasse mit erhöhter Vielseitigkeit implementiert wurde, also werde ich es hinzufügen! Ihr mehrschichtiges Perzeptron ist verschmutzt