date-created: 2024-06-25 02:20:14 date-modified: 2024-06-28 07:25:06

Deep Learning

anchored to 116.00_anchor_machine_learning proceeds from 116.13_neural_networks Tags: #Study #machinelearning


Overview

Wir haben jetzt, aus 116.13_neural_networks gelernt, wie wir ein Neuronales Netz bauen und konstruieren können, sodass wir ein beliebiges Problem lösen können.

Dabei haben wir folgende Toolbox definiert / aufgebaut:

  1. Netzwerarchitektur auswählen
  2. Loss auswählen - passend
  3. Gradient-basierter Optimierer auswählen
  4. trainieren

Dabei haben wir wieder den Unterschied zwischen der Regression und Klassifikation betrachten:

Regression:

  • Ausgabe ist kontinuierlich - gemäß der Prediction
  • Square loss zum optimieren
  • Ausgabe ist linear

Klassifikation:

  • Ausgabe sind diskret –> ist die Klasse oder nicht!
  • Nutzen ähnlichen Trick, wie bei logistischer Regression:
    • WSk kann man durch die Sigmoid-Funktion darstellen!
    • wir nutzen dann damit die Cross-Entropy-Loss Function1

Deep-Learning | Grundlagen

Wir haben bereits 116.13_neural_networks kennengelernt, wobei sie immer einen Input, einen Output und beliebige hidden layer hatten. Wir wollen das Konzept der hidden layer jetzt Grundlegend Skalieren, um so mehr Aussagen bzw. bessere Konstrukte darstellen zu können!

Dabei werden auch neue Probleme auftreten, die wir bearbeiten und lösen möchten!

[!Feedback] Motivation für Deep Learning

Es gibt diverse Aspekte, weswegen deep learning eingeführt / betrachtet wurde:

  • mehr Rechenleistung zur Verfügung stehend –> gerade hohe parallelität kann viele Berechnungen vereinfachen / beschleunigen –> Damit sind größere Neuronale Netz möglich
  • Bilderkennung / Spracherkennung / Sprachverarbeitung etc profitieren von diesen komplexen Netzen
  • hat dazu beigetragen einen Durchbruch bei vielen ML-System zu erleben (etwa generative Modelle)

Definition von Deep-Neural-Networks

[!Definition] DNN - Deep neural networks

Deep neural networks beschreiben grundlegend wieder neuronale Netze, aber mit ein paar additionalen Aspekten / Parametern.

_Was beschreiben wir also mit einem DNN, welchen Vorteil hat diese Struktur? Und welche Herausforderungen erhalten wir dabei? #card

DNNs sind neuronale Netzwerke, die einfach viele hidden layer aufweisen

  • die Hidden layer lernen dann die Merkmale unserer Eingabedaten mit steigender Abstraktion – desto tiefer wir sind
  • Es wird ein End-To-End Training angewadnt –> wir nutzen Back-prop halt vom rechten Ende zum linken Ende des Netzes (müssen alle Schichten traversieren)

Gründe, warum wir viele Layer hinzufügen sollten / könnenn.

  • komplexere Funktionen können modelliert / dargestellt werden!
  • es erhält eine höhere Kapazität also kann mit mehr Daten besser werden
  • wir müssen uns selbst wenige “Gedanken machen, wie man Parameter wählt” –> Das Netz brauch weniger menschlichen Input

Herausforderungen, die dabei auftreten:

  • Mehr Speicher (Parameter) und Rechenleistung (trainieren eines tiefen, großen Netzes!)
  • explodierende / verschwindende Outputs (exploding / vanishing outputs)
  • ebenfalls explodierende / verschwindende Gradienten (exploding / vanishing gradients)

Wir möchten ferner die Initialwerte für die Gewichte des DNN betrachten und darüber urteilen / Probleme finden und Lösungen schaffen!

Exploding | Vanishing Outputs

Wir möchten die Problematik von exploding/vanishing outputs definieren:

[!Req] Exploding | Vanishing outputs

Betrachten wir folgendes neuronales Netz.

Wir können hier etwa den Forward-Pass ( die Berechnung von ) betrachten:

Angenommen die roten Gewicht im Layer sind gleich und alle anderen Gewicht (noch) null. Wass passiert dann mit dem Ouptut? Welches Problem erhalten wir? #card

Gilt diese Annahme, dann folgt also es wird direkt durchgeleitet.

Es folgen zwei Folgerungen:

und wenn

Das heißt die Outputs können dann sehr sehr klein werden oder aber auch explodieren –> Wenn wir die Wichtungen nicht gut initialisieren.

Exploding | Vanishing Gradients

selbiges Problem, wie bei Outputs können wir das auch bei den Gradienten betrachten und somit weiter aufzeigen, warum es wichtig ist die Wichtungen richtig zu initialisieren!

[!Req] Exploding | Vanishing Gradients

Betrachten wir wieder ein neuronales Netz:

Dann betrachten wir jetzt Backward-Pass (also Backprop), das heißt wir betrachten die Berechnung:

Was kann jetzt mit den Gradienten passieren, wenn wir die Werte groß / klein wählen? #card

Wir multiplizieren hier immer mit - etwa bei für ein großes –> Das heißt es wird sehr klein, wenn groß im negativen/positiven ist!

–> Dadurch können die Gradienten verschwindend klein werden, wenn wir große / kleine s initialisieren!

Dadurch sehen wir jetzt, dass wir eine neue Aktivierungsfunktion oder eben eine gute Initialisieung!

Motivation | Faktoren von starken Deep-Networks

mit obiger Erweiterung des Begriffes von neuronalen Netzen möchten wir jetzt Faktoren bestimmen und beschreiben, weswegen neuronale Netze so funktionsfähig und mächtig (geworden) sind.

  • Aktivierungsfunktion ohne verschwindende Gradienten: ReLU und ¨ahnliche
  • Skip-Connections / Residual Learning
  • Autodifferentiation (autodiff)
  • Optimierer (z.B. RMSProp, Adam)
  • Architekturen mit unterschiedlichen inductiven Biasen:
    • Convolution Networks
    • Graph Nets
    • Recurrent Networks
    • Transformers

[!Attention]

Es werden jetzt einige Anpassungen / Erweiterungen notwendig sein, damit wir die obigen Herausforderungen zu beheben.

Aktivierungsfunktionen (für Hidden Layers) : ReLU

Wir möchten eine neue Aktivierungsfunktion betrachten, welche die vorher definierten / betrachteten - Sigmoid / tanh etc. - ersetzen kann / wird.

[!Definition]

Wir betrachten also die ReLU - Rectified Linear Unit :

Unter Betrachtung des Funktionswertes, wie ist die ReLU definiert? Welchen Vorteil erkennen wir bei Eingaben ? Wozu führt sie weiter? #card

Die ReLU ist folgend definiert:

Was wir hier beobachten können: für sehr große sättigt sie sich nicht - im Vergleich zu etc –> das heißt sie wird nicht zwischen stuck sein

-> Sie führt dadurch auch zu einer sparse Repräsentation –> denn manche hidden Aktivierungen könnten dann auch 0 sein.

Problem: Wenn wir jetzt haben, dann lernen wir nichts, weil entsprechend resultieren wird.

Wir haben bei der ReLU jetzt folglich das Problem, dass dazu führen würde, dass wir keine Werte erhalten –> nicht lernen.

Dem möchten wir mit einer angepassten ReLU Funktion entgegentreten:

[!Req] L-ReLU - leaky ReLU

Was ändern wir bei der L-ReLU - sodass sie auch für Werte kleiner 0 lernen kann / einen sinnigen Wert ausgibt? #card

Wir wollen die Leaky ReLU jetzt folgend definieren:

ist dabei typischerweise relativ klein gewählt, damit es nicht zu viel Einfluss nimmt ( es einfach verhindert, dass 0 auftritt); meist etwa

Wichtigkeit der Initialisierung

Wie in Task 3 Training a Neural Network schon gesehen sind die Initialparameter sehr wichtig, um entsprechende Ergebnisse mit einem neuronalen-Netz zu erhalten.

Das werden wir ferner formaler beobachten und eine Lösung vorschlagen.

[!Definition] Initialisierung | Probleme

Wir möchten ferner ein Beispiel-Netz betrachten (nur High-Level) und hierbei verschiedene Startparameter für die Gewichte einsetzen und beobachten.

Unter Betrachtung des folgenden Netzes, was passiert, wenn wir Nullgewichte einfügen? Was passiert mit normalverteilten Gewichten? Was passiert bei skalierten normalverteilten Gewichten? #card

Unter Einsetzen von Nullgewichten werden wir sehen, dass die Aktivierungen der Schichten einfach bei stehen bleiben werden:

Unter Einsetzen von Normalverteilten Gewichten werden wir folglich sehen, dass die Aktivierungen schnell gesättigt sein werden und somit gerade in die Extrema peaken:

Sofern wir jetzt gut skalierte normalverteilte Gewichte verwenden, werden wir auch in den Aktivierungen eine Normalverteilung beobachten –> Sie ist also ausgeglichener:

Wir sehen also, dass es relevant ist, wie die Initialisierung umgesetzt wird.

[!Feedback] Wichtigkeit am Beispiel einsehen:

Folgend ein Link, der die Wichtigkeit / das Problem darstellen kann:

https://www.deeplearning.ai/ai-notes/initialization/index.html

Ferner haben wir herausgefunden, dass eine skalierte Gewichtsverteilung optimal wäre / ist.

Skalieren der Anfangs Gewichtsverteilung

[!Bem] Finden der optimalen Gewichte

Wir möchten ferner unter Betrachtung der Eingabewerte x also eine optimale Initial-Wichtung erzeugen.

Angenommen die Eingangsdaten und die Gewichte sind normalvertetilg, also und die Gewichte Wir suchen also noch die Varianz und fordern hier folgend:

  • Die Varianz der Aktivierung sollte gleich bleiben!

Wir nehmen jetzt an, dass die Aktivierungsfunktion mehr oder weniger linear ist (etwa bei mit kleinem ) Wie ist die Varianz der Aktivierung eines hidden layers dann bestimmt? #card

Die Aktivierung ist dann das Produkt von zwei unabhängigen Normalverteilungen was wir folgend aufteilen können (da iid.): Es folgt dann:

(Für die Gradientenberechnung - dem Backward-Pass! - können wir dann ähnlich argumentieren!)

[!Beweis] Praxisanwendung

Man nimmt hier meist bestimmte Initialisierungen:

  • Xavier
  • Glorot
  • He Initialisierung (bei ReLU)

Automatic Differentiation

Als Ausblick, wie die Berechnung der Ableitungen für [Back-prob ()](116.13_neural_networks.md#Back-prob%20()) etwas automatisiert werden kann - weil es sonst aufwendig und vor Allem manuell gemacht werden muss - möchten wir einen Ansatz betrachten, welcher diese Ableitung berechnet:

[!Idea]

Betrachten wir also folgende Beispiel-Funktion, die wir ableiten wollen: , was unsere typische Aktivierungsfunktion sein kann.

Wir können jetzt einen Execution Tree anschauen und damit den Term aufgliedern:

Im Beispiel erhalten wir etwa folgende Struktur:

-> Wir könenn also die Funktion/ den Code zur Auswertung des Ausdruckes Generieren

-> Ferner können wir auch die Ableitung davon dann erzeugen lassen

  • Das kommt daher, dass wir relativ einfach die Ableitung der einzelnen Fragmente bestimmen und anschließend unter Anwendung der Kettenregel entsprechend umformen können

Training Speed | Konvergenz verbessern

[!Hinweis] Motivation

Während gradient descent prinzipiell nicht schlecht ist und dabei hilft die Minima zu finden, sind die leider langsam.

Weiterhin können sie teils falsch konvergieren / oder nicht und daher brauch es also weitere Intervention.

Wir wollen dafür jetzt drei verschiedene Methoden betrachten, die helfen sollen, das zu verbessern!

Momentum

[!Definition] Gradient Descent mit Momentum

Wenn wir den Loss optimieren wollen, kann diese Funktion in der Übersicht viele “Klüfte, Hänge und Grobheiten” aufweisen - also wir uns da etwa verhängen, wenn wir nur lokale Minima suchen.

Visuell etwa:

Wenn wir die Loss-Funktion schon als Terrain betrachten, kann man jetzt durch eine passende Analogie einen neuen Ansatz für einen besseren Gradient-Descent anschauen:

Setzen wir folgende Analogie: Gradient Descent ist wie ein Ball, der eine Oberfläche hinunterrollt. Wir bauen durch dessen Masse/Trägheit jetzt ein Momentum auf, das uns dabei helfen kann, das optimale Minimum zu finden. Wie können wir genau das passend modellieren und umsetzen? #card

Wir setzen das Momentum so um, dass wir immer den Durchschnitt von vergangenen Gradienten - die Menge kann variieren! - behalten und in die Berechnung einbeziehen.

Wir berechnen sie dann folgend: wobei hier:

  • die Gradientenschritte nummeriert
  • der Mittlungsparameter ist (meist so )

Wir werden jetzt die Gewichte immer entsprechend des geglättenden Gradienten anpassen, also:

Vorteile:

  • wir vermeiden Oszillation ( zwischen einem Tal hin und her!)
  • kleinere lokale Minima kann man überwinden (wir rollen drüber)
  • flache Regionen und zerklüftete Loss-Oberflächen werden auch entsprechend traversiert (schneller)

Exponential Moving Averages

Wir wollen folgend betrachten, wie man unter Vorliegen von Elementen , wobei (ein Zeitindex ist) den Durchschnitt berechnet, mit der Prämisse, dass wir die jüngste Vergangenheit (also nur Elemente aus der Menge) dafür nutzen möchten.

Normalerweise berechnen wir den Durchschnitt einfach mit

wir wollen jetzt aber nur aus der selektierten Menge den Durchschnitt bilden:

[!Req] Umsetzung des Durchschnittes der jüngsten Vergangenheit

Wenn wir jetzt also den Durchschnitt für eine selektive Menge von Zeitdaten berechnen wollen, brauchen wir eben diese Werte von , also

wie können wir das mit EMA umsetzen? welche vorteile hat das? Wozu wird alpha in der Formel genutzt? #card

Wir bräuchten, um immer die recenten Werte zu speichern, also mehr Speicher - neben der Speicherung aller Daten - und somit möchten wir eine andere Struktur betrachten.

Wir wenden hierbei die EMA - Exponentiell gleitende Durchschnitte - an, die die jüngste Vergangenheit stärker berücksichtigen, als die ältere, dabei aber keinen weiteren Speicher brauchen!

Wir können sie folgend beschreiben:

Hierbei gibt der Parameter die Länge des Durchschnittes an

er wird aktualisiert und berücksichtigt einen Teil des Durchschnitttes durch einen Teil des neuen Inputs - den wir jetzt etwa hinzugefügt haben. Ferner gilt:

  • gibt uns keinen Durchschnitt und wir nehmen einfach die Werte direkt
  • für dominiert der Durchschnitt den gesamten Wert ( weil die Wichtung davon halt steigt)
  • meistens ist der effektive Durchschnittshorizont

Learning Rates

Ein weiteres Maß, was uns hilft den Gradientenabstieg zu verbessern, ist das aktive Anpassen der Learning Rates!

[!Definition]

Wir wissen, dass beim Gradientenabstieg mit die Lernrate das Ausmaß der Änderung der Parameter pro Schritte angibt.

Wir wissen, dass eine feste Lernrate nicht so optimal ist und wir somit eine bessere Lösung finden wollen.

was wäre eine Möglichkeit diese Learning-Rate anpassungsfähig zu machen #card

Man könnte etwa immer mit großen Updates anfangen ( also groß) und dann Schritt für Schritt kleinere wählen. Also etwa mit

Besser wäre noch weiter:

  • adaptive learning rates –> also solche, die aufgrund von Parametern anpassen und somit verschieden skalieren können
  • Lernraten schedule: Lernratenabnahme um nach einigen Epochen und weiterhin kosinusförmige Lernraten.

Wir wollen ferner Adaptive Learning Rates genauer betrachten und einige Varianten dafür betrachten.

Adaptive Learning Rates | RMSprop

[!Bsp] RMSprop - Root Mean Square Propagation

Als Grundlegende Idee: wir skalieren die Lernrate pro Parameter/Gewicht, um dabei eine ähnliche Update-Größe zu erhalten.

Wir werden also den Durchschnitt über die Magnituden der vergangenen Gradienten komponentenweise (also für jedes Gewicht) berechnen. Das machen wir folgend:

was können wir aus dieser Betrachtung ziehen, wie skalieren wir? Wie verhält sich die Lernrate? Was müssen wir nach Berechnung des obigen Durchschnittes anschließend tun? #card

  • wir skalieren hier also die Lernrate umgekehrt proportional zur Größe des Gradienten
  • dabei werden dann kleine Größen also zu einer erhöhten Lernrate führen
  • ferner könenn wir hiermit vanishing / exploding Gradients verhindern

haben wir dann den Durchschnitt entsprechend berechnet, werden wir anschließend den Gradienten der skalierten Lernrate anwenden:

Wir verwenden hier nur um die Division mit 0 zu verhindern xd. Daher ist er meist auch sehr klein:

  • nennen wir dann also den Regularisierer
  • ist meistens und gibt an, wie viele vergangene Gradienten wir berücksichtigen / einbeziehen! (das wären damit also 1000 Stück)

Adaptive Learning Rates | Adam

Adam verwendet RMSprop und auch Momentum, merged also beide Ansätze zusammen!

[!Definition] Adam

Als Kernidee formulieren wir: Wir skalieren die Lernrate jedes Parameters durch die Mittelwerte/Magnituden!

Wir berechnen in diesem Modell also folgend die Mittelwerte des Gradienten (Mittelwert) und dessen Varianz - sie ist nicht zentriert! - folgend: und die Varianz mit

(Bedenke, dass wir das wieder für jeden einzelnen Parameter machen!)

Was müssen wir anschließend noch tun, wie? #card

Wir müssen dann noch den mittleren Gradienten skaliert anwenden - wie bei RMSProp:

Wir resultieren hierbei ähnlich wie bei den Signal-Rausch-Verhältnissen!

  • kleiner Mittelwert und große Varianz: viel Rauschen, kleine Lenrrate
  • großer Mittelwerrt und große Varianz: vertrauenwürdiges Signal, normale Lernrate

[!Tip] Umsetzung von Adam

Wir wollen Adam mehr oder weniger anwenden:

womit beginnen wir, was muss danach bzgl. des Bias folgen? Was sind Standardwerte für mu,eta,beta,epsilon? #card

Zunächst möchten wir also und - die ersten beiden Momente, die wir definieren - mit 0 ansetzen!

–> Es wird nun eine Bias-Korrektur durchgeführt, um den Bias aus der Initialisierung zu entfernen! Dafür korrigieren wir und !

und weiter: ( meint hier den Exponent beim Zeitschritt !)

–> Folgerung: Da erhalten wir ( siehe geometrische Reihen) und somit passiert diese Korrektur nur am Anfang!

Standardparameter wären ferner:

  • ( ist aber stabiler)

Bemerkung | Einordnung

[!Bsp] Folgerungen zu adaptive learning rates

Tatsächlich ist der Squared-Descent-Gradient (SDG) mit gut abgestimmten Learning Rates meist schon sehr gut / konkurrenzfähig!

Adaptive Learning Rates Adam ist der De-Facto-Standard, da er weniger Parameterabstimmungen erfordert!

Man entwickelt diese Optimizer für die Learning Rate primär für den Trainingstart, jedoch laufen sie während des gesamten Trainings weiter / sind aktiv.

Es gibt hier noch viele weitere Optimizer, jedoch gibt es keinen überlegenen (noch!)

  • Entweder man verwendet einen Optimizer und prüft verschiedene Hyperparameter
  • oder man probiert die gleiche Anzahl unterschiedlicher Optimizer mit ihren Standards

-> Bei beiden werden wir dann ähnliche Ergebnisse erhalten!

Batch-Normalization

Wir wollen jetzt noch eine Optimierung betrachten, die darauf abzielt die Layer des DNN so anzupassen, das sie alle ähnliche normalisierte! Aktiverungen haben.

[!Definition] BachtNorm

Was beschreiben wir mit der Batch-Norm? #card

Wir normalisieren die Aktivierung jedes Neurons, sodass der Mittelwert und die Varianz innerhalb jedes mini-batches ist (also wir wollen eine Standardverteilung erhalten(?))

wir fügen dann lernbare Parameter hinzu, um die normalisierten Werte zu skalieren und /oder zu verschieben.

Für einen Mini-Batch berücksichtigen wir (also in dem Layer die Berechnung der Werte ()) mit dem Mittelwert und der Standardabweichung folgend: -> Wir normalisieren die Pre-Aktivierung der Hidden unit folgend:

Danach skalieren und verschieben wir diese folgend: wobei:

  • und ebenfalls durch den Gradient Descent gelernt werden (können/müssen actually).
  • –> Damit erreichen wir eine schnellere Trainingskonvergenz!

Wir wollen das ganz konkret für einen beliebigen Punkt berechnen!

[!Feedback]

Um klarzustellen, wie der Mittelwert und die Standardabweichung berechnet werden:

Für ein Batch mit Datenpunkten erhalten wir folgend den angepassten Wert des Batches folgend:

Wie können wir ihn berechnen? Welche Vorteile und Nachteile ziehen wir hieraus? #card


Vorteile, die wir erhalten:

  • es verbessert den Gradientenfluss –> vanishing / exploding gradients werden verhindert
  • ermöglicht hohe Learning rates - ohne direkt über die Ziele zu schießen!
  • es reduziert die Empfindlichkeit gegenüber der Initialisierung
  • Wir erhalten hier eine Regularisierung! –> Es fügt ein Rauschen zu den Aktivierungen innerhalb der Layer hinzu –> damit haben wir ein Measure gegen Overfitting! erhalten!

Nachteile/Überlegungen dazu:

  • Bei der Batch-Norm werden die “Layers” typischerweise vor der Aktivierungsfunktion platziert!
  • für jedes batch wird der Mittelwert und die Varianz berechnet, während des Trainings zumindest!
  • bei der Inferenz: –> ein gleitender Durchschnitt dieser Statistiken während des Trainings - oder dem Testbatch <– wird angewandt.
  • man brauch eine sorgfältige Implementierung dieser Struktur/ Idee

Convolutional Neural Networks #refactor

Wir haben bis dato immer vollständig verbundene Netze betrachtet und analysiert. Damit werden also alle Eingaben mit der gleichen Relevanz behandelt. und somit alle betrachtet.

[!Hinweis] Problem bei der Betrachtung aller Eingaben

(Am Beispiel von Bilderkennung)

Welches Problem haben wir, wenn wir immer alle Eingaben betrachten und daraus ein Netz bilden/ trainieren? #card

Betrachten wir etwa ein Bild der Größe Eingaben (also Pixel), dann sehen wir hier schon, dass es immens groß wird und bei steigender Größe nur noch schlimmer wird.

Weiterhin: wenn sich etwa ein Bild nur minimal ändert -> für Menschen etwa gar nicht so sehr - werden die Daten schon signifkant anders sein und somit eventuell das Modell beeinflussen ( wenn wir etwa ein Bild nach rechts verschieben oder anders croppen

–> Wir wollen also irgendwie die Dichte von Informationen verstärken bzw. so anpassen, dass wichtige Daten aufgenommen und betrachtet werden können, während unwichtige Dinge herausgelassen werden.

Ferner können wir dafür etwa folgende Aspekte betrachten:

  • lokale Strukturen existieren (bei Bildern)
  • Verschiebungen von Bildern um einen Pixel sollte die Semantik des Bildes nicht verändern

Wir möchten uns dafür jetzt einige Techniken anschauen, die helfen die Informationen zu reduzieren und die wichtigsten zu erhalten / zu filtern.

Lokalität und Verschiebungsinvarianz ausnutzen | Convolution

[!Idea]

Wie obig benannt, wollen wir jetzt das Netzwerk auf weniger Input laufen lassen, indem wir die Darstellung von lokalen Strukturen anwenden und ferner auch die Verschiebungsinvarianz anwenden

Was können wir hieraus machen, was sind convolutional layers? #card

Aus dieser Betrachtung wollen wir dann jetzt Convolutional Layers bauen:

  • Jede Einheit schaut hierbei nur ein kleines Fenster des gesamten Bildes an
  • Jede Einheit berechnet aber auch genau das Gleiche –> Deterministisch

Damit können wir dann das Bild in seiner Menge verringern, aber die wichtigen Daten behalten!

Das wird folgend umgesetzt:

[!Definition] Convolutional Layers

betrachten wir die obige Grafik, wie funktioniert die Konvolution hier? #card

Wir wenden einen Kernel an, welcher quasi ais Filter agiert und uns dabei helfen wird bestimmte Daten aus einer großen Menge zu extrahieren / zu übernehmen.

Im Beispiel werden wir etwa wie folgt vorgehen:

[!Definition] Convolution Layer / Berechnung

Wir wollen das Konzept ferner noch formal beschreiben:

Betrachten wir also ein Eingangsbild:

Ferner brauchen wir noch die Gewichte –> sie werden das kleinere Bild bilden, welches reduziert wurde / ist.

Wie definieren wir jetzt den Kernel? Wo finden wir hier die Struktur, die wir später optimieren sollten ( also die Wichtung) und somit den Gradientenabstieg? Was passiert noch in der Praxis #card

Der Konvolutionskern / Kernel gibt die Gewichte an (bedenke, dass dieser Kernel für jeden Block angewandt wird!) und wird beschrieben mit:

Wir können dann sehen, wie wieder die Aktivierungsfunktion in dieser Idee gebunden / enthalten ist, denn: –> Wir wenden also für jeden Eintrag immer die Gewichte - welche im Kernel gespeichert sind an- und berechnen dann die Ausgabe.

Hier ist wieder der Bias

–> Das Bild kann dann also mit dem gelernten Filter gefiltert / bearbeitet werden!

Unter allen Einheiten werden die Parameter geteilt –> weil wir den Kernel mehrfach auf verschiedene Blöcke anwenden!

(In der Praxis): -> man hat meist mehrere Filter gleichzeitig auf ein Bild laufen –> es gibt also viele Kanäle, die das Bild verschieden “darstellen”

Convolutional Layers | Beispiel Pooling

Zuvor haben wir schon die Methode gesehen, bei welcher wir einen Kernel anwenden, um das Bild anzupassen.

Es gibt natürlich noch weitere Ideen / Ansätze:

[!Req] Definition | Max Pooling | Min Pooling

Wir möchten eine Reduktion der Größe von Bildern - der Darstellung dieser als Matrix - umsetzen.

Wie können wir das mit “Pooling” umsetzen? Welche zwei Arten betrachten wir? #card

Wir können hier Pooling anwenden, welches ein Bild durch eine definiere Größe ersetzt, also Matrizen.

Es gibt zwei Ansätze:

  • Max-Pooling, was in den Kacheln der Größe den maximalen Wert nimmt
  • Mean-Pooling, was in den Kacheln den mittleren Wert extrahiert@

Am Beispiel etwa:


Definition | Anwendung | CNNs

[!Feedback] Umsetzung eines CNN

Angenommen wir wollen für ein Eingabebild eine Erkennung von Inhalten bestimmen / berechnen:

Wie gehen wir mit diesem CNN vor? Welche Schritte durchläuft es? #card

Wie in der Grafik zu erkennen, durchlaufen wir mehrere Schichten, die verschiedene Aufgaben haben:

Es besteht grundsätzlich aus vielen Convolutional / Pooling Layers welche das Bild:

  • in verschiedene Kanäle, meist einteilt ( mit verschiedenen Fokus quasi )
  • es werden in den Layers die Gewichte geteilt!
  • das Netz extrahiert Merkmale aus dem Bild

Ferner, weil wir immer weiter abstrahieren und “komprimieren”, werden wir immer weiter abstrahierte Convolutional layers

Weitere Anpassungen

Betrachten wir CNNs, dann sind hier noch weitere Aspekte notwendig, die dabei helfen, Bilder richtig zu reduzieren bzw. zu verarbeiten. Zwei dieser Konzepte wollen wir uns noch anschauen:

Padding

[!Definition]

Wir wissen, dass durch die Convolution die Dimension reduziert wird.

wie kann das behoben werden, wie wird es umgesetzt? #card

Durch Padding können wir diese Reduktion vermeiden, indem wir Nullen um das Bild drumherum setzen ( bevor durch den Kernel gefiltert wird!) und somit verlieren wir weniger Dimensionen.

Hierbei wird das Padding gewählt mit

Visuell also:

Stride

[!Definition] Stride

Wenn wir die Convolution ansetzen, werden wir den Kernel immer über das Bild setzen und somit nach und nach konvertieren.

Was gibt uns Stride an? #card

Mit Stride wird festgelegt um wie viele Pixel der Kernel immer verschoben wird –> damit wir etwa verhindern, dass bestimmte Bereiche mehrfach durch den Kernel bearbeitet werden.

Visuell etwa:


Bekannte Architekturen:

Mit das erste Netz, was in dieser Struktur funktionierte - aber nicht sehr gut war - ist das LeNet-5 ( Veröffentlich ==1998!==)

Es besteht aus etwa Gewichten und konnte einen Testfehler von auf dem MNIST-Datensatz erzielen!


AlexNet - von Krizhevsky (2012) (Hat sehr viel angestoßen, weil es so viel schneller / besser war, als die vorherigen!)


VGG - Simonyan und Zisserman (2012)

Ist auch relativ bekannt und schnell.

Hier ist die Hauptkomponente:

  • Convolutional Kernels von der Größe im Gegensatz zu variablen Größen in AlexNet –> dadurch waren weniger Parameter notwendig!

GoogLeNet (2014 - Szegedy) (Ist riiesig!)

Das Inception-Modul besteht aus Convolutional Kernels () die parallel arbeiten und aggregiert werden. –> Jedes Inception-Modul kann dann Merkmale auf verschiedenen Ebenen erfassen

Es hat auch Zwischenoutputs, die man während des Trainings verwenden kann!


ImageNet –> Als Benchmark für CNN:

  • großer Datensatz mit 14 Millionen Bildern mit 20.000 Kategorien!
  • üblicher Ausschnitt ist ImageNet-1K mit 1.2 Millionen Bildern mit etwa 1000 Klassen
  • Es gibt einen Wettbewerb, der den besten Recognizer kürt / sucht

[!Attention] Größer ist nicht immer besser!

Wir sehen folgend, dass mit größeren Netzen nicht zwingend bessere Werte erzielt werden können.


Overfitting verhindern: #refactor

[!Idea] Grund der Regularisierung

Wir haben jetzt starke Netze konstruiert, welche sich durch viele Schichten auf bestimmte Aufgaben spezialisieren und diese lernen können.

Es kann weiterhin zu Overfitting kommen

Das Auftreten des Overfittings möchten wir folgend unter Anwendung von zwei Methoden unterbinden oder verringern.

Early Stopping

[!Definition]

Wir wollen folgend ein Verfahren definieren, was mit folgender Grundprämisse beginnt und anschließend Overfitting verhindern möchte:

  • unser neuronales Netz wird zu Beginn relativ kleine Gewichte aufweisen / haben
  • Desto länger wir trainieren, desto höher wird die Komplexität des Netzes - und somit dessen Gewichte.

Wie können wir unter der Voraussetzung jetzt Overfitting verhindern? #card

Im Prinzip wird early Stopping snapshots von früheren Parametern machen und so, bei fortlaufendem Training, alte Parameter, die einen besseren Output bei der validation erhalten haben, wiederherstellen.

Wir versuchen also das Overfitting zu verhindern, indem wir auf einen älteren Zustand springen, wenn wir bemerken, dass unser Training für die validation schlechtere Werte ausgibt.

Regularisation via Weight Decay

[!Req]

Erinnern wir uns wieder an **Regularisierung | Ridge-Regression ** - wo wir auch einen Regularizer eingebracht haben, um bestimmte Gewichte “bestrafen” zu können, also Penalties für bestimmte, etwa große, Gewichte geben.

Was werden wir für diese Methode anwenden? Wie übt sich dieser beim Gradientenabstieg aus? #card

Wir fügen jetzt bei unserer Struktur auch einen Regularizer ein, welcher spezifisch große Gewichte “bestraft”:

Wobei hier die Regularisierungsstärke ist (wie stark der Einfluss ist)

Damit manifestiert er sich als ein “Weight Decay” Term während des Gradientenabstieg. Also folglich:

Das heißt, wenn das Gewicht sehr groß ist, wird dann entsprechend ein starker Penalty durch den Term verursacht und somit das Update für diesen Vektor einen starken Einfluss verursachen

some further resource might be found here: https://benihime91.github.io/blog/machinelearning/deeplearning/python3.x/tensorflow2.x/2020/10/08/adamW.html


Dropout

[!Example] Definition | Dropout

Wir wollen noch eine weitere Möglichkeit zur Verminderung von Overfitting betrachten.

Gehen wir dabei von folgender Prämisse aus:

  • Unser Netzwerk lernt nach und nach Parameter und verwendet dabei “hoffentlich” Bereiche des Netzes, die es benötigt / wo aktiv viele Entscheidungen getroffen werden.
  • Es sollte hierbei beim trainieren am besten zusätzliche Kapazitäten - die es nicht zwingend bräuchte - ignorieren.

Wie können wir daraus jetzt eine Struktur schaffen, die Overfitting vermindern kann? #card

Wir wollen folgendes Prinzip anwenden:

Wir erzeugen eine Regularisierung durch ein gesetztes Rauschen auf den hidden layers(units).

–> Damit kann es im Extremfall dazu kommen, dass manche Eingaben innerhalb der Einheiten vollständig ignoriert werden, etwa weil die Wichtung 0 ist.

Dropout beschreibt also:

  • Es wird eine Eingabe- oder eine versteckte Einheit mit gewisser WSK in jedem Minibatch herausgenommen bzw. “deaktiviert” –> und das netz muss weiter trainieren und sich daran anpassen
  • Wir können somit “zu starke Fokussierung auf bestimmte Parameter” verringern / verhindern

Verwendung von Domänewissen

[!Bsp] Definition

Wir kennen oft die Eigenschaften der Daten, die wir betrachten möchten - das können bestimmte Werte, Invarianzen etc sein.

Als Beispiel können wir eine Rotations/Skalierungsinvarianz betrachten:

Wie können wir diese Information jetzt in das Modell einbinden, sodass es besser erkennen oder gegen die Invarianzen einfacher vorgehen kann? #card

Wir können dem Modell jetzt über zwei Wege die Informationen über etwaige Eigenschaften - hier Invarianzen - der Daten zukommen lassen:

  • Die Invarianz direkt in das Modell einbringen –> etwa erst eine Translation durchfuhren, sodass die Daten vereinheitlicht werden können o.ä.
  • Die Loss-Funktion anpassen
  • oder Data-Augmentation hinzufügen -> Also Transformierte Daten in den Trainingssatz mit einbringen

Data Augmentation

[!Req] Definition | Data Augmentation

Was ist gemeint, wenn wir data augmentation für unser Modell anwenden? #card

Mit Data Augmentation möchten wir Invarianzen o.ä. Eigenschaften unserer Daten explizit in das Modell und den Trainingssatz einbringen.

Das heißt, dass wir etwa diverse Trainingsbeispiele so modifizieren, dass sie etwa verschiedene Drehungen aufweisen, also die Invarianzen einbauen

Normalerweise sollte eine solche Augmentation / Transformation die Labels der abgebildeten Daten nicht ändern.

Betrachten wir Bilder, könnte das u.U. schon passieren.

–> Ist das ein Problem?!

Nicht wirklich, das Modell wird dennoch besser / sicherer


Phänomen: Double Descent | Bias-Variance-Trade-off++

[!Definition] Double Descent;

Es kann beobachtet werden, dass sehr große Netzwerke weniger stark overfitten. –> Dass das passiert ist “rätselfhaft”, aber es gibt eine Vermutung dafür:

Was beschreibt das “Double-Descent-Phänomen”? #card

(Hierbei gibt die X-Achse die Modellkomplexität (Menge der Parameter) an)

Weitere Infos dazu finden sich hier: link