Falls das hier im falschen Unterforum ist, könnt ihr es gerne verschieben, ich poste es mal hier und nicht im "Wissenschaftliches Rechnen"-Bereich weil es eher um den Inhalt und nicht um die Bibliotheken geht.
Habe ein ganz einfaches künstliches neuronales Netz mit Python und Numpy programmiert, mit nur einer versteckten Schicht und nur einem Ausgabeneuron (falls das der richtige Begriff ist). Also für Regression.
Ich habe gehört dass es da ausgereifte Bibliotheken für gibt, aber es geht darum etwas zu lernen. Also dass nicht nur das Netz etwas lernt sondern auch ich.
Dafür habe ich Kapitel 11.3 dieses Buches benutzt: https://web.stanford.edu/~hastie/ElemStatLearn/
Code: Alles auswählen
import numpy as np
class NeuronalesNetz:
"""Neuronales Netz für Regression.
Aktivierungsfunktion ist 1/(1+e^-x).
Es gibt nur ein Ausgabeneuron.
Die Werte der versteckten Neuronen werden für das Ausgabeneuron nur
linearkombiniert, und nicht durch eine weitere Funktion durchgedrückt."""
def __init__(self, anz_eingaben, anz_versteckte):
self.anz_eingaben = anz_eingaben
self.anz_versteckte = anz_versteckte
# gewichte_vorn heißen im Buch alpha
self.gewichte_vorn = np.random.rand(anz_versteckte, anz_eingaben+1) / 10 - 0.05
# gewichte_hinten heißen im Buch beta
self.gewichte_hinten = np.random.rand(1+anz_versteckte) / 10 - 0.05
def versteckte_werte(self, eingabewerte):
"""Eingabe: eine Matrix, jede Zeile entspricht einem Eingabepunkt,
jede Spalte entspricht einem Eingabeneuron.
Berechnet die Werte der Zwischenschicht, im Buch Z genannt"""
eingabewerte = np.array(eingabewerte)
assert len(eingabewerte.shape) == 2 and eingabewerte.shape[1] == self.anz_eingaben
aktivierungsfunktion = lambda x: 1 / (1 + np.exp(-x))
eingaben_mit_1 = np.hstack([np.ones([eingabewerte.shape[0], 1]), eingabewerte])
return aktivierungsfunktion(self.gewichte_vorn @ eingaben_mit_1.T)
def auswerten(self, eingabewerte):
return self.auswerten_für_training(eingabewerte)[1]
def auswerten_für_training(self, eingabewerte):
"""Gibt Werte der Zwischenschicht und Endergebnisse"""
versteckte_werte = self.versteckte_werte(eingabewerte)
return (versteckte_werte,
self.gewichte_hinten[1:] @ versteckte_werte + self.gewichte_hinten[0])
def trainingsschritt(self, eingaben, ausgaben, lernrate, decayparameter=0):
"""´´eingaben´´ soll eine Matrix sein, ´´ausgaben´´ soll ein 1d-Array sein was so viele
Einträge hat wie ´´eingaben´´ Zeilen hat.
Batch-Backpropagation mit Weight Decay."""
versteckte_werte, ergebnisse = self.auswerten_für_training(eingaben)
# fehler_hinten heißen im Buch delta
fehler_hinten = -2 * (ausgaben - ergebnisse)
# fehler_mitte heißen im Buch s
abgeleitete_aktivierungsfunktion = lambda x: np.exp(-x) / (1 + np.exp(-x)) **2
fehler_mitte = ((abgeleitete_aktivierungsfunktion(self.gewichte_vorn[:, 1:] @ eingaben.T)
* fehler_hinten).T * self.gewichte_hinten[1:]).T
self.gewichte_hinten[1:] -= lernrate * (versteckte_werte @ fehler_hinten
+ 2 * decayparameter * self.gewichte_hinten[1:])
self.gewichte_vorn[:, 1:] -= lernrate * (fehler_mitte @ eingaben
+ 2 * decayparameter * self.gewichte_vorn[:, 1:])
if __name__ == "__main__":
nn = NeuronalesNetz(3, 20)
#print(nn.auswerten_für_training([[1,2,3],[3,2,1]]))
for i in range(1000):
nn.trainingsschritt(np.array([[1,2,3], [2,3,4]]), np.array([1, 3]), .1)
print(nn.auswerten(np.array([[1,2,3], [2,3,4]])))
Ist das normal so? Hab ich was falsch gemacht? Soll das die künstliche Intelligenz sein, von der alle reden?
Irgendwie ist das aber auch Quatsch was ich da ausprobiere. Vielleicht wären die Ergebnisse bei einer richtigen Regression auf verrauschten Daten besser. Aber die verschiebe ich auf morgen.
Weitere Rückmeldung ist willkommen.