Navigation: 🤖 Teil 1 - 🤖 Teil 2 - 🤖 Teil 3 - 🤖 Teil 4Loading ⌛Loading ⌛

🤖 Wie funktioniert maschinelles Lernen 4

1. Was ist in der Black Box drin?

Wenn du mathematisch noch nicht so bewandert bist, darfst du die Formeln in diesem Kapitel ohne schlechtes Gewissen überfliegen.
Lies jedoch auf alle Fälle diejenigen Textpassagen, welche mit einem ℹ️ gekennzeichnet sind.


ℹ️ In den Teilen 1 - 3 wurden die Machine-Learning-Verfahren als „Black Box“ dargestellt. In diesem Kapitel erfährst du, was in dieser Black Box drin ist und wie diese im Detail funktioniert. Um diese Frage zu beantworten, wirst du dich mit einer weit verbreiteten Variante eines neuronalen Netzes befasssen, dem sogenannten „Feedforward Neural Network (FNN)“. Konkret stecken in der Machine-Learning-Black-Box Zahlen, Formeln und viele Konzepte drin. Daher werden in diesem Kapitel nicht nur Konzepte genannt, es werden auch die entsprechenden Formeln gezeigt. Je nach deinem mathematischen Wissen kannst du die Formeln verstehen oder diese einfach als gegeben ansehen.


1.1 Aufbau eines neuronalen Netzes

ℹ️ Abb.1 zeigt ein neuronales Netz vom Typ „Feedforward Neural Network (FNN)“. Ein FNN ist aus mehreren miteinander verbundenen Neuronen (die Kreise ◯) aufgebaut, welche in mehreren Spalten angeordnet sind. Diese Spalten werden als Schichten (layers) bezeichnet. Die Spalte ganz links ist der Input Layer, die Spalte ganz rechts ist der Output Layer und alle Spalten dazwischen sind Hidden Layers. Die schwarzen Kreise ● bezeichnen spezielle Neuronen, welche immer den Ausgangswert $1$ haben. Sie werden als „Bias“ bezeichnet. Jede Verbindungslinie, welche zwei Neuronen ◯ (oder Bias ● und Neuron ◯) miteinander verbindet, stellt ein Gewicht dar. Im Training werden diese Gewichte angepasst. Der Input Layer ist zwar mit Kreisen ◯ eingezeichnet, jedoch wird in diesen Neuronen nichts verarbeitet, sie leiten die Eingangswerte direkt weiter.

  • Input Layer: Besteht aus mehreren Input-Neuronen, die mit dem Index $h$ von $0$ bis $n_i$ (der Anzahl Input-Neuronen) durchnummeriert werden. Jedes Input-Neuron gibt den zugehörigen Eingangswert $x_h$ weiter. Das Input-Neuron $0$ ist das Bias und gibt stets den Wert $1$ weiter.
  • Hidden Layer: Besteht aus mehreren Hidden-Neuronen, die mit dem Index $i$ von $0$ bis $n_h$ (der Anzahl Hidden-Neuronen) durchnummeriert werden. Jedes Hidden-Neuron gibt den Funktionswert der zugehörigen Aktivierungsfunktion $\phi_i$ weiter. Das Hidden-Neuron $0$ ist das Bias und gibt stets den Wert $1$ weiter.
  • Output Layer: Besteht aus mehreren Output-Neuronen, die mit dem Index $j$ von $1$ bis $n_o$ (der Anzahl Ouput-Neuronen) durchnummeriert werden. Jedes Output-Neuron gibt den Funktionswert der zugehörigen Aktivierungsfunktion $\varphi_j$ als Ausgangswert $y_j$ aus. Im Output Layer gibt es kein Bias.
  • Gewichte: Das Gewicht vom Input-Neuron $h$ zum Hidden-Neuron $i$ ist: $v_{hi}$ . Das Gewicht vom Hidden-Neuron $h$ zum Ouput-Neuron $j$ ist: $w_{ij}$.
Abb.1 FNN mit einem Hidden Layer1) Abb.2 Das Neuron in der Mitte des Hidden Layers2)
  • Neuron: Das Neuron in der Mitte des Hidden Layers ist in Abb.2 abgebildet. Jedes Neuron (abgesehen von den Input-Neuronen und dem Bias) empfängt als „Aktivierung“ die Summe aller Eingänge multipliziert mit den zugehörigen Gewichten. D.h. für das Neuron in der Abb.2 ist die Aktivierung $a = v_{02} \cdot 1 + v_{12} \cdot x_1 + v_{22} \cdot x_2$ . Danach wird die Aktivierung $a$ mit der Aktivierungsfunktion $\phi_2(a)$ verrechnet und der Funktionswert den rechts angeschlossenen Neuronen übergeben.
  • Aktivierungsfunktion: Es kommen in der Praxis verschiedene Aktivierungsfunktionen $\phi(.)$ und $\varphi(.)$ zum Einsatz. Wichtig ist, dass zumindest in einem Layer eine nicht-lineare Funktion verwendet wird (sonst kann das neuronale Netz nicht viel lernen). Ein Beispiel für eine nicht-lineare Aktivierungsfunktion ist die „logistische Funktion“ $f_{\textrm{logistic}}(z) = \frac{1}{1 + e^{-z}}$ . Für die Output-Neuronen kommen manchmal auch lineare Aktivierungsfunktionen zum Einsatz, z.B. die „lineare Funktion“ $f_{\textrm{linear}}(z) = z$ .

ℹ️ Alles kombiniert ergibt sich für jeden Ausgang $y_j$ folgende Formel für ein FNN mit einem Hidden Layer:

$y_j = \varphi_j \left[ \displaystyle\sum_{i=0}^{n_h} w_{ij} \cdot \phi_i \left( \displaystyle\sum_{h=0}^{n_i} v_{hi} \cdot x_h \right) \right]\enspace ,\quad \phi_0(.) = x_0 = 1 , \quad$ (FNN mit einem Hidden Layer).

Dabei bezeichnet das Zeichen $\sum$ eine Summe. Z.B. ist $\sum_{h=0}^{n_i} v_{hi} \cdot x_h$ die Summe aller $v_{hi} \cdot x_h$ mit einem Index $h$ von $0$ bis $n_i$. Für $i = 1$ wird die Summe zu $\sum_{h=0}^{n_i} v_{h1} \cdot x_h = v_{01}\cdot x_0 + v_{11}\cdot x_1 +v_{21}\cdot x_2$. Wird in dieser Formel berücksichtigt, dass das Bias $x_0 = 1$ ist, ergibt sich $\sum_{h=0}^{n_i} v_{h1} \cdot x_h = v_{01} + v_{11}\cdot x_1 +v_{21}\cdot x_2$ .


1.2 Fehlerfunktion

ℹ️ Um das neuronale Netz zu trainieren, braucht es eine Fehlerfunktion $J[k]$ (da zwei verschiedene Buchstaben $v$ und $w$ für die Gewichte verwendet werden, wird nicht $J(w[k])$ geschrieben, sondern nur $J[k]$. Für das FNN in Abb.1 verwenden wir die einfache Fehlerfunktion „squared error (SE)“. Diese wird für jedes Sample (Trainingsbeispiel) einzeln berechnet, und gleich danach (d.h. nach jedem Sample) werden die Gewichte angepasst. Das ist ein anderes Vorgehen, als z.B. für die gebräuchlichere Fehlerfunktion „mean squared error (MSE)“. Beim MSE wird zuerst der Fehler über mehrere Samples gemittelt und erst danach die Gewichte angepasst. Die Formel für den SE ist

$J[k] = \frac{1}{2} \displaystyle\sum_{j=1}^{n_0} (y_j[k]-d_j)^2\quad$ (SE),

Dabei ist $d_j$ der gewünschte Ausgangswert (Desired Output) zum Ausgang $y_j$. Die Differenz zwischen erhaltenem Ausgang $y_j$ und Desired Output $d_j$ bildet die Basis für die Fehlerberechnung. Das Quadrat bei $(y_j[k]-d_j)^2$ sorgt dafür, dass der Fehler eine positive Zahl ist. Zudem werden grosse Differenzen $y_j[k]-d_j$ durch das Quadrat stärker bestraft als kleine. Der Faktor $\frac{1}{2}$ spielt für das Training selber keine Rolle. Er wird jedoch im Gebiet der neuronalen Netze häufig dazu genommen, weil damit die Gleichungen für das Gradientenverfahren vereinfacht werden3).

Falls du wissen möchtest, wie die Formel für den "mean squared error (MSE)" aussieht, hier klicken!


1.3 Lernen der Gewichte

Für das Update der Gewichte $v_{hi}$ und $w_{ij}$ wird das Gradientenverfahren verwendet:

$v_{hi}[k+1] = v_{hi}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial v_{hi}};\quad w_{ij}[k+1] = w_{ij}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial w_{ij}}\quad$ (Gradientenverfahren)

wobei $\frac{\partial J[k]}{\partial v_{hi}}$ und $\frac{\partial J[k]}{\partial w_{ij}}$ die (partiellen) Ableitungen der Fehlerfunktion $J[k]$ nach den Gewichten $v_{hi}$ und $w_{ij}$ bezeichnen und $\mu$ die Lernrate ist. Zusammen bilden alle $\frac{\partial J[k]}{\partial v_{hi}}$ und $\frac{\partial J[k]}{\partial w_{ij}}$ den Gradienten $\nabla$.

Werden als Modell $y_j = \dots$ die Formeln für das FNN mit einem Hidden Layer und als Fehlerfunktion $J[k]$ der SE verwendet, werden die partiellen Ableitungen zu:

$\displaystyle\frac{\partial J[k]}{\partial v_{hi}} = \displaystyle\sum_{j=1}^{n_0}(y_j[k] - d_j) \cdot \varphi'_j(.) \cdot w_{ij}[k] \cdot \phi'_i(.) \cdot x_h[k]; \quad \displaystyle\frac{\partial J[k]}{\partial w_{ij}} = (y_j[k] - d_j) \cdot \varphi'_j(.) \cdot \phi_i(.)\quad$ (partielle Ableitungen)

wobei

$\phi_i(.)= \phi_i\left( \displaystyle\sum_{h=0}^{n_i} v_{hi}[k] \cdot x_h \right); \quad \varphi_j(.) = \varphi_j\left( \displaystyle\sum_{i=0}^{n_h} w_{ij}[k] \cdot \phi_i(.)\right); \quad \phi_0(.) = x_0 = 1$

und $\phi'_i(.)$ und $\varphi'_j(.)$ die Ableitungen von $\phi_i(.)$ und $\varphi_j(.)$ sind.

ℹ️ Auch wenn du die Formeln nicht im Detail verstehen solltest. Für das Update der Gewichte wird ausgehend vom Fehler, welcher am Ausgang berechnet wird, „rückwärts“ (von rechts nach links) durch das neuronale Netz gegangen. Das wird in den Formeln für $\frac{\partial J[k]}{\partial v_{hi}}$ und $\frac{\partial J[k]}{\partial w_{ij}}$ ersichtlich. Dort steht zuerst der Ausgang, d.h. $y_j$ und $d_j$, dann folgt der Output Layer $\varphi_j(.)$, dann allenfalls die Gewichte zwischen Hidden- und Output Layer $w_{ij}$, dann der Hidden Layer $\phi_i(.)$ und allenfalls noch der Input Layer ($x_h$).

ℹ️ Wird ein neuronales Netz mit mehr als einem Hidden Layer verwendet, wird von „Deep Learning“ gesprochen. Bei mehreren Hidden Layern werden alle Formeln entsprechend länger. Da jedoch der Rechenschritt von einem Layer zum nächsten vom Prinzip her immer derselbe ist, können die Berechnungen mit einer Schleife (über alle Hidden Layer) oder mit einer Rekursion programmiert werden.

Falls du wissen willst, wie die Formeln für die partiellen Ableitungen hergeleitet werden, hier klicken!


1.4 Informationsfluss im Feedforward Neural Network

ℹ️ Der Name Feedforward Neural Network (zu Deutsch: „vorwärtsgerichtetes neuronales Netz“) kommt daher, dass in der Anwendungsphase die Information „vorwärts“ von links nach rechts verarbeitet wird. Eine kompakte (rekursive) Formulierung des Gradientenverfahrens für FNN mit mehreren Hidden Layern stellt der sogenannte Backpropagation Algorithmus dar (zu Deutsch: „Rückwärtsverarbeitung“). Der Name weist darauf hin, dass beim Gradientenverfahren, für das Updaten der Gewichte, die Information „rückwärts“ von rechts nach links verarbeitet wird.


ℹ️ ✍ Auftrag Informationsfluss im Feedforward Neural Network

Loading ⌛

👉 Hier lernst du, dass im „Betrieb“ die Information von links nach rechts durch das FNN fliesst (von Eingang zu Ausgang), aber beim Training umgekehrt von rechts nach links (vom Ausgang zum Eingang).

  1. Starte die Animation durch einen Klick auf den Startbutton (mehrfach). Beachte dabei Folgendes.
    • Das FNN verarbeitet Eingangsdaten von links nach rechts verarbeitet (türkis animiert).
    • Ist die Information am Ausgang angelangt, wird mit dem Ausgangswert und dem Desired Output der Fehler berechnet (rot animiert).
    • Anschliessend wird das Fehlersignal rückwärts von rechts nach links vom FNN verarbeiten (rot animiert) und die Gewichte angepasst (gelb animiert).
  2. Markiere diesen Auftrag als „Erledigt!“.


2. Das Gradientenverfahren von Hand durchrechnen

Auch hier darfst du die Formeln ohne schlechtes Gewissen überfliegen. Lies jedoch auch hier die ℹ️ Textpassagen. Den Auftrag kannst du auch ohne Verständnis der Formeln durchrechnen.


ℹ️ In diesem Kapitel geht es darum, einmal von Hand ein ganz einfaches neuronales Netz durchzurechnen. D.h. einen Vorwärtsschritt und den Fehler zu berechnen, anschliessend neue Gewicht-Einstellungen auszurechnen, um am Ende, nach einem zweiten Vorwärtsschritt, einen tieferen Fehler zu erhalten. Dafür verwenden wir das sehr einfache FNN aus Abb.35) und passen die Formeln aus dem letzten Kapitel an dieses FNN an (dadurch werden die Formeln vereinfacht).

Abb.3 Einfaches FNN6)


Als Aktivierungsfunktion $\phi(.)$ wird die logistische Funktion verwendet:

$\phi(z) = \displaystyle\frac{1}{1 + e^{-z}}$

und als Aktivierungsfunktion $\varphi(.)$ die lineare Funktion:

$\varphi(z) = z$ .

Da der Output Layer nur ein Neuron enthält, fällt das Summenzeichen für die Output-Neuronen weg. Und da als Aktivierungsfunktion $\varphi(.)$ die lineare Funktion verwendet wird, kann $\varphi(.)$ ebenfalls weggelassen werden. Somit vereinfacht sich die allgemeine Formel für ein FNN mit einem Hidden Layer (zum Sehen anklicken) zu:

$y_1 = \displaystyle\sum_{i=0}^{n_h} w_{i1} \cdot \phi_i \left( \displaystyle\sum_{h=0}^{n_i} v_{hi} \cdot x_h \right) \enspace ,\quad \phi_0(.) = x_0 = 1$

Die Formel für den SE vereinfacht sich zu:

$J[k] = \displaystyle\frac{1}{2} (y_1[k]-d_1)^2$

Die Formeln für das Gradientenverfahren bleiben bis auf den Umstand, dass es nur ein Hidden- und ein Output-Neuron gibt, gleich ($v_{hi}$ wird zu $v_{h1}$ und $w_{ij}$ zu $w_{i1}$):

$v_{h1}[k+1] = v_{h1}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial v_{h1}}\enspace ;\quad w_{i1}[k+1] = w_{i1}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial w_{i1}}$

Da für die Aktivierungsfunktion $\varphi(.)$ die lineare Funktion verwendet wird und deren Ableitung $\varphi'(.) = 1$ ist, vereinfachen sich die Formel für die partiellen Ableitungen zu:

$\displaystyle\frac{\partial J[k]}{\partial v_{h1}} = (y_1[k] - d_1) \cdot w_{11}[k] \cdot \phi'_1[k](.) \cdot x_h[k]\enspace ; \quad \displaystyle\frac{\partial J[k]}{\partial w_{i1}} = (y_1[k] - d_1) \cdot \phi_i[k](.)$

mit

$\phi_1(.)= \phi_1\left( \displaystyle\sum_{h=0}^{n_i} v_{h1}[k] \cdot x_h \right)\enspace ; \quad x_0 = 1$

Da für $\phi_1(.)$ die logistische Funktion gewählt wurde, wird die Ableitung $\phi'_1(.)$ zu: (für die Herleitung hier klicken)

$\phi'_1(.)= \phi_1(.) \cdot (1 - \phi_1(.))$


ℹ️ ✍ Auftrag neuronales Netz durchrechnen

👉 Hier lernst du, was es heisst, bei einem winzigen neuronalen Netz einen Lernschritt mit einem einzigen Sample durchzuführen und erlebst, wie dabei der Fehler minimiert wird.

⚠️ In diesem Auftrag rechnest du einen Vorwärts-, dann einen Rückwärts- und anschliessend einen weiteren Vorwärtsschritt für das kleine FNN aus Abb.3 für ein einziges Sample durch. Alle Formeln, welche du dafür brauchst, sind in diesem Auftrag enthalten. Ebenso gegeben sind die Eingangsgrössen $x_1$ und $x_2$ des Samples zusammen mit dem Desired Output $d_1$, alle Gewichte $v_{hi}[k]$ und $w_{ij}[k]$ zum Zeitpunkt $k$ und die Lernrate $\mu$. Alle weiteren Zahlen, welche du brauchst, wirst du Schritt für Schritt berechnen.

  1. Berechne alle Zahlen ⚠️ auf drei Kommastellen genau und trage sie in die Textfelder ein. ⚠️ Rechne jeweils mit den auf drei Kommastellen gerundeten Zahlen weiter.


Werte zum Zeitpunkt $k$

$x_1=1.2$ $v_{01}[k]=0.235$ $w_{01}[k]=0.664$
$x_2=-0.7$ $v_{11}[k]=-0.323$ $w_{11}[k]=-0.861$
$d_1=1.8$ $v_{21}[k]=0.578$ $\mu=0.2$


Vorwärtsschritt zum Zeitpunkt [k] inklusive Berechnung des Fehlerwerts

$a_1[k] = \displaystyle\sum_{h=0}^{n_i} v_{h1}[k] \cdot x_h = v_{01}[k] + v_{11}[k]\cdot x_1 + v_{21}[k]\cdot x_2 =$ Loading ⌛
$\phi_1[k](.) = \displaystyle\frac{1}{1 + e^{-a_1[k]}} =$ Loading ⌛
$y_1[k] = \displaystyle\sum_{i=0}^{n_h} w_{i1}[k] \cdot \phi_i[k](.) = w_{01}[k] + w_{11}[k]\cdot \phi_1[k](.) =$ Loading ⌛
$J[k] = \displaystyle\frac{1}{2} (y_1[k]-d_1)^2 = $ Loading ⌛


Rückwärtsschritt zum Zeitpunkt [k] inklusive Gewicht-Update

$(y_1[k]-d_1) =$ Loading ⌛
$\phi'_1[k](.)= \phi_1[k](.) \cdot (1 - \phi_1[k](.)) =$ Loading ⌛
$\displaystyle\frac{\partial J[k]}{\partial w_{01}} = (y_1[k] - d_1) =$ Loading ⌛
$\displaystyle\frac{\partial J[k]}{\partial w_{11}} = (y_1[k] - d_1) \cdot \phi_1[k](.) =$ Loading ⌛
$\displaystyle\frac{\partial J[k]}{\partial v_{01}} = (y_1[k] - d_1) \cdot w_{11}[k] \cdot \phi'_1[k](.) =$ Loading ⌛
$\displaystyle\frac{\partial J[k]}{\partial v_{11}} = (y_1[k] - d_1) \cdot w_{11}[k] \cdot \phi'_1[k](.) \cdot x_1[k] =$ Loading ⌛
$\displaystyle\frac{\partial J[k]}{\partial v_{21}} = (y_1[k] - d_1) \cdot w_{11}[k] \cdot \phi'_1[k](.) \cdot x_2[k] =$ Loading ⌛
$w_{01}[k+1] = w_{01}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial w_{01}}=$ Loading ⌛
$w_{11}[k+1] = w_{11}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial w_{11}}=$ Loading ⌛
$v_{01}[k+1] = v_{01}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial v_{01}}=$ Loading ⌛
$v_{11}[k+1] = v_{11}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial v_{11}}=$ Loading ⌛
$v_{21}[k+1] = v_{21}[k] - \mu \cdot \displaystyle\frac{\partial J[k]}{\partial v_{21}}=$ Loading ⌛


Vorwärtsschritt zum Zeitpunkt [k] inklusive Berechnung des Fehlerwerts

$a_1[k+1] = \displaystyle\sum_{h=0}^{n_i} v_{h1}[k+1] \cdot x_h = v_{01}[k+1] + v_{11}[k+1]\cdot x_1 + v_{21}[k+1]\cdot x_2 =$ Loading ⌛
$\phi_1[k+1](.) = \displaystyle\frac{1}{1 + e^{-a_1[k+1]}} =$ Loading ⌛
$y_1[k+1] = \displaystyle\sum_{i=0}^{n_h} w_{i1}[k+1] \cdot \phi_i[k+1](.) = w_{01}[k+1] + w_{11}[k+1]\cdot \phi_1[k+1](.) =$ Loading ⌛
$J[k+1] = \displaystyle\frac{1}{2} (y_1[k+1]-d_1)^2 = $ Loading ⌛


Vergleich der Fehlerwerte $J[k+1]$ und $J[k]$

Der Fehler hat durch das Training um so viel abgenommen (d.h. trage das Resultat von $J[k] - J[k+1]$ ein): Loading ⌛


Eigene Notizen

Loading ⌛

1) , 2) , 5) , 6)
eigene Darstellung, CC0 1.0
3)
Streng genommen ist somit die obige Formel nicht eine Formel für den SE, sondern für den halben SE
4)
Streng genommen ist somit auch hier die obige Formel nicht eine Formel für den MSE, sondern für den halben MSE