"Was denkst du über diesen Kerl?"
"Sehr hübsch ..."
Ein Gefühl herauszukommen.
Ich hatte die Gelegenheit, das mehrschichtige Perceptron zu kratzen, daher ist dies ein zusammenfassender Artikel.
Dieses Mal habe ich es geschrieben, damit Sie mit einer Oberfläche wie scicit-learn lernen können, während Sie es schön und allgemein gestalten.
Fast alle Parameter wie die Anzahl der ausgeblendeten Ebenen, die Anzahl der Knoten, die Anzahl der Lernvorgänge, die Lernrate usw. können durch Übergeben von Argumenten angepasst werden. Es gibt Hinweise auf eine Herausforderung bei der Chargennormalisierung, die jedoch mithilfe der Verteilung nicht erfolgreich normalisiert wurde.
Dieser Artikel enthält einen nicht allgemeinen, aber prägnanten Artikel.
Wenn Sie es so machen, dass Sie etwas bis zu einem gewissen Grad verwenden können, wird es schließlich kompliziert. Ich möchte es schöner machen. Das Folgende ist derjenige, der das mehrschichtige Perceptron trainiert hat, um die exklusive logische Summe zu lernen (oft gesehen).
mlp.py
import numpy as np
class MultilayerPerceptron:
def __init__(self, featureNum, rho, classNum, hidden, normalization=True):
self.featureNum = featureNum
self.rho = rho
self.classNum = classNum
self.hidden = hidden
self.normalization = normalization
rc = [self.featureNum]+self.hidden+[self.classNum]
self.W = [np.random.randn(rc[i]+1, rc[i+1]) for i in range(len(hidden)+1)]
self.h = [[] for _ in range(len(self.hidden)+1)]
self.g = [[] for _ in range(len(self.hidden)+1)]
def fit(self, X, y, learn_times=1000, batch_size="full"):
self.X = np.array(X)
one = np.ones((len(self.X), 1))
self.learn_times = learn_times
self.X_train_mean = np.sum(self.X, axis=0)/len(self.X)
self.X_train_sigma = np.var(self.X, axis=0)**0.5
if (self.normalization):
self.X = (self.X - self.X_train_mean)/self.X_train_sigma
self.X = np.hstack((self.X, one))
self.y = np.tile(y, (1, 1))
self.eps = [[] for _ in range(len(self.hidden)+1)]
self.sigmoid = np.vectorize(lambda x: 1.0 / (1.0 + np.exp(-x)))
self.batch_size = len(self.X) if (batch_size == "full") else int(batch_size)
for _ in range(self.learn_times):
self.shuffled_index = np.random.permutation(len(self.X))
self.X_shuffled = self.X[self.shuffled_index]
self.y_shuffled = self.y[self.shuffled_index]
self.X_batch_list = np.array_split(self.X_shuffled, len(self.X)//self.batch_size, 0)
self.y_batch_list = np.array_split(self.y_shuffled, len(self.y)//self.batch_size, 0)
for p in range(len(self.X_batch_list)):
self.X_batchp = self.X_batch_list[p]
self.y_batchp = self.y_batch_list[p]
self.X_batch_mean = np.sum(self.X_batchp, axis=0) / self.batch_size
one_batchp = np.ones((len(self.X_batchp), 1))
#Die Aktivierungsfunktion der Eingabeschicht wird nicht berechnet,Berechnen Sie eine andere Ausgabe als die Eingabeebene
self.h[0] = self.X_batchp @ self.W[0]
self.g[0] = np.hstack((self.sigmoid(self.h[0]), one_batchp))
for j in range(1,len(self.hidden)):
#Da die Gewichte bereits in der richtigen Form erzeugt werden, wenn die Gewichte erzeugt werden,Führen Sie einfach die Matrixoperation in Vorwärtsausbreitungsrichtung aus
self.h[j] = self.g[j-1] @ self.W[j]
#Wenn die Ausgabe nicht die letzte Ebene ist, kleben Sie 1 seitlich, um dem erweiterten Gewichtsvektor zu entsprechen
self.g[j] = np.hstack((self.sigmoid(self.h[j]), one_batchp))
self.h[-1] = self.g[-2] @ self.W[-1]
self.g[-1] = self.sigmoid(self.h[-1])
#Die Ausgabe der Eingabeebene ist,Gleicher Wert wie wenn die Aktivierungsfunktion als gleiche Funktion angesehen wird,Daher ist es ausreichend zu verzweigen, damit der Wert der Eingabeebene nur bei der Berechnung des Fehlers mit der Eingabeebene verwendet wird.
self.eps[-1] = np.array((self.g[-1] - self.y_batchp) * self.g[-1]*(1-self.g[-1]))
for j in range(1, len(self.eps)):
#Für das Matrixprodukt aus Gewichten und Fehlern,Nimm das Element Produkt
#Weil die letzte Spalte des Gewichtsvektors Bias ist,Von der vorderen Schicht,Sie können die Verzerrung der vorherigen Ebene nicht sehen
#Löschen Sie also die letzte Spalte
self.eps[-(j+1)] = self.eps[-j] @ self.W[-j].T * self.g[-(j+1)]*(1-self.g[-(j+1)])
self.eps[-(j+1)] = np.delete(self.eps[-(j+1)], -1, axis=1)
self.W[0] -= self.rho * self.X_batchp.T @ self.eps[0] / len(self.X_batchp)
for j in range(1, len(self.hidden)+1):
self.W[j] -= self.rho * self.g[j-1].T @ self.eps[j] / len(self.X_batchp)
def pred(self, X_test):
self.X_test = np.array(X_test)
one = np.ones((len(self.X_test), 1))
if (self.normalization):
self.X_test = (self.X_test - self.X_train_mean)/self.X_train_sigma
self.X_test = np.hstack((self.X_test, one))
self.h[0] = self.X_test @ self.W[0]
self.g[0] = np.hstack((self.sigmoid(self.h[0]), one))
for j in range(1, len(self.hidden)):
self.h[j] = self.g[j-1] @ self.W[j]
self.g[j] = np.hstack((self.sigmoid(self.h[j]), one))
self.h[-1] = self.g[-2] @ self.W[-1]
self.g[-1] = self.sigmoid(self.h[-1])
return np.argmax(self.g[-1], axis=1)
def score(self, X_test, y_test):
self.X_test = np.array(X_test)
self.y_test = np.array(y_test)
self.loss_vector = (np.argmax(np.array(self.y_test),axis=1) == self.pred(self.X_test))
return np.count_nonzero(self.loss_vector)/len(self.X_test)
#Bias (Anfangsgewicht ist 1) wird zu den Neuronen in der verborgenen Schicht hinzugefügt.
mlp = MultilayerPerceptron(featureNum=2, rho=1, classNum=2, hidden=[4, 3])
x = [[0, 0], [0, 1], [1, 0], [1, 1]]
y = [[1, 0], [0, 1], [0, 1], [1, 0]]
mlp.fit(x, y, 1000, 2)
print(mlp.pred(x))
print(mlp.score(x, y))
Klicken Sie hier für die Version ohne Kommentare
mlp.py
import numpy as np
class MultilayerPerceptron:
def __init__(self, featureNum, rho, classNum, hidden, normalization=True):
self.featureNum = featureNum
self.rho = rho
self.classNum = classNum
self.hidden = hidden
self.normalization = normalization
rc = [self.featureNum]+self.hidden+[self.classNum]
self.W = [np.random.randn(rc[i]+1, rc[i+1]) for i in range(len(hidden)+1)]
self.h = [[] for _ in range(len(self.hidden)+1)]
self.g = [[] for _ in range(len(self.hidden)+1)]
def fit(self, X, y, learn_times=1000, batch_size="full"):
self.X = np.array(X)
one = np.ones((len(self.X), 1))
self.learn_times = learn_times
self.X_train_mean = np.sum(self.X, axis=0)/len(self.X)
self.X_train_sigma = np.var(self.X, axis=0)**0.5
if (self.normalization):
self.X = (self.X - self.X_train_mean)/self.X_train_sigma
self.X = np.hstack((self.X, one))
self.y = np.tile(y, (1, 1))
self.eps = [[] for _ in range(len(self.hidden)+1)]
self.sigmoid = np.vectorize(lambda x: 1.0 / (1.0 + np.exp(-x)))
self.batch_size = len(self.X) if (batch_size == "full") else int(batch_size)
for _ in range(self.learn_times):
self.shuffled_index = np.random.permutation(len(self.X))
self.X_shuffled = self.X[self.shuffled_index]
self.y_shuffled = self.y[self.shuffled_index]
self.X_batch_list = np.array_split(self.X_shuffled, len(self.X)//self.batch_size, 0)
self.y_batch_list = np.array_split(self.y_shuffled, len(self.y)//self.batch_size, 0)
for p in range(len(self.X_batch_list)):
self.X_batchp = self.X_batch_list[p]
self.y_batchp = self.y_batch_list[p]
self.X_batch_mean = np.sum(self.X_batchp, axis=0) / self.batch_size
one_batchp = np.ones((len(self.X_batchp), 1))
self.h[0] = self.X_batchp @ self.W[0]
self.g[0] = np.hstack((self.sigmoid(self.h[0]), one_batchp))
for j in range(1,len(self.hidden)):
self.h[j] = self.g[j-1] @ self.W[j]
self.g[j] = np.hstack((self.sigmoid(self.h[j]), one_batchp))
self.h[-1] = self.g[-2] @ self.W[-1]
self.g[-1] = self.sigmoid(self.h[-1])
self.eps[-1] = np.array((self.g[-1] - self.y_batchp) * self.g[-1]*(1-self.g[-1]))
for j in range(1, len(self.eps)):
self.eps[-(j+1)] = self.eps[-j] @ self.W[-j].T * self.g[-(j+1)]*(1-self.g[-(j+1)])
self.eps[-(j+1)] = np.delete(self.eps[-(j+1)], -1, axis=1)
self.W[0] -= self.rho * self.X_batchp.T @ self.eps[0] / len(self.X_batchp)
for j in range(1, len(self.hidden)+1):
self.W[j] -= self.rho * self.g[j-1].T @ self.eps[j] / len(self.X_batchp)
def pred(self, X_test):
self.X_test = np.array(X_test)
one = np.ones((len(self.X_test), 1))
if (self.normalization):
self.X_test = (self.X_test - self.X_train_mean)/self.X_train_sigma
self.X_test = np.hstack((self.X_test, one))
self.h[0] = self.X_test @ self.W[0]
self.g[0] = np.hstack((self.sigmoid(self.h[0]), one))
for j in range(1, len(self.hidden)):
self.h[j] = self.g[j-1] @ self.W[j]
self.g[j] = np.hstack((self.sigmoid(self.h[j]), one))
self.h[-1] = self.g[-2] @ self.W[-1]
self.g[-1] = self.sigmoid(self.h[-1])
return np.argmax(self.g[-1], axis=1)
def score(self, X_test, y_test):
self.X_test = np.array(X_test)
self.y_test = np.array(y_test)
self.loss_vector = (np.argmax(np.array(self.y_test),axis=1) == self.pred(self.X_test))
return np.count_nonzero(self.loss_vector)/len(self.X_test)
mlp = MultilayerPerceptron(featureNum=2, rho=1, classNum=2, hidden=[4, 3])
x = [[0, 0], [0, 1], [1, 0], [1, 1]]
y = [[1, 0], [0, 1], [0, 1], [1, 0]]
mlp.fit(x, y, 1000, 2)
print(mlp.pred(x))
print(mlp.score(x, y))
Böser Kleber und Schwung, und entkommen Sie der Realität vor dem Test.
Recommended Posts