Startseite
  Über...
  Archiv
  Gästebuch
  Kontakt
  Abonnieren


http://myblog.de/mycode

Gratis bloggen bei
myblog.de





FF-Netze in Matrizen-Form Teil 2

Willkommen zurück!

In diesem Teil gehe ich näher auf die genaue Form ein, die benötigt wird um Erfolgreich ein FeedForward zu realisieren, sowie auf den
Back-Propagation-Algorithmus.

Grundlegendes zuerst:
Ihr müsst jedes Zwischenergebnis (also Ergebnis der Matrix-Multiplikation) speichern, da sie für den Back-Propagation-Algo gebraucht werden.


1. Die Forward-Propagation

In den meisten Fällen werdet ihr eine eigene Matrix-Klasse anlegen wollen, da das ganze einfacher zu handeln ist.

Ich habe es folgendermaßen gelöst:

1 Array für die ErgebnissMatrizen, wobei der erste Eintrag
die EingangsMatrix ist und der letzte die AusgangsMatrix
darstellen soll

1 Array für die GewichtsMatrizen, wobei es genau 1 Matrix
weniger gibt, als es ErgebnisMatrizen gibt.

1 Array für die späteren FehlerMatrizen, wobei es genauso viele
Matrizen gibt, wie es GewichtsMatrizen gibt.

Die ReihenZahl der ersten GewichtsMatrix wird bestimmt
von der Anzahl an gleichzeitigen Eingängen.
Die SpaltenZahl von den benötigten Knoten in diesem Layer

Die ReihenZahlen der darauffolgenden GewichtsMatrizen
wird bestimmt durch die Anzahl der Knoten (Spalten)
der vorheringen GewichtsMatrix.
Die SpaltenZahl stellt wieder die Anzahl der Knoten dar.

Die letzte GewichtsMatrix ist definiert durch:
Reihen: Spalten der vorherigen Matrix
Spalten: Anzahl der Ausgänge.

Dabei zu beachten ist natürlich dass die Matrizen
1. Eine zusätzliche Spalte voller 1er braucht, falls es eine Werte-Matrix ist
2. Eine zusätzliche Reihe voller 1er braucht, falls es eine Gewichts-Matrix ist

Wenn ihr wie ich die ganzen Matrizen in Arrays gepackt habt, sieh das ganze wie folgt aus (wobei AF für die Aktivierungsfunktion für jedes
Element der Matrix steht und BiasIt der Matrix eine Spalte mit 1er
anhängt)

For i from 0 to Results.Length-2:

Results[i+1] = Results[i]*WeightMatrix[i]
Results[i+1] = AF(Results[i+1])

If(i < Results.Length-2)

BiasIt(Results[i+1])

EndIf

EndFor


Die letzte Matrix wird nicht mehr mit 1er Aufgefüllt.

Das ist die ganze Forward-Propagation.
Einfacher kann es gar nicht sein.



2. Die Back-Propagation

Hier wird das ganze auch versimpelt.

Wie im simplen Feed-Forward-Netzwerk wird zunächst der Ausgangsfehler berechnet.
Dies geschieht einfach durch Subtraktion
der Matrizen:
(DesiredOutput - CurrentOutput)

Die Matrix lege ich als letztes Element in das Array der FehlerMatrizen.

Im original FF-Netz werden die darauffolgenden Fehler
berechnet, indem man die Summe der gewichteten Ausgangsfehler
mit dem abgeleiteten Ergebnis multipliziert.

Nehmen wir an, wir haben eine tanh-Aktivierungsfunktion.
Dann sind die Abgeleiteten Werte 1 - Wert² für jeden
Eintrag in der Matrix.

Wir brauchen 4 Matrix-Operationen
-UnBiasIt gibt die Gewichtsmatrix ohne 1er Spalte zurück
-Transpose transponiert die Matrix
-Derivate gibt eine WerteMatrix zurück, die die abgeleiteten Werte beinhaltet
-Und die Operation .* stellt eine punktweise Verknüpfung dar
(Das heißt, so fern die beiden Matrizen die gleichen Dimensionen haben,
werden einfach nur die korrespondierenden Elemente multipliziert)


So könnte es aussehen:

For i from ErrorMatrix.Length-2 to 0:

TempMatrix = ErrorMatrix[i+1] * WeightMatrix[i+1].UnBiasIt().Transpose()

ErrorMatrix[i] = Results[i+1].UnBiasIt().Derivate() .* TempMatrix

EndFor

Jetzt haben wir also die Fehler-Matrizen. Fehlt nur noch
das Update der Gewichte über Delta-Werte.

Das berechnet sich normalerweise durch die Multiplikation des Fehlerwertes
mit der Lernrate sowie mit dem Ergebnis des vorherigen Knotens, der
zu dem Gewicht gehört.

Jetzt ist es genauso simpel. Alles was wir brauchen ist eine weitere Operation:
Skalar-Multplikation. Die verknüpft jeden Wert der Matrix mit einem einfachen Wert.

For i from 0 to WeightMatrix.Length:

WeightMatrix[i] += Results[i].Transpose() * ErrorMatrix[i] * learningRate

EndFor


Damit haben wir es geschafft!
Das Netz sollte jetzt gleichzeitig alle Trainingsbeispiele berechnen können.
26.3.16 13:30


FF-Netze in Matrizen-Form Teil 1

Hi @all.
Wie versprochen, starte ich meine Reihe "FF-Netze in Matrizen-Form".

Ich finde, diese Form der Darstellung extrem elegant und schön (wenn man ein Code so nennen darf).
Außerdem hat das ganze den Vorteil, dass die GPU massiv parallel Matrizen multiplizieren kann, was natürlich ein Performance-Gewinn ist.

Fangen wir zunächst mit den Grundlagen an.

1. Warum in einer Matrix?

Wie oben erwähnt ist es die elegantere Darstellung.
Wenn man sich mal erinnert, wie eine Matrix-Multiplikation
funktioniert, merkt man auch, warum.

Für die, die es nicht eben nachschlagen wollen.

Zunächst müssen die Spaltenzahl von Matrix A mit der
Reihenzahl der Matrix B übereinstimmen.

Nehmen wir an wir haben eine Matrix A in einer 3x4 Form (3 Reihen, 4 Spalten) und eine Matrix B in 4x2 Form.

A =
|1 | 2 | 3 | 4|
|5 | 6 | 7 | 8|
|9 | 1 | 2 | 3|

B =
|1 | 2|
|3 | 4|
|5 | 6|
|7 | 8|

Die Matrix C = A*B hat die Form 3x2.

Berechnen wir C mal

C =
|1*1 + 2*3 + 3*5 + 4*7 | 1*2 + 2*4 + 3*6 + 4*8|
|5*1 + 6*3 + 7*5 + 8*7 | 5*2 + 6*4 + 7*6 + 8*8|
|9*1 + 1*3 + 2*5 + 3*7 | 9*2 + 1*4 + 2*6 + 3*8|

C =
| 50 | 60 |
| 114 | 140|
| 43 | 49 |

Das Prinzip ist ziemlich einfach.
Man nimmt den Vektor der n-ten Reihe von Matrix A
und Multipliziert ihn mit dem Vektor der m-ten Spalte von Matrix B

sagen wir mal n1 bis n3 währen die Reihen-Vektoren von A
und m1 bis m2 die Spalten-Vektoren von B

Dann ist C=

n1*m1 | n1*m2
n2*m1 | n2*m2
n3*m1 | n3*m2

Gut. Soweit müsste alles klar sein.

Wer aufgepasst hat, dem wird aufgefallen sein, dass
jeder Eintrag in C die Summe der Multiplikationen ist.

Wenn wir jetzt unser Neuron betrachten:

Ein Neuron hat gewichtete Eingänge.
Das Ergebnis des Neurons (bevor es durch die Aktivierungsfunktion
gejagt wird) ist die Summe der gewichteten Eingänge.

Also Result = Sum(w*x)

Sehen wir also noch einmal auf unsere Matrizen aus dem Beispiel:

A =
|1 | 2 | 3 | 4|
|5 | 6 | 7 | 8|
|9 | 1 | 2 | 3|

B =
|1 | 2|
|3 | 4|
|5 | 6|
|7 | 8|

Sagen wir A ist eine Eingangs-Matrix und B ist die Gewichtungs-Matrix.

Dann ist schnell klar:
Die Spalten von A stellen die Eingänge eines Neurons dar.
Da jedes Neuron die gleichen Eingänge erhält stellen also
die Spalten von B die Neuronen dar, während die Reihen
die Eingangsgewichtungen darstellen.

B =
|1 | 2|
|3 | 4|
|5 | 6|
|7 | 8|
->Spalte x = Neuron x
->Reihe y = Eingang y von Neuron x

Was aber genau stellen dann die Reihen von Matrix A dar?
Hier wird es interessant.
In unserem simplen FF-Netz vom letzten mal mussten wir,
wenn wir verschiedene Eingangswerte hatten die nicht gleichzeitig
anlagen, immer wieder von vorne das Netz einen FeedForward
machen lassen.
Jetzt aber stellen die Reihen von A diese Werte dar und können
gleichzeitig verarbeitet werden.


A =
|1 | 2 | 3 | 4|
|5 | 6 | 7 | 8|
|9 | 1 | 2 | 3|
->Spalte x = Gleichzeitige Eingänge
->Reihe y = Beispiel y mit den Werten x(1 bis n)

Wenn wir nun auf jedes Element C = A*B die Aktivierungsfunktion
anwenden ist C das Ergebnis eines Neuronalen Netzes
mit einer Hidden-Schicht in denen 2 Neuronen sitzen, die
je 4 Werte akzeptieren.

Dabei haben wir 3 Beispiele in das Netz propagiert, die
alle 4 Werte haben.

Da C immer genauso viel Reihen hat wie A
bekommen wir auch 3 Ergebnis-Sets.
Da C immer so viel Spalten hat wie B, bekommen wir
je 2 Werte für jedes Set.

Wir definieren also die Gewichtsmatrix folgendermaßen:
1.
Sie hat genauso viele Reihen, wie Werte pro Beispiel
aus der Werte-Matrix A (also Spalten).

2.
Sie hat genauso viele Spalten, wie Werte in der nächsten
Werte-Matrix C vorhanden sein sollen (also Spalten).

Nun können wir in einer Einzigen Matrix eine komplette Schicht an Neuronen darstellen.


Wo bleiben aber die Bias-Werte?
Die sind relativ simpel zu erzeugen.

Wir setzen einfach eine Spalte voller 1er in die Eingangsmatrix
und eine Reihe voller 1er in die Gewichtsmatrix.
Die 1er der Gewichtsmatrix werden sich hierbei verändern (ist klar, da es ja die Gewichtsmatrix ist).

Zum Abschluss ein kleiner Tipp:
Wenn ihr eine Matrix-Multiplikation implementiert, benutzt
einfach den normalen Algorithmus dafür.
Heutige PCs sind schnell genug um das zu realisieren.
26.3.16 12:35


Simples Neuronales Netz Teil 3

In diesem Teil wird etwas näher auf die Backpropagation
eingegangen.

Warum funktioniert die Backpropagation?

Gehen wir erst einmal von der Ausgabe-Schicht aus:

Unser Fehler wird standardmäßig über 1/2(DesiredOutput - CurrentOutput)²
berechnet.

Für unser Verfahren nutzen wir die Ableitung -> (DesiredOutput - CurrentOutput) um die Steigung zu erhalten.

Durch das Quadrieren haben wir eine Art Parabel, die ihr Minimum beim kleinsten Fehler bekommt und somit auch die kleinste Steigung besitzt.

Zusätzlich leiten wir die Aktivierungsfunktion ab, wodurch wir
die Steigung der Aktivierungsfunktion erhalten.

Der Rest ist simpler als man meinen möchte.
Wir multiplizieren die Steigung des Fehlers mit der Steigung des Ergebnisses.

Dadurch kommen zwei Mechanismen zum Einsatz:
Ist der Fehler groß ist auch die Steigung groß.
Ist das Ergebnis nahe an der null, ist die Steigung groß.

(Man geht davon aus, dass, je näher die Summe an die 0 herankommt, desto größer ist die Auswirkung auf den Fehler. Hier liegt auch das Problem: Bei extremen Werten ändert der Algorithmus garnichts)

Dadurch wird dort, wo die Steigungen beider Funktionen groß sind auch das größte Fehlersignal erzeugt.

Schauen wir uns nun die weiteren Schichten an, wird die Ableitung des Fehlers der folgenden Schicht rückwärts gewichtet und mit der Steigung der Aktivierungsfunktion multipliziert.

Somit wird der Fehler dort größer, wo am meisten
Gewicht vorhanden ist, also dort, wo der größte Einfluss auf
den Fehler liegt.

Stellen wir uns das ganze als Berg- und Hügellandschaft vor.
Haben wir den maximalen Fehler liegt der Wert auf der Bergkuppel.
Wir wolle das der Fehler möglichst tief liegt.
Die Steigung gibt die Richtung an. Ist die Steigung negativ geht der Wert runter. Wir rollen vorwärts den Berg hinab Richtung Fehlerfrei.
Ist Steigung positiv rollen wir den Berg rückwärts runter.
Wir Pendeln also zwischen zwei Bergen hin und her, bis wir
im Tal zum stehen kommen.

So pendelt sich auch das Gewicht bis zum Optimum ein.

Hier erkennt man auch die Wichtigkeit einer guten Lernrate.
Ist sie zu hoch, springen wir um das Optimum herum.
Zu niedrig und es dauert zu lange.

Ein weiterer Punkt ist, dass es auch zu lokalen Minima kommen kann.
Dort ist das Fehlersignal klein, aber der Fehler an sich nicht beseitigt.

Dahin gehend gibt es allerdings ein paar Techniken um dies zu vermeiden (Stichwort: Momentum).

Im nächsten Teil werde ich mich noch einmal der Implementierung widmen. Diesmal jedoch in der Matrizen-Version, was, wie ich denke, viel cooler ist, da es eleganter ist und direkt auf der GPU ausgeführt werden kann (was um einiges schneller ist!)
17.3.16 14:27


Simples Neuronales Netz Teil 2

In diesem Teil geht es um etwas in die Materie.
Ich werde einen Pseudocode schreiben und
erklärenwie genau das ganze aufgebaut sein kann.

Zunächst einmal:
Ich nutze als Aktivierungsfunktiondie Tangens Hyperbolicus.
Er ist relativ leicht abzuleitenund ermöglicht, im Gegensatz zur Sigmoid-Funktion, dem Netznegative Werte zu produzieren.

Als Trainingsbeispiel nehmen wir den Sinus, daes hierbei pro Zeitschritt nur einen Eingang und einen Ausgang erzeugt und relativ einfach ist, einen'desired Output' (d.h. der gewünschte Ausgang für das Training) zu erzeugen.Zunächst definieren wir eine Neuronen-Klasse

Ein Neuron braucht folgende Werte:
Class Neuron:
VariablenInput[]
Weights[]
Bias
Sum
Result
Error

Funktionen
Propagate()

In Pseudocode für die Propagate-Funktion:
For i = 0 to Input.Length:
Sum = Sum + Input[i]*Weights[i]
EndFor
Result = Tanh(sum)

Das war es auch schon mit dem Neuron.
Normalerweise könnte man die Neuronen jetzt
in einem 2-Dimensionalen Array ablegen, wenn jede Schicht gleich viele Neuronen hat.
Da das nicht so ist, legen wir noch eine Layer-Klasse an,
welche ein Array vom Typ Neuron beinhaltet.

So können wir im Main-Code ein Array erzeugen, welches
unterschiedlich viele Neuronen besitzt.

Class Layer:
Neuron[]

Nun kann man das ganze schon Initialisieren.

Folgendes gilt zu beachten:
Wir nutzen Neuronen auch für den Eingang somit sollten
alle Eingangsneuronen einen Eingang mit einer Gewichtung von 1
besitzen (wir haben so viele Eingangsneuronen wie Eingabe-Werte).
Da Neuronen nur einen Ausgang besitzen haben wir in der Letzten Schicht so viele Neuronen wie Ausgaben benötigt werden.

Für unseren Sinus benutzen wir zunächst 3 Schichten:

Eingang, Hidden, Hidden.

Die Anzahl der Neuronen sind:
1-6-1

Also können wir im Hauptprogramm sagen:
Layer[] = new Layer[3]
Layer[0].Neuron[] = new Neuron[1]
Layer[1].Neuron[] = new Neuron[6]
Layer[2].Neuron[] = new Neuron[1]

Die Gewichtungen werden Standardmäßig zufällig gewählt.

Für den nächsten Schritt brauchen wir 3 Schleifen um die Vorwärts-Propagation zu starten.

For i = 0 to Layer.Length
For j = 0 to Layer[i].Neuron.Length
If i = 0 Set Input-Values
Else
For k = 0 to Layer[i-1].length
Layer[i].Neuron[j].Input[k] = Layer[i-1].Neuron[k].Result
EndFor
EndIf
Layer[i].Neuron[j].Propagate()
EndFor
EndFor

Fertig. So wird das ganze nach vorne Propagiert.

Der nächste Schritt besteht aus dem Korrigieren der Gewichtungen für
jedes Neuron.
Dafür berechnen wir Rückwärts den Fehler jedes Neurons
Wir unterscheiden dabei: Letze Schicht und Restliche Schichten.

In der Letzten Schicht (die wir zuerst berechnen) berechnen wir den Fehler direkt.Dazu benötigen wir, wie im letzten Teil erwähnt, die Ableitung.

Tanh hat die Ableitung: 1-tanh(x)²

Der Fehler berechnet sich aus der Multiplikation der Ableitung mit der Differenz zwischen DesiredOutput und CurrentOutput, also
1-tanh(x)²* 1/2(DO-CO)²

Da wir tanh(x) schon in jedem Knoten berechnet habe (es ist der Result-Wert) vereinfacht das uns die ganze Sache erheblich.

For each Neuron in OutputLayer
Error = (1-Result²)*1/2(DesiredOutput-Result)²

Sieht simpel aus oder?Da hier der Result-Wert gleichzeitig die Ausgabe ist können wir ihn auch direkt für die Abweichung benutzen. Daher DesiredOutput-Result.

Für alle anderen Layer muss natürlich der Fehler gewichtet zurückpropagiert werden.

Der Fehler für den Aktuellen Knoten ist die Summe aller
(Fehler der nächsten Schicht * der Gewichtung) Aktuellen Knotens.
Anschließend wird auch hier mit der Ableitung multipliziert.

Hört sich zunächst kompliziert an. Technisch gesehen ist es aber relativ einfach:

For i = Layer.Length-1 to 0
For j = 0 to Layer[i].Neuron.Length
Sum = 0
For k = 0 to Layer[i+1].Neuron.Length
Sum = Sum + Layer[i+1].Neuron[k].Error
*Layer[i+1].Neuron[k].Weights[j]
EndFor
Error = Sum * (1-Result²)
EndFor
EndFor

Es ist relativ Simpel. Da der Index des Neurons in der
betrachteten Schicht auch der korrespondierende Index für
die Gewichtung aller Neuronen in der nächsten Schicht ist.

Allgemein betrachtet:
Wir berechnen den Fehler an den Ausgangsneuronen direkt.
Dann gehen wir von Schicht zu Schicht rückwärts.
Für jeden Knoten in der Schicht Summieren wir alle Fehlerder nächsten Schicht multipliziert mit der Gewichtung auf und berechnen daraus den Fehler.

Um es noch mehr zu veranschaulichen:
Wir haben Knoten X in der vorletzten Schicht
und die Knoten Y und Z in der letzten Schicht.
Wir gewichten erstmal die Fehler in Y und Z mit den Gewichten
X zu Y und X zu Z und addieren sie.
Fertig.

Ein letzter Schritt fehlt noch: Das Update der Gewichte.
Dafür brauchen wir noch eine Variable.
Diese nennt sich Lernrate und bestimmt, wir stark das Gewicht angepasst wird.

Zu groß und das Netz springt um den optimalen Wert herum.
Zu klein und es dauert zu lange.

In jedem Knoten wird jedes Gewicht so neu berechnet:

Weight = Weight + LearningRate*Error*Input

Der Input bezieht sich auf den Input des zu ändernden Gewichtes.

Genauso verhält es sich mit dem Bias:

Bias = Bias + LearningRate*Error

Da der Bias standardmäßig 1 ist, muss kein gesondertes Gewicht geändert werden. Wir ändern den Bias-Wert direkt.
Das Netzwerk ist nun in der Lage zu lernen.
Nach jeder Runde kann dann das gelernte mit dem gesamten Zahlenbereich getestet werden. (Anstatt Sinus mit 1er Schritten, Sinus mit 0.1er Schritten z.B.)

Am besten packt man die einzelnen Schritte in mehrere
Funktionen.Init()
While Error>DesiredError
Propagate(Input)
BackPropagate(DesiredOutput)
Test(Input)
EndLoop

Natürlich gibt es noch einige Sachen bezüglich der Parameter (Anzahl der Neuronen in der Hidden-Schicht, Lernrate, Fehler-Größe

Wählt man z.B. die Fehler-Toleranz zu klein, wird das Netzwerk übertrainiert. D.h. Statt einer Sinus-Kurve in der Test-Phase erhaltenwir eine Zickzack-Kurve.

Das selbe kann bei zu vielen Neuronen passieren.
Eine zu hohe Toleranz und zu wenig Neuronen führt zu einer
zu hohen Verallgemeinerung und die Werte werden nicht genau genug.

Die Lernrate haben wir bereits angesprochen.
Wichtig ist auch: In der Test-Phase wird NIE zurückpropagiert.
17.3.16 13:15


Simples Neuronales Netz Teil 1

In dieser Beitrags-Reihe geht es um simple Neuronale Netze.
Um genauer zu sein, wird es um FeedForward Netze gehen.

Diese Art von Netzwerken eignen sich besonders für den
Einstieg in die Materie, da sie einen einfachen Aufbau haben
und mit etwas mathematischem Verständnis auch
sehr schnell zu Begreifen sind.

Teil 1. Grundlagen

Was ist ein Feed-Forward Netz?

Einfach gesagt ist ein FF-Netz (so wie jedes andere Netz allgemein auch)
ein Klassifizierer.
Es fließen Informationen in das Programm, sie werden Bewertet und am Ende steht ein (oder mehrere) Ergebnisse fest.
Genau genommen ist es nichts anderes als eine Funktion.

Nehmen wir z.B. f(x) = x². Hier wird jeder x-Wert einem y-Wert zugewiesen (hier y= x²).
So könnte auch das Ergebnis des Netzwerks aussehen, nur das dieses zunächst auf die Ausgangswerte trainiert werden muss und auch dann NUR die Werte beurteilen kann, die innerhalb des Trainings-Raums basiert.


Was heißt das also?

Trainieren wir das Netz darauf den Sinus von Zahlen von 0 bis 7 (ca. 2PI) zu berechnen und das in, sagen wir, 1er Schritten.
Die Eingangszahlen wären demnach:
0,1,2,3,4,5,6,7.
Anschließend kann das Netz die Ergebnisse aller Zahlen dazwischen berechnen, also von z.B. 3.1415 usw.
Darüber und darunter kann es nur Schätzungen abgeben (die meist nicht dem realen Ergebnis entsprechen).

Geht man von einem normalen FF-Netzwerk aus, so kann man
sagen: Hat man eine mathematische Formel, um die Ergebnisse zu berechnen, nutzt man lieber die Formel als ein neuronales Netz.
Der Grund liegt auf der Hand: Es ist genauer und muss nicht zuerst trainiert werden.
Hat man jedoch keine Formel und kennt nur Ursache und Ergebnis
trainiert man das neuronale Netz um Aussagen zu treffen.
(Wenn ihr Polynomaproximation kennt, wird euch das bekannt vorkommen).


Wie funktioniert es?

Ein Netzwerk besteht aus Knotenpunkten, sogenannten Neuronen (in Anlehnung an das menschliche Gehirn).

Jedes dieser Neuronen besitzt ein oder mehrere Eingänge und einen Ausgang. Zusätzlich besitzt jedes Neuron einen Bias-Wert, welches die Eingänge verstärkt oder abschwächt sowie eine Aktivierungsfunktion die entscheidet, ob das Neuron nun einen Wert weitergibt oder nicht.

Aber die Eingangswerte kommen nicht einfach so in das Neuron, sondern werden zunächst gewichtet.

Die Eingangswerte werden also zunächst gewichtet und dann aufsummiert (dazu gehört auch der Bias-Wert) und anschließend durch die Aktivierungsfunktion geschickt.
Der resultierende Wert liegt am Ausgang an.


Beispiel:

Das Neuron feuert nur, wenn das Resultat der Eingänge und des Bias
größer 0 ist. (D.h. 1 Wenn R > 0, sonst 0)
Das ist die Aktivierungsfunktion.

Das Neuron besitzt 2 Eingänge. Der Bias sei hierbei 1.
Die Eingänge sind beschaltet mit -1 und 0.5

Die Gewichtungen seien: 0.5 und 1

Die Summe der Eingangswerte (+Bias) sind demnach
R = 1+((-1)*0.5)+(0.5*1) = 1

Die Aktivierungsfunktion entscheidet, das der Wert groß genug ist.
Am Ausgang liegt demnach eine 1 an.
;

Der Aufbau

Ein Netz besteht in der Regel aus vielen solcher Neuronen und Neuronen-Schichten.

Es gibt die Eingangschicht, ein oder mehrere Hidden-Schichten (Schichten, die nichts an den Nutzer ausgeben und somit versteckt sind) und Ausgänge.

In jeder dieser Schichten sind ein oder mehrere Neuronen vorhanden.
Wichtig dabei ist, das jeder Knoten aus einer Schicht mit jedem Knoten aus der vorherigen verbunden ist.

Anschaulich heißt das:
Haben wir 2 Knoten am Eingang und 3 in der nächsten Schicht,
hat jeder der Knoten in der nächsten Schicht 2 Eingänge und kriegt
die Ergebnisse aus jedem der Eingangsknoten.




Wie lernt das Netzwerk?

Hier wird es etwas mathematischer (aber keine Sorge. Es ist eigentlich ganz simpel).
Es handelt sich hierbei um die Backpropagation mittels Gradientenwanderung. Hierdurch werden die Gewichtungen
verändert.
Dafür nutzen wir aus, dass wir uns (hoffentlich) eine einfach ableitbare Aktivierungsfunktion ausgesucht haben.

Hierbei wird ein Ausgangsfehler berechnet (der Fehler zwischen dem Ausgang des Netzwerkes und dem erwünschten Ausgangswert).

Dieser wird Knoten für Knoten zurückpropagiert. Dabei wird die Gewichtungen berücksichtigt, sodass der berechnete Fehler dort am größten wird, wo der größte Einfluss auf das Ergebnis besteht.

Anschließend wird der Fehlerwert in jedem Knoten benutzt, um die
Gewichtungen zu ändern.

In den folgenden Teilen werde ich etwas näher auf die Mathematik eingehen.
Aber für's erste war's das erst einmal.

Ich hoffe, ihr konntet in diesem Teil einen kleinen Einblick gewinnen.
17.3.16 11:27





Verantwortlich für die Inhalte ist der Autor. Dein kostenloses Blog bei myblog.de! Datenschutzerklärung
Werbung