Machine Learning von Grund auf · Lektion 7.1 · 32 von 33 fertigen Lektionen · 12 Min.
Neuronale Netze: viele einfache Einheiten im Verbund
Kurz gesagt
Ein neuronales Netz stapelt einfache Einheiten, die je eine Gerade ziehen und knicken. Mit mehr verborgenen Einheiten biegen sich die Grenzen um Iris-Blüten.
Aufwärmen Zwei Fragen aus früheren Lektionen. Eine Minute, und sie blockiert die Lektion nicht.
Die logistische Regression aus Lektion 5 kann nur eine gerade Grenze ziehen. Bäume können nur Kästen zeichnen. Aber was, wenn sich die Klassen umeinander winden? Du könntest versuchen, für jedes Problem von Hand die richtige Kurve zu erfinden – oder du baust ein Modell aus Bausteinen, die so einfach sind, dass jeder nur eine Gerade ziehen kann, und lässt die Kombination alles Mögliche zeichnen. Das ist die Wette hinter neuronalen Netzen. Probier es zuerst selbst aus, bevor du die Erklärung liest.
Wähle eine Antwort und wie sicher du bist.
Antworte, um das Labor freizuschalten.
Interaktives Labor
Dieses interaktive Labor läuft im Browser mit aktiviertem JavaScript. Der Text drumherum beschreibt, was es zeigt.
Antwort anzeigen
Richtige Antwort: Sie steigt nicht und kann sogar sinken, obwohl das Training besser wird
Zwei Neuronen erreichen im Test 81,3 %, 32 Neuronen nur 70,7 %, obwohl die Trainingsgenauigkeit von 81,3 % auf 94,7 % steigt. Das größere Netz passt sich an zufällige Einzelheiten der 75 Trainingsblumen an. Zwei der drei Arten überlappen sich in diesen beiden Messwerten, eine perfekte Trennung gibt es also ohnehin nicht.
Probier es aus
- Stell den Regler für die verborgenen Einheiten auf den kleinsten Wert und drück auf Trainieren. Sieh dir die Entscheidungsbereiche an: Wie viele gerade Kanten erkennst du?
- Erhöhe die Zahl der verborgenen Einheiten und drück erneut auf „Trainieren“. Beobachte, wie sich die Grenzen biegen, und vergleiche die Genauigkeit.
- Stell den Regler für die verborgenen Einheiten auf den größten Wert und trainiere. Beginnen sich die Bereiche um einzelne Blüten zu biegen? Frag dich, ob eine neue Blüte in so einer Ausbuchtung wirklich zu dieser Art gehören würde.
- Sieh dir die Blüten an, bei denen sich zwei Arten überlappen. Kann irgendeine Grenze sie mit nur diesen beiden Messwerten trennen?
Die Idee in einfachen Worten
Ein neuronales Netz besteht aus kleinen Einheiten, den Neuronen. Jedes Neuron tut etwas, das wir schon kennen: Es bildet eine gewichtete Summe seiner Eingaben, addiert einen Achsenabschnitt und schickt das Ergebnis durch eine einfache Knickfunktion, die Aktivierungsfunktion. Ein einzelnes Neuron ist fast eine logistische Regression; es kann die Ebene mit einer Geraden teilen.
Neuronen sind in Schichten angeordnet. Die Eingaben (hier zwei Messwerte einer Blüte) speisen eine verborgene Schicht (Hidden Layer) von Neuronen, von denen jedes seine eigene Gerade zieht und meldet, wie weit und auf welcher Seite ein Punkt liegt. Die Ausgabeschicht fasst diese Meldungen zur endgültigen Entscheidung zusammen. Weil jedes verborgene Neuron sein Signal knickt, entstehen durch ihre Kombination Grenzen mit Ecken und Kurven.
Stell dir ein Team sehr einfacher Wachposten vor, die ein Feld bewachen. Jeder Posten kann nur sagen „der Eindringling ist links“ oder „rechts von meinem Zaun“ – einem einzigen geraden Zaun. Ein Posten allein nützt wenig. Aber eine Chefin, die vielen Posten zuhört, deren Zäune an verschiedenen Stellen stehen, kann Bereiche fast jeder Form eingrenzen.
Warum es funktioniert
Ein Neuron berechnet
Ausgabe = f(w · x + b)
Dabei ist x die Liste der Eingaben, w sind die Gewichte, b ist der Achsenabschnitt und f die Aktivierungsfunktion. Ohne f wäre das Stapeln von Schichten sinnlos: Eine gewichtete Summe aus gewichteten Summen ist immer noch nur eine gewichtete Summe, also würde das ganze Netz eine einzige Gerade ziehen. Die Aktivierung ist der Knick, der bleibt. Mit ihr fügt jedes verborgene Neuron eine Biegung hinzu, und genügend Biegungen können jede vernünftige Grenze annähern. Mehr verborgene Einheiten bedeuten mehr mögliche Biegungen – mehr Flexibilität, und die ist, wie Lektion 7 gezeigt hat, ein zweischneidiges Schwert.
Die Gewichte werden mit den Werkzeugen aus den Lektionen 4 und 5 gelernt. Das Netz macht Vorhersagen, der Log-Loss misst, wie falsch sie sind, und der Gradientenabstieg schiebt jedes Gewicht bergab. Der einzige neue Trick ist, wie man den Gradienten für Gewichte tief im Inneren des Netzes findet: Ein Algorithmus namens Backpropagation (Fehlerrückführung) wendet die Kettenregel der Differentialrechnung rückwärts vom Ausgang her an, Schicht für Schicht, und sagt jedem Gewicht, wie viel es zum Fehler beigetragen hat.
Das Beispiel in dieser Lektion ist der Iris-Datensatz: 150 Blüten dreier Arten, je 50, berühmt geworden durch Ronald Fishers Arbeit von 1936. Wir nehmen zwei der vier Messwerte, sodass jede Blüte ein Punkt in einer Ebene ist, und das trainierte Netz ordnet jeder Stelle dieser Ebene eine vorhergesagte Art zu.
Die Idee ist alt – Frank Rosenblatt baute 1958 das Perzeptron, ein einzelnes trainierbares Neuron –, aber Netze wurden erst dominant, als Daten, Rechenleistung und Trainingstricks groß genug waren, um viele Schichten zu trainieren.
Häufiger Fehler
„Neuronal“ lässt an ein Gehirn denken, und diese Assoziation führt in die Irre. Ein künstliches Neuron ist eine gewichtete Summe mit Knick, kein Modell einer biologischen Zelle, und ein Netz versteht keine Blumen; es passt eine Funktion an Beispiele an. Der praktische Fehler ist die Annahme, größer sei immer besser. Ein Netz mit vielen verborgenen Einheiten kann auf einem kleinen Datensatz genauso auswendig lernen wie ein tiefer Baum oder ein Polynom hohen Grades. Seine Größe muss mit Validierungsdaten gewählt werden, und beim Training muss man dieselbe Lücke zwischen Trainings- und Testleistung im Auge behalten, die wir in Lektion 7 kennengelernt haben.
Staple genügend Schichten, füttere sie mit genügend Text, und aus einer Vorhersageaufgabe wird etwas, das schreibt. In der letzten Lektion sehen wir, wie ein Netz Sprache lernt, indem es das nächste Wort rät.
Willst du tiefer einsteigen? Der NN-Kurs beginnt mit einem einzigen Neuron (PL).
Quiz
Drei Fragen zur Selbstkontrolle. Wähle eine Antwort oder klappe die Lösung unter der Frage auf. Mit der Tastatur: Pfeiltasten wählen, Enter oder Leertaste bestätigt.
Das Wichtigste
- Ein Neuron ist eine gewichtete Summe plus eine knickende Aktivierungsfunktion.
- Eine verborgene Schicht kombiniert viele einfache Geraden zu gekrümmten Grenzen.
- Die Gewichte werden per Gradientenabstieg gelernt; die Backpropagation liefert den Gradienten für jede Schicht.
- Mehr verborgene Einheiten bedeuten mehr Flexibilität, die mit Validierungsdaten gezügelt werden muss.
Tiefer: Formel, Code, Praxis
Die Mathematik
Ein Neuron berechnet a = f(w·x + b), wobei x die Eingaben enthält, w die Gewichte, b den Achsenabschnitt und f die Aktivierungsfunktion. Eine versteckte Schicht mit h Neuronen ist dasselbe in Matrixform: a = f(W₁x + b₁). Die Ausgabeschicht berechnet dann ŷ = softmax(W₂a + b₂).
- Ohne
ffallen die Schichten zusammen:W₂(W₁x + b₁) + b₂ = (W₂W₁)x + (W₂b₁ + b₂), das ist eine einzige lineare Abbildung. Die Aktivierung macht Tiefe erst nützlich. - Das Training minimiert den Log-Loss
L = −(1/n) Σ log ŷᵢ,yᵢ, wobeiŷᵢ,yᵢdie Wahrscheinlichkeit ist, die das Modell der wahren Art von Blume i gegeben hat. - Backpropagation ist die Kettenregel, von der Ausgabe rückwärts angewendet:
∂L/∂W₁ = ∂L/∂ŷ · ∂ŷ/∂a · ∂a/∂W₁. - Der Gradientenabstieg aktualisiert dann jedes Gewicht:
w ← w − η · ∂L/∂w, wobeiηdie Lernrate ist.
Im Code (Python)
Ein kleines Netz auf den Daten des Labs: zwei Kelchblatt-Messwerte, die Hälfte der Blüten fürs Training (75), standardisierte Eingaben, tanh-Einheiten, 2 und 32 versteckte Einheiten. Das ist der Trainer von scikit-learn, nicht der des Labs:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X, y = load_iris(return_X_y=True)
X = X[:, :2] # Kelchblattlänge und Kelchblattbreite, wie im Lab
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.5, stratify=y, random_state=1)
for h in (2, 32):
net = make_pipeline(StandardScaler(), MLPClassifier(hidden_layer_sizes=(h,), activation="tanh", solver="lbfgs", max_iter=5000, random_state=0))
net.fit(X_tr, y_tr)
print(f"{h:2d} hidden units: train {net.score(X_tr, y_tr):.1%}, test {net.score(X_te, y_te):.1%}")
Ausgabe
2 hidden units: train 84.0%, test 74.7%
32 hidden units: train 96.0%, test 66.7%
Das Muster ist das der Lektion: Das größere Netz passt die Trainingsblüten besser an und schneidet auf den Testblüten schlechter ab. Der eigene Trainer des Labs (Gradientenabstieg mit Momentum) ergibt für 2 und 32 Einheiten 81,3 % und 70,7 % auf dem Testset, die Zahlen unterscheiden sich also, das Muster aber nicht.
Notebook herunterladen (.ipynb). Öffne es in Jupyter oder lade es in Google Colab hoch; fehlende Daten lädt es selbst.
Für die Praxis
- Standardisiere die Eingaben vor dem Training (ziehe den Mittelwert der Trainingsdaten ab, teile durch die Standardabweichung der Trainingsdaten). Unskalierte Merkmale machen den Gradientenabstieg langsam oder instabil.
- Wähle die Zahl der versteckten Einheiten auf Validierungsdaten, nicht nach der Trainingsgenauigkeit. Ein größeres Netz passt das Trainingsset fast immer besser an (oben 96,0 % gegen 84,0 %).
- Kleine Datensätze, wie 75 Trainingsblüten, lassen sich leicht auswendig lernen. Probiere ein kleineres Netz, Weight Decay oder frühes Stoppen, bevor du Einheiten hinzufügst.
- Verschiedene zufällige Anfangsgewichte ergeben verschiedene Netze. Lege für einen fairen Vergleich die verwendeten Seeds fest und vergleiche über mehrere von ihnen.
- Bei tabellenförmigen Daten sind gradientenverstärkte Bäume oft die stärkere Baseline. Probiere sie aus, bevor du zu einem Netz greifst.
War das hilfreich?
Danke! Das hilft uns, besser zu werden.
Mehr im Atlas
Einträge der Enzyklopädie zu den Ideen dieser Lektion: