Deep Learning Neuronale Netze in einfachem Englisch erklärt

Maschinelles Lernen und insbesondere tiefes Lernen sind zwei Technologien, die die Welt verändern.

Nach einem langen "KI-Winter", der sich über 30 Jahre erstreckte, haben Rechenleistung und Datensätze endlich die Algorithmen für künstliche Intelligenz eingeholt, die in der zweiten Hälfte des 20. Jahrhunderts vorgeschlagen wurden.

Dies bedeutet, dass Deep-Learning-Modelle endlich verwendet werden, um effektive Vorhersagen zu treffen, die reale Probleme lösen.

Für Datenwissenschaftler und Softwareentwickler ist es wichtiger denn je, ein umfassendes Verständnis dafür zu haben, wie Deep-Learning-Modelle funktionieren. Dieser Artikel erklärt die Geschichte und die grundlegenden Konzepte von Deep-Learning-Neuronalen Netzen in einfachem Englisch.

Die Geschichte des tiefen Lernens

Deep Learning wurde in den 1980er Jahren von Geoffrey Hinton konzipiert. Er gilt weithin als der Gründungsvater des Bereichs des tiefen Lernens. Hinton arbeitet seit März 2013 bei Google, als sein Unternehmen DNNresearch Inc. übernommen wurde.

Hintons Hauptbeitrag auf dem Gebiet des tiefen Lernens bestand darin, maschinelle Lerntechniken mit dem menschlichen Gehirn zu vergleichen.

Insbesondere schuf er das Konzept eines "neuronalen Netzwerks", eines Deep-Learning-Algorithmus, der ähnlich wie die Organisation von Neuronen im Gehirn aufgebaut ist. Hinton verfolgte diesen Ansatz, weil das menschliche Gehirn wohl die leistungsstärkste heute bekannte Rechenmaschine ist.

Die von Hinton geschaffene Struktur wurde als künstliches neuronales Netzwerk (oder kurz künstliches neuronales Netz) bezeichnet. Hier ist eine kurze Beschreibung ihrer Funktionsweise:

  • Künstliche neuronale Netze bestehen aus Knotenschichten
  • Jeder Knoten ist so konzipiert, dass er sich ähnlich wie ein Neuron im Gehirn verhält
  • Die erste Schicht eines neuronalen Netzes wird inputSchicht genannt, gefolgt von hiddenSchichten und schließlich der outputSchicht
  • Jeder Knoten im neuronalen Netz führt eine Art Berechnung durch, die an andere Knoten weiter unten im neuronalen Netz weitergegeben wird

Hier ist eine vereinfachte Visualisierung, um zu demonstrieren, wie dies funktioniert:

Eine Visualisierung eines künstlichen neuronalen Netzes

Neuronale Netze waren ein immenser Fortschritt im Bereich des tiefen Lernens.

Es dauerte jedoch Jahrzehnte, bis maschinelles Lernen (und insbesondere tiefes Lernen) an Bedeutung gewann.

Wir werden im nächsten Abschnitt untersuchen, warum.

Warum Deep Learning nicht sofort funktionierte

Wenn Deep Learning ursprünglich vor Jahrzehnten konzipiert wurde, warum gewinnt es heute gerade erst an Dynamik?

Dies liegt daran, dass jedes ausgereifte Deep-Learning-Modell eine Fülle von zwei Ressourcen erfordert:

  • Daten
  • Rechenleistung

Zum Zeitpunkt der konzeptionellen Geburt von Deep Learning hatten die Forscher weder Zugang zu Daten noch zu genügend Rechenleistung, um aussagekräftige Deep-Learning-Modelle zu erstellen und zu trainieren. Dies hat sich im Laufe der Zeit geändert, was dazu geführt hat, dass Deep Learning heute eine herausragende Rolle spielt.

Neuronen im Deep Learning verstehen

Neuronen sind eine kritische Komponente jedes Deep-Learning-Modells.

In der Tat könnte man argumentieren, dass man tiefes Lernen nicht vollständig verstehen kann, wenn man ein tiefes Wissen darüber hat, wie Neuronen funktionieren.

Dieser Abschnitt führt Sie in das Konzept der Neuronen beim tiefen Lernen ein. Wir werden über den Ursprung von Deep-Learning-Neuronen sprechen, wie sie von der Biologie des menschlichen Gehirns inspiriert wurden und warum Neuronen heutzutage in Deep-Learning-Modellen so wichtig sind.

Was ist ein Neuron in der Biologie?

Neuronen im tiefen Lernen wurden von Neuronen im menschlichen Gehirn inspiriert. Hier ist ein Diagramm der Anatomie eines Gehirnneurons:

Die Anatomie eines Neurons im Gehirn

Wie Sie sehen können, haben Neuronen eine interessante Struktur. Gruppen von Neuronen arbeiten im menschlichen Gehirn zusammen, um die Funktionen auszuführen, die wir in unserem täglichen Leben benötigen.

Die Frage, die Geoffrey Hinton während seiner wegweisenden Forschung in neuronalen Netzen stellte, war, ob wir Computeralgorithmen entwickeln können, die sich ähnlich wie Neuronen im Gehirn verhalten. Die Hoffnung war, dass wir durch Nachahmung der Struktur des Gehirns einen Teil seiner Fähigkeiten erfassen könnten.

Zu diesem Zweck untersuchten die Forscher das Verhalten von Neuronen im Gehirn. Eine wichtige Beobachtung war, dass ein Neuron an sich nutzlos ist. Stattdessen benötigen Sie Netzwerke von Neuronen, um sinnvolle Funktionen zu generieren.

Dies liegt daran, dass Neuronen durch Empfangen und Senden von Signalen funktionieren. Insbesondere dendritesempfangen die Neuronen die Signale und leiten diese Signale durch die axon.

Die dendriteseines Neurons sind mit denen axoneines anderen Neurons verbunden. Diese Verbindungen werden genannt synapses, ein Konzept, das auf das Gebiet des tiefen Lernens verallgemeinert wurde.

Was ist ein Neuron im tiefen Lernen?

Neuronen in Deep-Learning-Modellen sind Knoten, durch die Daten und Berechnungen fließen.

Neuronen arbeiten so:

  • Sie empfangen ein oder mehrere Eingangssignale. Diese Eingangssignale können entweder aus dem Rohdatensatz oder von Neuronen stammen, die auf einer vorherigen Schicht des neuronalen Netzes positioniert sind.
  • Sie führen einige Berechnungen durch.
  • Sie senden einige Ausgangssignale über a an Neuronen, die tiefer im neuronalen Netz liegen synapse.

Hier ist ein Diagramm der Funktionalität eines Neurons in einem tief lernenden neuronalen Netz:

Die Funktion eines Neurons in einem Deep-Learning-Modell

Lassen Sie uns dieses Diagramm Schritt für Schritt durchgehen.

Wie Sie sehen können, können Neuronen in einem Deep-Learning-Modell Synapsen haben, die mit mehr als einem Neuron in der vorhergehenden Schicht verbunden sind. Jeder Synapse ist eine zugeordnet weight, was sich auf die Bedeutung des vorhergehenden Neurons im gesamten neuronalen Netzwerk auswirkt.

Gewichte sind ein sehr wichtiges Thema im Bereich des Deep Learning, da die Anpassung der Gewichte eines Modells der primäre Weg ist, auf dem Deep Learning-Modelle trainiert werden. Sie werden dies später in der Praxis sehen, wenn wir unsere ersten neuronalen Netze von Grund auf neu aufbauen.

Sobald ein Neuron seine Eingaben von den Neuronen in der vorhergehenden Schicht des Modells erhält, addiert es jedes Signal multipliziert mit seinem entsprechenden Gewicht und leitet es wie folgt an eine Aktivierungsfunktion weiter:

Aktivierungsfunktion eines Neurons

Die Aktivierungsfunktion berechnet den Ausgabewert für das Neuron. Dieser Ausgabewert wird dann über eine andere Synapse an die nächste Schicht des neuronalen Netzwerks weitergegeben.

Dies dient als umfassender Überblick über Deep-Learning-Neuronen. Machen Sie sich keine Sorgen, wenn es viel zu tun gab - wir werden im Rest dieses Tutorials viel mehr über Neuronen erfahren. Im Moment reicht es aus, wenn Sie ein umfassendes Verständnis dafür haben, wie sie in einem Deep-Learning-Modell strukturiert sind.

Deep Learning-Aktivierungsfunktionen

Aktivierungsfunktionen sind ein Kernkonzept, das beim tiefen Lernen zu verstehen ist.

Sie ermöglichen es Neuronen in einem neuronalen Netzwerk, über ihre Synapsen miteinander zu kommunizieren.

In diesem Abschnitt lernen Sie, die Bedeutung und Funktionalität von Aktivierungsfunktionen beim Deep Learning zu verstehen.

Was sind Aktivierungsfunktionen beim Deep Learning?

Im letzten Abschnitt haben wir gelernt, dass Neuronen Eingangssignale von der vorhergehenden Schicht eines neuronalen Netzwerks empfangen. Eine gewichtete Summe dieser Signale wird in die Aktivierungsfunktion des Neurons eingespeist, dann wird der Ausgang der Aktivierungsfunktion an die nächste Schicht des Netzwerks weitergeleitet.

Es gibt vier Haupttypen von Aktivierungsfunktionen, die in diesem Lernprogramm behandelt werden:

  • Schwellenwertfunktionen
  • Sigmoid-Funktionen
  • Gleichrichterfunktionen oder ReLUs
  • Hyperbolische Tangentenfunktionen

Lassen Sie uns diese Aktivierungsfunktionen einzeln durcharbeiten.

Schwellenfunktionen

Schwellenwertfunktionen berechnen ein unterschiedliches Ausgangssignal, je nachdem, ob sein Eingang über oder unter einem bestimmten Schwellenwert liegt oder nicht. Denken Sie daran, dass der Eingabewert für eine Aktivierungsfunktion die gewichtete Summe der Eingabewerte der vorhergehenden Schicht im neuronalen Netzwerk ist.

Mathematisch gesehen ist hier die formale Definition einer Deep-Learning-Schwellenfunktion:

Schwellenwertfunktionen

Wie das obige Bild zeigt, wird die Schwellenwertfunktion manchmal auch als a bezeichnet unit step function.

Schwellenwertfunktionen ähneln booleschen Variablen in der Computerprogrammierung. Ihr berechneter Wert ist entweder 1(ähnlich True) oder 0(äquivalent zu False).

Die Sigmoid-Funktion

Die Sigmoid-Funktion ist in der Data-Science-Community aufgrund ihrer Verwendung in der logistischen Regression, einer der wichtigsten Techniken des maschinellen Lernens zur Lösung von Klassifizierungsproblemen, bekannt.

Die Sigmoid-Funktion kann einen beliebigen Wert annehmen, berechnet jedoch immer einen Wert zwischen 0und 1.

Hier ist die mathematische Definition der Sigmoidfunktion:

Sigmoid-Funktionen

Ein Vorteil der Sigmoidfunktion gegenüber der Schwellenwertfunktion besteht darin, dass ihre Kurve glatt ist. Dies bedeutet, dass Ableitungen an jedem Punkt entlang der Kurve berechnet werden können.

Die Gleichrichterfunktion

Die Gleichrichterfunktion hat nicht die gleiche Glätteigenschaft wie die Sigmoidfunktion aus dem letzten Abschnitt. Es ist jedoch immer noch sehr beliebt im Bereich des tiefen Lernens.

Die Gleichrichterfunktion ist wie folgt definiert:

  • Wenn der Eingabewert kleiner als ist 0, wird die Funktion ausgegeben0
  • Wenn nicht, gibt die Funktion ihren Eingabewert aus

Hier wird dieses Konzept mathematisch erklärt:

Gleichrichterfunktionen

Gleichrichterfunktionen werden oft als Rectified Linear UnitAktivierungsfunktionen oder ReLUskurz bezeichnet.

Die hyperbolische Tangentenfunktion

Die hyperbolische Tangentenfunktion ist die einzige Aktivierungsfunktion in diesem Lernprogramm, die auf einer trigonometrischen Identität basiert.

Die mathematische Definition ist unten:

Hyperbolische Tangentenfunktion

Die hyperbolische Tangentenfunktion ähnelt im Aussehen der Sigmoidfunktion, ihre Ausgangswerte sind jedoch alle nach unten verschoben.

Wie funktionieren neuronale Netze wirklich?

Bisher haben wir in diesem Tutorial zwei der Bausteine ​​für den Aufbau neuronaler Netze erörtert:

  • Neuronen
  • Aktivierungsfunktionen

Sie sind jedoch wahrscheinlich immer noch etwas verwirrt darüber, wie neuronale Netze wirklich funktionieren.

In diesem Tutorial werden die bereits besprochenen Teile zusammengestellt, damit Sie verstehen, wie neuronale Netze in der Praxis funktionieren.

Das Beispiel, das wir in diesem Tutorial verwenden werden

In diesem Tutorial wird Schritt für Schritt ein Beispiel aus der Praxis durchgearbeitet, damit Sie verstehen, wie neuronale Netze Vorhersagen treffen.

Insbesondere werden wir uns mit Immobilienbewertungen befassen.

Wahrscheinlich wissen Sie bereits , dass es eine gibt Tonne von Faktoren , die Einfluss auf Immobilienpreise, einschließlich der Wirtschaft, Zinssätze, die Zahl der Schlafzimmer / Bäder, und seine Lage.

Die hohe Dimensionalität dieses Datensatzes macht ihn zu einem interessanten Kandidaten für den Aufbau und das Training eines neuronalen Netzwerks.

Eine Einschränkung in diesem Abschnitt ist das neuronale Netzwerk, mit dem wir Vorhersagen treffen werden. Es wurde bereits trainiert . Wir werden den Prozess zum Trainieren eines neuen neuronalen Netzwerks im nächsten Abschnitt dieses Tutorials untersuchen.

Die Parameter in unserem Datensatz

Beginnen wir mit der Erörterung der Parameter in unserem Datensatz. Stellen wir uns genauer vor, dass der Datensatz die folgenden Parameter enthält:

  • Quadratmeterzahl
  • Schlafzimmer
  • Entfernung zum Stadtzentrum
  • Hausalter

Diese vier Parameter bilden die Eingangsschicht des künstlichen neuronalen Netzwerks. Beachten Sie, dass es in der Realität wahrscheinlich viel mehr Parameter gibt , mit denen Sie ein neuronales Netzwerk trainieren können, um die Immobilienpreise vorherzusagen. Wir haben diese Zahl auf vier beschränkt, um das Beispiel einigermaßen einfach zu halten.

Die grundlegendste Form eines neuronalen Netzes

In seiner grundlegendsten Form besteht ein neuronales Netzwerk nur aus zwei Schichten - der Eingangsschicht und der Ausgangsschicht. Die Ausgabeschicht ist die Komponente des neuronalen Netzes, die tatsächlich Vorhersagen trifft.

Wenn Sie beispielsweise Vorhersagen mit einem einfachen gewichteten Summenmodell (auch als lineare Regression bezeichnet) treffen möchten, hat Ihr neuronales Netzwerk die folgende Form:

Ein grundlegendes neuronales Netzwerk

Obwohl dieses Diagramm etwas abstrakt ist, können die meisten neuronalen Netze auf folgende Weise visualisiert werden:

  • Eine Eingabeebene
  • Möglicherweise einige versteckte Schichten
  • Eine Ausgabeebene

Es ist die verborgene Schicht von Neuronen, die dazu führt, dass neuronale Netze für die Berechnung von Vorhersagen so leistungsfähig sind.

Für jedes Neuron in einer verborgenen Schicht werden Berechnungen unter Verwendung einiger (oder aller) Neuronen in der letzten Schicht des neuronalen Netzwerks durchgeführt. Diese Werte werden dann in der nächsten Schicht des neuronalen Netzwerks verwendet.

Der Zweck von Neuronen in der verborgenen Schicht eines neuronalen Netzwerks

Sie befinden sich wahrscheinlich fragen - was genau tut jedes Neuron in der verborgenen Schicht Mittelwert ? Anders gesagt, wie sollten Praktiker des maschinellen Lernens diese Werte interpretieren?

Im Allgemeinen werden Neuronen in den mittleren Schichten eines neuronalen Netzes 1für einen Eingabewert aktiviert (was bedeutet, dass ihre Aktivierungsfunktion zurückkehrt ), der bestimmte Untereigenschaften erfüllt.

Ein Beispiel für unser Modell zur Vorhersage des Immobilienpreises könnten Häuser mit 5 Schlafzimmern und geringen Entfernungen zum Stadtzentrum sein.

In den meisten anderen Fällen ist es nicht so einfach, die Eigenschaften zu beschreiben, die dazu führen würden, dass ein Neuron in einer verborgenen Schicht aktiviert wird.

Wie Neuronen ihre Eingabewerte bestimmen

Zu Beginn dieses Tutorials schrieb ich: „Für jedes Neuron in einer verborgenen Schicht werden Berechnungen unter Verwendung einiger (oder aller) Neuronen in der letzten Schicht des neuronalen Netzwerks durchgeführt.“

Dies zeigt einen wichtigen Punkt: Jedes Neuron in einem neuronalen Netz muss nicht jedes Neuron in der vorhergehenden Schicht verwenden.

Der Prozess, durch den Neuronen bestimmen, welche Eingabewerte aus der vorhergehenden Schicht des neuronalen Netzes verwendet werden sollen, wird als Training des Modells bezeichnet. Im nächsten Abschnitt dieses Kurses erfahren Sie mehr über das Training neuronaler Netze.

Visualisierung des Vorhersageprozesses eines neuronalen Netzes

Bei der Visualisierung eines neutralen Netzwerks zeichnen wir im Allgemeinen Linien von der vorherigen Schicht zur aktuellen Schicht, wenn das vorhergehende Neuron 0in der gewichteten Summenformel für das aktuelle Neuron ein höheres Gewicht aufweist .

Das folgende Bild hilft dabei, dies zu veranschaulichen:

Ein fertiges neuronales Netzwerk

Wie Sie sehen können, hat nicht jedes Neuron-Neuron-Paar eine Synapse. x4füttert beispielsweise nur drei der fünf Neuronen in der verborgenen Schicht. Dies zeigt einen wichtigen Punkt beim Aufbau neuronaler Netze - dass nicht jedes Neuron in einer vorhergehenden Schicht in der nächsten Schicht eines neuronalen Netzes verwendet werden muss.

Wie neuronale Netze trainiert werden

Bisher haben Sie Folgendes über neuronale Netze gelernt:

  • Dass sie aus Neuronen bestehen
  • Dass jedes Neuron eine Aktivierungsfunktion verwendet, die auf die gewichtete Summe der Ausgaben der vorhergehenden Schicht des neuronalen Netzwerks angewendet wird
  • Ein umfassender Überblick ohne Code darüber, wie neuronale Netze Vorhersagen treffen

Wir haben noch keinen sehr wichtigen Teil des Engineering-Prozesses für neuronale Netze behandelt: wie neuronale Netze trainiert werden.

Jetzt lernen Sie, wie neuronale Netze trainiert werden. Wir werden Datensätze, Algorithmen und allgemeine Prinzipien diskutieren, die beim Training moderner neuronaler Netze zur Lösung realer Probleme verwendet werden.

Hardcodierung vs. Softcodierung

Es gibt zwei Möglichkeiten, wie Sie Computeranwendungen entwickeln können. Bevor Sie sich mit dem Training neuronaler Netze befassen, müssen Sie sicherstellen, dass Sie den Unterschied zwischen hard-codingund soft-codingComputerprogrammen verstehen .

Hardcodierung bedeutet, dass Sie Eingabevariablen und Ihre gewünschten Ausgabevariablen explizit angeben. Anders gesagt, die Hardcodierung lässt dem Computer keinen Raum, um das Problem zu interpretieren, das Sie lösen möchten.

Softcodierung ist das genaue Gegenteil. Es lässt dem Programm Raum, um zu verstehen, was im Datensatz geschieht. Durch Softcodierung kann der Computer seine eigenen Lösungsansätze entwickeln.

Ein konkretes Beispiel ist hier hilfreich. Hier sind zwei Beispiele dafür, wie Sie Katzen in einem Datensatz mithilfe von Soft- und Hardcodierungstechniken identifizieren können.

  • Hardcodierung: Sie verwenden bestimmte Parameter, um vorherzusagen, ob ein Tier eine Katze ist. Genauer gesagt könnte man sagen, wenn das Gewicht und die Länge eines Tieres innerhalb eines bestimmten Bereichs liegen
  • Softcodierung: Sie stellen einen Datensatz bereit, der Tiere enthält, die mit ihrem Arttyp und ihren Merkmalen zu diesen Tieren gekennzeichnet sind. Anschließend erstellen Sie ein Computerprogramm, um anhand der Merkmale im Datensatz vorherzusagen, ob ein Tier eine Katze ist oder nicht.

Wie Sie sich vorstellen können, fällt das Training neuronaler Netze in die Kategorie der Softcodierung. Denken Sie daran, wenn Sie diesen Kurs durchlaufen.

Training eines neuronalen Netzes mit einer Kostenfunktion

Neuronale Netze werden unter Verwendung von a trainiert cost function, einer Gleichung, die verwendet wird, um den in der Vorhersage eines Netzes enthaltenen Fehler zu messen.

Die Formel für eine Deep-Learning-Kostenfunktion (von der es viele gibt - dies ist nur ein Beispiel) lautet wie folgt:

Kostenfunktionsgleichung

Hinweis: Diese Kostenfunktion wird als bezeichnet mean squared error, weshalb sich auf der linken Seite des Gleichheitszeichens eine MSE befindet.

Diese Gleichung enthält zwar viele Formelmathematik, lässt sich jedoch am besten wie folgt zusammenfassen:

Take the difference between the predicted output value of an observation and the actual output value of that observation. Square that difference and divide it by 2.

Um es noch einmal zu wiederholen, beachten Sie, dass dies nur ein Beispiel für eine Kostenfunktion ist, die beim maschinellen Lernen verwendet werden könnte (obwohl dies zugegebenermaßen die beliebteste Wahl ist). Die Auswahl der zu verwendenden Kostenfunktion ist ein komplexes und interessantes Thema für sich und liegt außerhalb des Rahmens dieses Lernprogramms.

Wie bereits erwähnt, besteht das Ziel eines künstlichen neuronalen Netzwerks darin, den Wert der Kostenfunktion zu minimieren. Die Kostenfunktion wird minimiert, wenn der vorhergesagte Wert Ihres Algorithmus so nahe wie möglich am tatsächlichen Wert liegt. Anders gesagt, das Ziel eines neuronalen Netzwerks ist es, den Fehler zu minimieren, den es in seinen Vorhersagen macht!

Ändern eines neuronalen Netzwerks

Nachdem ein anfängliches neuronales Netzwerk erstellt und seine Kostenfunktion unterstellt wurde, werden Änderungen am neuronalen Netzwerk vorgenommen, um festzustellen, ob sie den Wert der Kostenfunktion verringern.

Insbesondere ist die tatsächliche Komponente des neuronalen Netzwerks, die modifiziert wird, das Gewicht jedes Neurons an seiner Synapse, das mit der nächsten Schicht des Netzwerks kommuniziert.

Der Mechanismus, durch den die Gewichte modifiziert werden, um das neuronale Netzwerk zu Gewichten mit weniger Fehlern zu bewegen, wird aufgerufen gradient descent. Im Moment reicht es für Sie zu verstehen, dass der Prozess des Trainings neuronaler Netze folgendermaßen aussieht:

  • Anfangsgewichte für die Eingabewerte jedes Neurons werden zugewiesen
  • Vorhersagen werden unter Verwendung dieser Anfangswerte berechnet
  • Die Vorhersagen werden in eine Kostenfunktion eingespeist, um den Fehler des neuronalen Netzwerks zu messen
  • Ein Gradientenabstiegsalgorithmus ändert die Gewichte für die Eingabewerte jedes Neurons
  • Dieser Vorgang wird fortgesetzt, bis sich die Gewichte nicht mehr ändern (oder bis der Betrag ihrer Änderung bei jeder Iteration unter einen bestimmten Schwellenwert fällt).

Das mag sehr abstrakt erscheinen - und das ist in Ordnung! Diese Konzepte werden normalerweise erst dann vollständig verstanden, wenn Sie mit dem Training Ihrer ersten Modelle für maschinelles Lernen beginnen.

Abschließende Gedanken

In diesem Tutorial haben Sie gelernt, wie neuronale Netze Berechnungen durchführen, um nützliche Vorhersagen zu treffen.

Wenn Sie mehr über das Erstellen, Trainieren und Bereitstellen eines hochmodernen Modells für maschinelles Lernen erfahren möchten, lernen Sie in meinem eBook Pragmatic Machine Learning, wie Sie 9 verschiedene Modelle für maschinelles Lernen mithilfe realer Projekte erstellen.

Sie können den Code aus dem eBook auf Ihrem GitHub oder Ihrem persönlichen Portfolio bereitstellen, um ihn potenziellen Arbeitgebern anzuzeigen. Das Buch erscheint am 3. August - jetzt 50% Rabatt vorbestellen!