Machine Learning für Softwareentwickler. Paolo Perrotta. Читать онлайн. Newlib. NEWLIB.NET

Автор: Paolo Perrotta
Издательство: Bookwire
Серия:
Жанр произведения: Математика
Год издания: 0
isbn: 9783969100264
Скачать книгу
»Parameter« genannt, was in der Programmierung jedoch etwas unglücklich ist, da wir die Bezeichnung »Parameter« hier schon für etwas anderes verwenden. Es ist sehr leicht möglich, Parameter wie w und b mit den Parametern von Funktionen wie train() zu verwechseln.

      Um das zu vermeiden, werden die Parameter der Funktion train() im ML-Umfeld als Hyperparameter bezeichnet, also als »Parameter höherer Ordnung«. Kurz gesagt, legen wir Hyperparameter wie iterations und lr fest, damit die Funktion train() Parameter wie w und b ermitteln kann.

      In den ersten beiden Kapiteln haben Sie eine Menge Informationen erhalten und viele neue Begriffe kennengelernt. Lassen Sie mich daher eine Zusammenfassung geben.

      In diesem Kapitel haben wir unser erstes Programm zum überwachten Lernen geschrieben. Ein System für überwachtes Lernen wird mit Beispielen trainiert, die jeweils aus einer Eingabevariablen und einem Label bestehen. In unserem Fall waren die Eingabevariablen jeweils eine Anzahl von Reservierungen und die Labels jeweils eine Anzahl verkaufter Pizzas.

      Beim überwachten Lernen werden die Beispiele mit einer Funktion angenähert, die oft als Modell bezeichnet wird. In unserem ersten Programm ist das Modell eine Gerade, die durch zwei Parameter bestimmt wird, nämlich Gewicht und Bias. Das Prinzip der Annäherung von Beispielen durch eine Gerade wird lineare Regression genannt.

      Die erste Phase beim überwachten Lernen ist die Trainingsphase, in der das System die Parameter des Models anpasst, um eine Annäherung an die Beispiele zu erreichen. Bei dieser Suche richtet sich das System nach der Verlustfunktion, die die Abweichung des aktuellen Modells von der Grundwahrheit misst: je geringer der Verlust, umso besser das Modell. Unser Programm berechnet den Verlust mit der Formel für den mittleren quadratischen Fehler. Das Training resultiert in dem Gewicht und dem Bias, die zu dem geringsten Verlust führen, den das System finden konnte.

      Die in der Trainingsphase ermittelten Parameter werden anschließend in der Vorhersagephase des überwachten Lernens genutzt. Dabei werden Eingaben ohne Labels an das parametrisierte Modell übergeben. Das Ergebnis ist eine Vorhersage wie: »Heute Abend können Sie erwarten, 42 Pizzas zu verkaufen.«

      In gewisser Hinsicht entsprechen die Trainings- und die Vorhersagephase des überwachten Lernens der Kompilierungs- und Laufzeitphase in der Programmierung. Das Training ist gewöhnlich datenhungrig und erfordert umfassende Berechnungen, wohingegen die Vorhersage keinen großen Aufwand verursacht. Selbst in unserem kleinen Programm braucht die Funktion train() merkliche Zeit, um eine passende Gerade zu den Beispielen zu finden, während predict() einfach nur eine rasend schnelle Multiplikation durchführt.

      In umfangreichen Systemen wird der Unterschied zwischen Training und Vorhersage noch deutlicher: Das Training eines Spracherkennungssystems kann Wochen dauern und die Verarbeitung von Millionen von Audiodateien auf mehreren Prozessoren erfordern. Anschließend können Sie das System auf einem Smartphone installieren und dazu verwenden, ohne großen Aufwand die Bedeutung einzelner Stichproben zu bestimmen.

      Das war eine ganze Menge Stoff. Ich verspreche Ihnen aber, dass in keinem weiteren Kapitel so viele neue Begriffe auf einen Schlag eingeführt werden.

      Auf der anderen Seite haben wir in diesem Kapitel von Grund auf ein Programm zum überwachten Lernen erstellt, was schon eine ziemliche Leistung ist. Heutzutage nutzt der Großteil der ML-Software, darunter auch die meisten der erstaunlichen Deep-Learning-Systeme, das Prinzip des überwachten Lernens. Diese Systeme sind natürlich viel komplizierter als unser Pizzavorhersageprogramm. Statt einer Liste von Reservierungszahlen nehmen sie hochauflösende Bilder als Eingabe entgegen, und statt eines einfachen Modells mit zwei Parametern haben sie komplexe Modelle mit Zehntausenden von Parametern. Allerdings funktionieren sie nach denselben Grundprinzipien wie unser bescheidenes Python-Programm.

      Im nächsten Kapitel bauen wir auf dieser Grundlage auf und lernen einen der wichtigsten Algorithmen des Machine Learning kennen.

      Bevor Sie fortfahren, können Sie noch ein wenig mit dem Code herumspielen. Das ist eine gute Möglichkeit, um die Prinzipien besser zu verinnerlichen.

      Als Erstes können Sie sich dazu etwas besser mit den Hyperparametern des Systems vertraut machen (siehe den Kasten »Hyperparameter« auf Seite 37). Versuchen Sie, den Wert des Arguments lr von train() zu ändern. Was geschieht, wenn Sie lr auf einen kleineren Wert setzen – oder einen größeren? Welche Vor- und Nachteile ergeben sich dabei jeweils? Wenn Sie diese Experimente abgeschlossen haben, können Sie im Verzeichnis 02_first/solution nachschlagen, wo Sie klare Antworten auf diese Fragen erhalten.

      Am Gradienten entlang

      Im letzten Kapitel haben wir bereits etwas geschafft, auf das wir stolz sein können: Wir haben Code geschrieben, der lernen kann. Sollten wir diesen Code jedoch von einem Informatiker überprüfen lassen, so würde dieser ihn als mangelhaft einstufen. Insbesondere beim Anblick der Funktion train() würde er den Kopf schütteln. »Für diese einfache Aufgabe mag der Code in Ordnung sein«, mag der gestrenge Informatiker sagen, »aber er lässt sich nicht auf reale Probleme skalieren.«

      Womit er recht hätte. In diesem Kapitel werden wir zwei verschiedene Dinge tun, damit es nicht zu einer solchen Kritik kommt. Erstens verzichten wir darauf, den Code einem Informatiker zur Überprüfung vorzulegen. Zweitens schauen wir uns die Probleme der jetzigen Implementierung von train() genauer an und lösen sie mit einem der grundlegenden Prinzipien des Machine Learnings, nämlich einem Algorithmus, der als Gradientenverfahren, Gradientenabstieg oder Verfahren des steilsten Abstiegs bekannt ist. Ebenso wie unser bisheriger Code von train() dient dieses Verfahren dazu, das Minimum der Verlustfunktion zu finden, allerdings schneller, genauer und allgemeiner als mit dem Code aus dem vorherigen Kapitel.

      Der Gradientenabstieg ist nicht nur für unser kleines Programm nützlich. Ohne dieses Verfahren werden Sie beim Machine Learning nicht weit kommen. Dieser Algorithmus wird uns in verschiedener Form das ganze Buch hindurch begleiten.

      Schauen wir uns als Erstes das Problem an, das wir mit dem Gradientenverfahren lösen wollen.

      Unser Programm kann erfolgreich Pizzaverkaufszahlen vorhersagen. Aber warum sollten wir es dabei belassen? Vielleicht können wir mit demselben Code ja auch andere Dinge vorhersagen, etwa Bewegungen auf dem Aktienmarkt. Damit könnten wir über Nacht reich werden! (Um Ihnen die Enttäuschung zu ersparen: Nein, das funktioniert nicht.)

      Allerdings stoßen wir schon bald auf ein Problem, wenn wir versuchen, unser Programm zur linearen Regression auf eine andere Aufgabe anzuwenden. Unser Code verwendet ein einfaches Geradenmodell mit zwei Parametern, nämlich dem Gewicht w und dem Bias b. In der Praxis sind jedoch meistens komplexe Modelle mit mehr Parametern erforderlich. Denken Sie zum Beispiel an das Ziel, das wir uns für Teil I dieses Buchs gesetzt haben, nämlich ein System zu konstruieren, das Bilder erkennen kann. Ein Bild ist viel komplizierter als eine einzelne Zahl, weshalb wir auch ein Modell mit weit mehr Parametern brauchen als für das Pizzaprogramm.

      Wenn wir unserem Modell weitere Parameter hinzufügen, geht seine Leistung jedoch in den Keller. Betrachten Sie dazu noch einmal die Funktion train() aus dem letzten Kapitel:

      def train(X, Y, iterations, lr):

      w = b = 0

      for i in range(iterations):

      current_loss = loss(X, Y, w, b)

      print("Iteration %4d => Loss: %.6f" % (i, current_loss))

      if