image

image

Zu diesem Buch – sowie zu vielen weiteren O’Reilly-Büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei oreilly.plus+:

www.oreilly.plus

Einführung in TensorFlow

Deep-Learning-Systeme programmieren,
trainieren, skalieren und deployen

Tom Hope, Yehezkel S. Resheff & Itay Lieder

Deutsche Übersetzung von
Kristian Rother & Thomas Lotze

image

Tom Hope, Yehezkel S. Resheff und Itay Lieder

Lektorat: Alexandra Follenius

Übersetzung: Kristian Rother und Thomas Lotze

Korrektorat: Claudia Lötschert, www.richtiger-text.de

Herstellung: Susanne Bröckelmann

Umschlaggestaltung: Karen Montgomery, Michael Oréal, www.oreal.de

Satz: III-satz, www.drei-satz.de

Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, 33100 Paderborn

Bibliografische Information Der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:

Print

978-3-96009-074-8

PDF

978-3-96010-180-2

ePub

978-3-96010-181-9

mobi

978-3-96010-182-6

Dieses Buch erscheint in Kooperation mit O’Reilly Media, Inc. unter dem Imprint »O’REILLY«. O’REILLY ist ein Markenzeichen und eine eingetragene Marke von O’Reilly Media, Inc. und wird mit Einwilligung des Eigentümers verwendet.

1. Auflage

Copyright © 2018 dpunkt.verlag GmbH

Wieblinger Weg 17

69123 Heidelberg

Authorized German translation of the English edition of Learning TensorFlow: A Guide to Building Deep Learning Systems, ISBN 978-1-491-97851-1 © 2017 Tom Hope, Itay Lieder, and Yehezkel S. Resheff. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same.

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.

Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und deren Folgen.

5 4 3 2 1 0

Inhalt

Vorwort

1Einleitung

Einstieg in Deep Learning

TensorFlow für KI-Systeme verwenden

TensorFlow: Was verbirgt sich hinter dem Namen?

Allgemeiner Überblick

Zusammenfassung

2Erste Schritte mit TensorFlow

TensorFlow installieren

Hallo Welt

MNIST

Softmax-Regression

Zusammenfassung

3Die Grundlagen von TensorFlow

Berechnungsgraphen

Was ist ein Berechnungsgraph?

Die Vorteile von Graphenberechnungen

Graphen, Sessions und Ergebnisabfragen

Einen Graphen erstellen

Eine Session erstellen und ausführen

Unseren Graphen aufbauen und verwalten

Ergebnisabfragen

Fließende Tensoren

Knoten als Operationen, Kanten als Tensor-Objekte

Datentypen

Tensor-Objekte und ihre Gestalt

Namen

Variablen, Platzhalter und einfache Optimierung

Variablen

Platzhalter

Optimierung

Zusammenfassung

4Konvolutionsnetze

Einführung in Konvolutionsnetze

MNIST: Zweite Runde

Konvolution

Pooling

Dropout

Das Modell

CIFAR10

Laden des CIFAR10-Datensatzes

Einfache CIFAR10-Modelle

Zusammenfassung

5Text I: Arbeiten mit Text und Sequenzen, Visualisierung mit TensorBoard

Warum Sequenzdaten so wichtig sind

Einführung in rekurrente neuronale Netze

Einfache Implementierung eines RNN

In TensorFlow eingebaute Funktionen für RNNs

RNNs für Textsequenzen

Textsequenzen

Überwachte Worteinbettungen

LSTM und die Verwendung von Sequenzlängen

Anlernen von Einbettungen und des LSTM-Klassifikators

Zusammenfassung

6Text II: Wortvektoren, fortgeschrittene RNNs und Visualisierung von Einbettungen

Einführung in die Worteinbettung

Word2vec

Skip-Gramme

Einbettungen in TensorFlow

Die Verlustfunktion für Noise-Contrastive Estimation (NCE)

Abfall der Lernrate

Anlernen und Visualieren mit TensorBoard

Einblick in unsere Einbettungen

Angelernte Einbettungen und fortgeschrittene RNNs

Angelernte Worteinbettungen

Bidirektionale RNNs und GRU-Zellen

Zusammenfassung

7Abstraktionen und Vereinfachungen in TensorFlow

Überblick über das Kapitel

Verfügbare Bibliotheken

contrib.learn

Lineare Regression

DNN-Klassifikator

FeatureColumn

Mit contrib.learn ein CNN selbst erstellen

TFLearn

Installation

CNN

RNN

Keras

Angelernte Modelle mit TF-Slim

Zusammenfassung

8Warteschlangen, Threads und das Einlesen von Daten

Die Eingabepipeline

TFRecords

Das Schreiben mit TFRecordWriter

Warteschlangen

Einstellen und Entnehmen

Multithreading

Koordinator und Warteschlangensteuerung

Eine vollständige parallele Eingabepipeline

tf.train.string_input_producer() und tf.TFRecordReader()

tf.train.shuffle_batch()

tf.train.start_queue_runners() und der Abschluss

Zusammenfassung

9TensorFlow und verteiltes Rechnen

Verteiltes Rechnen

Wo findet Parallelisierung statt?

Was ist das Ziel von Parallelisierung?

TensorFlow-Elemente

tf.app.flags

Cluster und Server

Replikation von Berechnungsgraphen über mehrere Prozessoren

Überwachte Sessions

Die Prozessorzuteilung

Beispiel mit verteiltem Rechnen

Zusammenfassung

10Modelle mit TensorFlow exportieren und via Server bereitstellen

Unser Modell speichern und exportieren

Geladene Gewichte zuweisen

Die Klasse Saver

Einführung in TensorFlow Serving

Überblick

Installation

Bauen und exportieren

Zusammenfassung

Anhang: Tipps zur Erstellung von Modellen und Verwendung von TensorFlow Serving

Index

Vorwort

Deep Learning hat sich in den letzten Jahren als vorherrschende Technik für Systeme etabliert, die aus Daten lernen. Deep-Learning-Netze, die ursprünglich der Lernweise des menschlichen Gehirns nachempfunden waren, werden mit großen Datenmengen angelernt, um komplexe Aufgaben mit unerhörter Genauigkeit zu lösen. Seit Open-Source-Frameworks diese Technik allgemein verfügbar machen, kommt man nicht mehr an ihr vorbei, wenn man sich mit Big Data und maschinellem Lernen beschäftigt.

Gegenwärtig ist TensorFlow die führende Open-Source-Software für Deep Learning. Sie wird von einer schnell wachsenden Zahl von Anwendern für Computersehen, die Verarbeitung natürlicher Sprache (NLP, »natural language processing«), Spracherkennung und für vorhersagende Datenanalyse im Allgemeinen eingesetzt.

Dieses Buch ist als umfassende Einführung in TensorFlow für Datenanalytiker, Ingenieure, Studenten und Wissenschaftler angelegt. Es wählt einen praktischen Ansatz, der sich an ein breites, technisch orientiertes Publikum richtet. So finden Anfänger einen leichten Einstieg, fortgeschrittene Themen werden eingehend behandelt, und es wird aufgezeigt, wie man produktiv einsetzbare Systeme erstellt.

In diesem Buch lernen Sie:

Dieses Buch ist von Datenanalytikern mit umfassender Erfahrung in Forschung und Entwicklung sowie in Industrie und akademischer Forschung geschrieben worden. Die Autoren verfolgen einen praktischen Ansatz mit anwendbaren und intuitiven Beispielen, Illustrationen und Erläuterungen, die sich sowohl an Anwender richten, die Systeme für den Produktivbetrieb bauen, als auch an Leser, die lernen möchten, flexible und mächtige Modelle zu verstehen und zu erstellen.

Voraussetzungen

Dieses Buch setzt einfache Programmierkenntnisse in Python voraus, darunter Grundkenntnisse der wissenschaftlichen Bibliothek NumPy.

Im Verlauf des Buchs werden einige Begriffe zum maschinellen Lernen behandelt und intuitiv zugänglich erklärt. Für ein tieferes Verständnis werden ausreichende Kenntnisse von maschinellem Lernen, linearer Algebra, Analysis, Wahrscheinlichkeitsrechnung und Statistik empfohlen.

In diesem Buch verwendete Konventionen

Die folgenden typografischen Konventionen werden in diesem Buch verwendet:

Kursiv

Kennzeichnet neue Begriffe, URLs, E-Mail-Adressen, Dateinamen und Dateiendungen.

Festbreitenschrift

Wird für Programmtexte und für Programmelemente in Textabschnitten wie Namen von Variablen und Funktionen, Datenbanken, Datentypen, Umgebungsvariablen, Anweisungen und Schlüsselwörter verwendet.

Fette Festbreitenschrift

Kennzeichnet Befehle oder anderen Text, den der Nutzer wörtlich eingeben soll.

Kursive Festbreitenschrift

Kennzeichnet Text, den der Nutzer durch eigene oder zum Kontext passende Werte ersetzen soll.

Verwendung von Codebeispielen

Zusatzmaterial wie Codebeispiele oder Übungen können Sie von https://github.com/Hezi-Resheff/Oreilly-Learning-TensorFlow herunterladen.

Dieses Buch soll Ihnen helfen, Ihre Arbeit zu erledigen. Im Allgemeinen dürfen Sie die Codebeispiele aus diesem Buch in Ihren eigenen Programmen und der dazugehörigen Dokumentation verwenden. Sie müssen uns dazu nicht um Erlaubnis fragen, solange Sie nicht einen beträchtlichen Teil des Codes reproduzieren. Beispielsweise benötigen Sie keine Erlaubnis, um ein Programm zu schreiben, in dem mehrere Codefragmente aus diesem Buch vorkommen. Wollen Sie dagegen eine CD-ROM mit Beispielen aus Büchern von O’Reilly verkaufen oder verteilen, benötigen Sie eine Erlaubnis. Eine Frage zu beantworten, indem Sie aus diesem Buch zitieren und ein Codebeispiel wiedergeben, benötigt keine Erlaubnis. Eine beträchtliche Menge Beispielcode aus diesem Buch in die Dokumentation Ihres Produkts aufzunehmen, bedarf hingegen einer Erlaubnis.

Wir freuen uns darüber, zitiert zu werden, verlangen es aber nicht. Ein Zitat enthält Titel, Autor, Verlag und ISBN. Ein Beispiel: »Einführung in TensorFlow von Tom Hope, Yehezkel S. Resheff und Itay Lieder, O’Reilly 2018, ISBN 978-3-96009-074-8.«

Wenn Sie glauben, dass Ihre Verwendung von Codebeispielen über eine angemessene Nutzung oder die oben gewährte Nutzungserlaubnis hinausgeht, dann kontaktieren Sie uns bitte unter kommentar@oreilly.de.

Dank

Als Autoren möchten wir unseren Gutachtern für ihr Feedback zum Buch danken: Chris Fregly, Marvin Bertin, Oren Sar Shalom und Yoni Lavi. Wir möchten außerdem Nicole Tache und dem Team von O’Reilly dafür danken, dass es ein Vergnügen war, dieses Buch zu schreiben.

Und natürlich danken wir all den Leuten bei Google, ohne die TensorFlow nicht existieren würde.

KAPITEL 1

Einleitung

Dieses Kapitel gibt Ihnen einen Überblick über TensorFlow und sein Haupteinsatzgebiet: die Implementierung und den Betrieb von Deep-Learning-Systemen. Wir beginnen mit einer sehr kurzen Einführung in Deep Learning. Anschließend präsentieren wir Ihnen TensorFlow und einige seiner eindrucksvollen Anwendungsbeispiele für maschinelle Intelligenz und sehen uns die wichtigsten Merkmale und Eigenschaften an.

Einstieg in Deep Learning

Von Großkonzernen bis zu Start-ups in Gründung sammeln Softwareingenieure und Datenanalytiker riesige Datenmengen und verwenden maschinelle Lernalgorithmen, um komplexe Fragestellungen zu beantworten und intelligente Systeme zu bauen. Wo auch immer man sich umschaut, konnten auf Deep Learning beruhende Algorithmen in letzter Zeit großartige Erfolge verzeichnen und haben traditionelle Methoden oft weit hinter sich gelassen. Deep Learning wird heute verwendet, um den Inhalt von Bildern, Text und Sprache zu verstehen. Die Systeme dazu erstrecken sich von Apps für mobile Geräte bis zu autonomen Fahrzeugen. Die Entwicklung schreitet in diesem Gebiet in atemberaubendem Tempo voran, und Deep Learning breitet sich auf weitere Gebiete und Arten von Daten aus, wie etwa komplexe chemische und genetische Strukturen bei der Suche nach Medikamenten und hochdimensionale medizinische Aufzeichnungen im Gesundheitswesen.

Deep-Learning-Methoden – die auch als Deep-Learning-Netze bezeichnet werden – waren ursprünglich an das riesige Netz der im menschlichen Gehirn miteinander verbundenen Neuronen angelehnt. Beim Deep Learning speisen wir Millionen Datenpunkte in ein neuronales Netz ein und bringen ihnen bei, Muster in den Rohdaten zu erkennen. Deep-Learning-Netze verarbeiten diese Rohdaten (etwa die Pixelwerte eines Bilds) und stellen sie in besser nutzbarer Form dar, wobei sie in ihnen Merkmale höherer Ordnung erkennen (beispielsweise Formen und Kanten in Bildern). Dabei werden komplexe Eigenschaften erfasst, indem immer kleinere Informationsbausteine miteinander kombiniert werden, um schwierige Aufgaben wie die Klassifikation von Bildern zu lösen (Abbildung 1-1). Diese Netze lernen automatisch, abstrakte Darstellungen zu erzeugen, indem sie sich selbst an die in den Daten beobachteten Muster anpassen und die eigenen Fehler korrigieren. Die Fähigkeit, Darstellungen von Daten automatisch zu konstruieren, ist der Hauptvorteil von Deep-Learning-Netzen gegenüber konventionellen maschinellen Lernmethoden, die üblicherweise Sachkenntnis und manuelles Erarbeiten von Merkmalen erfordern, bevor das »Lernen« erfolgen kann.

image

Abbildung 1-1: Illustration einer Bildklassifikation mit einem Deep-Learning-Netz. Das Netz verarbeitet Rohdaten (die Pixelwerte eines Bilds) und lernt, sie in eine zur genauen Bildklassifikation nützliche Darstellung zu überführen.

Dieses Buch beschäftigt sich mit TensorFlow, dem Deep-Learning-Framework von Google. Deep-Learning-Algorithmen werden seit mehreren Jahren in vielerlei Produkten und Arbeitsbereichen bei Google eingesetzt, beispielsweise Suche, Übersetzung, Werbung, Computersehen und Spracherkennung. TensorFlow ist Googles System zweiter Generation zum Implementieren und Betreiben von Deep-Learning-Netzen und löst das 2011 gestartete Projekt DistBelief ab.

TensorFlow wurde der Öffentlichkeit im November 2015 als Open-Source-Framework unter der Apache-Lizenz 2.0 zur Verfügung gestellt und hat die gesamte Branche im Sturm erobert. Die Anwendungen gehen weit über interne Google-Projekte hinaus. Seine Skalierbarkeit und Flexibilität sowie die beeindruckende Leistung der Programmierer bei Google, die TensorFlow ständig warten und weiterentwickeln, haben es zum führenden System für Deep Learning gemacht.

TensorFlow für KI-Systeme verwenden

Bevor wir uns genauer damit beschäftigen, was TensorFlow ist und welches seine wichtigsten Merkmale sind, möchten wir Ihnen einige aufregende Beispiele für aktuelle Anwendungen von TensorFlow aufzeigen, die bei Google und anderswo in der Praxis eingesetzt werden.

Angelernte Modelle: Herausragendes Computersehen für alle

Ein Gebiet, auf dem Deep Learning wirklich brilliert, ist das Computersehen. Eine grundlegende Aufgabe beim Computersehen ist die Klassifikation von Bildern – die Erstellung von Algorithmen und Systemen, die Bilder als Eingabe erhalten und eine oder mehrere Kategorien ausgeben, die diese am besten beschreiben. Forscher, Datenanalytiker und Softwareingenieure haben fortgeschrittene Deep-Learning-Netze entwickelt, die beim Verstehen visueller Inhalte hochgenaue Ergebnisse erzielen. Diese Deep-Learning-Netze werden üblicherweise mit großen Mengen an Bilddaten angelernt, was viel Zeit, Ressourcen und Mühe in Anspruch nimmt. Allerdings veröffentlichen Forscher immer häufiger angelernte Modelle – Deep-Learning-Netze, die Nutzer herunterladen und sofort auf ihre eigenen Daten anwenden können (Abbildung 1-2).

image

Abbildung 1-2: Fortgeschrittenes Computersehen mit angelernten TensorFlow-Modellen

TensorFlow enthält nützliche Hilfsmittel, mit denen Nutzer aktuelle angelernte Modelle beschaffen und verwenden können. Wir werden im Verlauf dieses Buchs mehrere praktische Beispiele hierfür sehen und uns mit den Details beschäftigen.

Ausführliche Beschreibungstexte zu Bildern erzeugen

Ein aufregendes Gebiet der Deep-Learning-Forschung zum Erstellen maschineller Lernsysteme konzentriert sich auf die Erzeugung von Beschreibungstexten zu visuellen Inhalten (Abbildung 1-3). Eine wichtige Aufgabe dabei ist die Bildbeschriftung – dem Modell beizubringen, kurze und präzise Bildunterschriften zu erzeugen. Auch hier sind fortgeschrittene angelernte TensorFlow-Modelle verfügbar, die das Verständnis von Text mit Computersehen kombinieren.

image

Abbildung 1-3: Vom Bild zur Bildunterschrift (Anwendungsbeispiel)

Text zusammenfassen

Das Verstehen natürlicher Sprache (Natural Language Understanding, NLU) ist eine wichtige Fertigkeit für KI-Systeme. Jeden Tag werden gewaltige Mengen von Text erstellt: Webinhalte, soziale Medien, Nachrichten, E-Mails, interne Firmenkorrespondenz und vieles mehr.

image

Abbildung 1-4: Ein Beispiel für automatische Zusammenfassung von Text

Eine der begehrtesten Fähigkeiten ist das Zusammenfassen von Text, aus langen Dokumenten kurze und zusammenhängende Sätze zu erzeugen, die die wichtigsten Informationen aus den ursprünglichen Texten wiedergeben (Abbildung 1-4). Wie wir später in diesem Buch sehen werden, enthält TensorFlow mächtige Werkzeuge zum Anlernen von Deep-Learning-Netzen für NLU-Aufgaben, die sich zur automatischen Zusammenfassung von Texten einsetzen lassen.

TensorFlow: Was verbirgt sich hinter dem Namen?

Bei Deep-Learning-Netzen geht es, wie der Name und die Anwendungsbeispiele vermuten lassen, um Netze aus Neuronen. Dabei lernt jedes Neuron, mit seiner Funktion zu einem großen Ganzen beizutragen. Daten wie Bilder werden in ein solches Netz eingegeben und fließen durch das Netz, während dieses sich im Anlernprozess anpasst oder im laufenden Betrieb Vorhersagen trifft.

Tensoren sind die im Deep Learning übliche Erscheinungsform von Daten. Einfach ausgedrückt sind Tensoren nichts weiter als mehrdimensionale Felder, eine Erweiterung zweidimensionaler Tabellen (Matrizen) auf Daten mit mehr Dimensionen. Wie Schwarz-Weiß-Bilder (oder Graustufen) sich als »Tabellen« der Pixelwerte abbilden lassen, so lassen sich Farbbilder im RGB-Format als Tensoren (dreidimensionale Felder) abbilden, wobei jedes Pixel drei Werte für die Farbkomponenten Rot, Grün und Blau besitzt.

In TensorFlow wird die Berechnung als Datenflussgraph abgebildet (Abbildung 1-5). Allgemein ausgedrückt, stehen die Knoten dieses Graphen für Operationen (wie Addition oder Multiplikation), und die Kanten stehen für Daten (Tensoren), die durch das System fließen. In den folgenden Kapiteln werden wir diese Begriffe genauer ausführen und anhand zahlreicher Beispiele ein Verständnis für sie entwickeln.

image

Abbildung 1-5: Ein Datenfluss-Berechnungsgraph. Die Daten fließen als Tensoren durch einen Graphen von Rechenoperationen, aus denen unser Deep-Learning-Netz besteht.

Allgemeiner Überblick

TensorFlow ist, allgemein ausgedrückt, ein Software-Framework für numerische Berechnungen, die auf Datenflussgraphen beruhen. Es ist aber vor allem als Schnittstelle zum Beschreiben und Implementieren maschineller Lernalgorithmen gedacht, vor allem von Deep-Learning-Netzen.

TensorFlow wurde im Hinblick auf Portierbarkeit entworfen, sodass die Berechnungsgraphen in ganz unterschiedlichen Umgebungen und auf vielerlei Hardwareplattformen ausführbar sind. Mit im Wesentlichen identischem Code lässt sich ein und dasselbe TensorFlow-Netz beispielsweise in der Cloud, über einen Cluster verteilt oder auf einem einzelnen Laptop anlernen. Es kann auf einem dedizierten Server Vorhersagen liefern und lässt sich auf mobilen Plattformen wie Android oder iOS oder einem Kleincomputer wie dem Raspberry Pi betreiben. TensorFlow ist natürlich auch mit den Betriebssystemen Linux, MacOS und Windows kompatibel.

Die Kernkomponente von TensorFlow ist in C++ geschrieben und besitzt zwei primäre Schnittstellen zu Hochsprachen, in denen sich Berechnungsgraphen beschreiben und ausführen lassen. Die am weitesten entwickelte Schnittstelle ist in Python geschrieben und wird von den meisten Forschern und Datenanalytikern genutzt. Die C++-Schnittstelle bietet eine API auf niedrigerer Ebene, die für effizientes Ausführen im Embedded-Bereich oder anderen Szenarien nützlich ist.

Neben der Portierbarkeit ist ein weiterer Hauptvorteil von TensorFlow seine Flexibilität, wodurch Forscher und Datenanalytiker Modelle relativ leicht formulieren können. Es ist bisweilen erhellend, sich die moderne Deep-Learning-Forschung wie das Spielen mit »LEGO-ähnlichen« Bausteinen vorzustellen, wobei man einzelne Steine im Netz durch andere ersetzt, schaut, was passiert, und bisweilen neue Bausteine entwirft. Wie wir das gesamte Buch hindurch sehen werden, bietet TensorFlow hilfreiche Werkzeuge für den Umgang mit diesen modularen Bausteinen sowie eine flexible Programmierschnittstelle, mit der sich neue Elemente schreiben lassen. Deep-Learning-Netze werden durch einen Feedback-Prozess namens Backpropagation angelernt, der zur Optimierung das Gradientenverfahren anwendet. TensorFlow unterstützt viele Optimierungsverfahren, die alle automatisch differenzieren können, sodass der Nutzer nicht schon im Voraus Gradienten angeben muss, sondern TensorFlow die partiellen Ableitungen anhand des Berechnungsgraphen und der vom Nutzer angegebenen Verlustfunktion ermittelt. Um den Anlernprozess zu beobachten, Fehler zu finden, Abläufe zu veranschaulichen und Experimente zu vereinheitlichen, bietet TensorFlow mit TensorBoard ein einfaches Visualisierungswerkzeug (Abbildung 1-6), das mit dem Webbrowser arbeitet und das wir im Buch immer wieder verwenden werden.

Abstraktionsbibliotheken sind der Schlüssel zu einer effizienten Nutzung der Flexibilität von TensorFlow. Bei den modernsten Deep-Learning-Netzen für Computersehen oder NLU ist das Schreiben von Code für TensorFlow mit einem gewissen Aufwand verbunden – dies kann zu einem komplexen, langen und schwerfälligen Unterfangen werden. Abstraktionsbibliotheken wie Keras und TF-Slim bieten einen vereinfachten Zugriff auf die der Bibliothek zugrunde liegenden »LEGO-Steine«, um einfacher Berechnungsgraphen zu erstellen und anzulernen sowie Vorhersagen zu treffen. Ein weiterer Erfolgsfaktor für Datenanalytiker und Softwareingenieure sind die mit TF-Slim und TensorFlow ausgelieferten angelernten Modelle. Diese Modelle wurden an riesigen Datenmengen unter Nutzung großer Rechenkapazitäten angelernt, an die man sonst nur schwer herankäme und die in jedem Fall nur mit erheblichem Aufwand zum Einsatz zu bringen wären. Mit Keras oder TF-Slim ist es beispielsweise möglich, diese fortgeschrittenen Modelle mit nur wenigen Codezeilen zur Vorhersage anhand eigener Daten zu nutzen oder sie auf neue Daten abzustimmen.

image

Abbildung 1-6: TensorBoard, das Visualisierungswerkzeug in TensorFlow, mit dem der Anlernprozess und Experimente überwacht, auf Fehler untersucht und analysiert werden.

Die Flexibilität und Portierbarkeit von TensorFlow ermöglichen einen glatten Übergang von der Entwicklung zum laufenden Betrieb, sodass Datenanalytiker ihre Modelle schneller in Produkte einbauen und Softwareingenieure algorithmische Ideen in robusten Code umwandeln können.

image

Abstraktionsbibliotheken für TensorFlow

Für TensorFlow sind Abstraktionsbibliotheken wie Keras und TF-Slim verfügbar, die einen vereinfachten Zugriff auf TensorFlow auf höherer Ebene ermöglichen. Diese Abstraktionsbibliotheken werden wir uns später im Buch genauer ansehen. Sie helfen dabei, Datenflussgraphen einfacher zu erstellen, und erlauben uns, diesen mit viel weniger Codezeilen anzulernen und für Vorhersagen zu nutzen.

Außer Flexibilität und Portierbarkeit besitzt TensorFlow jedoch noch weitere Eigenschaften, die es für die Arbeit an Praxisanwendungen von KI-Systemen attraktiv machen. Es unterstützt von Haus aus verteiltes Anlernen – tatsächlich lernen Google und andere Unternehmen damit auf Rechnerclustern riesige Netze mit gigantischen Datenmengen an. Code, der für einen einzelnen Prozessor geschrieben wurde, kann mit wenigen Änderungen auch auf mehreren lokalen Prozessoren genutzt werden. Auch bei der Umstellung vom lokalen auf den verteilten Betrieb ändert sich der Code nur relativ geringfügig, wodurch TensorFlow für den Einsatz in der Cloud, etwa auf Amazon Web Services (AWS) oder der Google-Cloud, besonders interessant wird. Außerdem werden wir im Verlauf des Buchs zahlreiche Funktionen von TensorFlow kennenlernen, die die Skalierbarkeit weiter verbessern. Dazu gehören die Unterstützung von asynchronen Berechnungen durch Threading und Warteschlangen, effiziente Ein- und Ausgabe und Datenformate und vieles mehr.

Deep Learning entwickelt sich in hohem Tempo weiter, und auch TensorFlow erfährt häufig neue, spannende Verbesserungen hinsichtlich Benutzerfreundlichkeit, Leistungsfähigkeit und Nützlichkeit.

Zusammenfassung

Aufgrund der in diesem Kapitel beschriebenen Werkzeuge und Merkmale wird klar, warum TensorFlow innerhalb eines Jahrs so viel Aufmerksamkeit erhalten hat. Dieses Buch möchte Sie zunächst schnell mit den Grundlagen vertraut machen, sodass Sie arbeitsbereit sind. Anschließend werden wir anhand zahlreicher spannender praktischer Beispiele tiefer in die Welt von TensorFlow eintauchen.

KAPITEL 2

Erste Schritte mit TensorFlow

In diesem Kapitel beginnen wir unsere Reise mit zwei funktionierenden Beispielen für TensorFlow. Das eine (ein traditionelles »Hallo Welt«-Programm) ist zwar kurz und einfach, enthält aber bereits viele wichtige Elemente, die wir in späteren Kapiteln eingehend behandeln. Mit dem anderen, einem ersten vollständigen Machine-Learning-Modell, beginnen Sie Ihre Reise zu modernem maschinellem Lernen mit TensorFlow.

Bevor wir anfangen, gehen wir kurz auf die Installation von TensorFlow ein1. Für einen schnellen und schmerzfreien Einstieg installieren wir nur die CPU-Version und heben uns die GPU-Version für später auf.2 (Wenn Sie nicht wissen, was es damit auf sich hat, macht das erst einmal nichts.) Falls Sie TensorFlow bereits installiert haben, springen Sie zum zweiten Abschnitt.

TensorFlow installieren

Falls Sie eine saubere Python-Installation verwenden (die Sie womöglich extra zum Erlernen von TensorFlow aufgesetzt haben), können Sie mit der einfachen pip-Installation beginnen:

$ pip install tensorflow

Dieser Ansatz hat jedoch den Nachteil, dass TensorFlow bereits existierende Pakete ggf. durch andere Versionen ersetzt, um seine Abhängigkeiten zu erfüllen. Benutzen Sie dieselbe Python-Installation noch für weitere Zwecke, ist das ein Problem. Eine übliche Lösung besteht darin, TensorFlow in einer virtuellen Umgebung zu installieren, die mit einem Werkzeug namens virtualenv verwaltet wird.

Es kann sein, dass Sie virtualenv auf Ihrem Rechner installieren müssen. Geben Sie dazu Folgendes ein:

$ pip install virtualenv

Weitere Anweisungen finden Sie unter http://virtualenv.pypa.io.

Um TensorFlow in einer virtuellen Umgebung zu installieren, müssen Sie zunächst die virtuelle Umgebung erstellen – in diesem Buch haben wir uns entschieden, virtuelle Umgebungen in den Ordner ~/envs zu legen, aber Sie können dafür auch einen anderen Ort wählen:

$ cd ~

$ mkdir envs

$ virtualenv ~/envs/tensorflow

Damit erzeugen Sie eine virtuelle Umgebung namens tensorflow in ~/envs (die als Ordner ~/envs/tensorflow auftauchen wird). Sie können die Umgebung folgendermaßen aktivieren:

$ source ~/envs/tensorflow/bin/activate

Der Prompt sollte sich nun ändern und die aktivierte Umgebung anzeigen:

(tensorflow)$

Nun installiert der Befehl

(tensorflow)$ pip install tensorflow

TensorFlow in die virtuelle Umgebung, ohne andere auf Ihrem Rechner installierte Pakete zu beeinflussen.

Um schließlich die virtuelle Umgebung zu verlassen, geben Sie

(tensorflow)$ deactivate

ein, woraufhin Sie wieder zum normalen Prompt zurückkehren sollten:

$

TensorFlow für Windows-Nutzer

Bis vor Kurzem war TensorFlow dafür berüchtigt, auf Windows-Maschinen nur schwer benutzbar zu sein. Ab TensorFlow 0.12 gibt es jedoch eine ganz einfache Windows-Integration:

pip install tensorflow

für die CPU-Version oder:

pip install tensorflow-gpu

für die GPU-fähige Version (vorausgesetzt, Sie haben bereits CUDA 8).

image

Einen Alias zu ~/.bashrc hinzufügen

Der beschriebene Weg, Ihre virtuelle Umgebung zu aktivieren und zu verlassen, kann sich bei häufiger Benutzung umständlich anfühlen. In diesem Fall können Sie einfach folgenden Befehl an Ihre Datei ~/.bashrc anhängen:

alias tensorflow="source ~/envs/tensorflow/bin/activate"

Verwenden Sie daraufhin den Befehl tensorflow, um die virtuelle Umgebung zu aktivieren. Verlassen können Sie diese nach wie vor mit deactivate.

Nun, da wir eine Grundinstallation von TensorFlow haben, können wir unsere ersten Anwendungsbeispiele in Angriff nehmen. Wir werden der guten alten Tradition folgen, mit einem »Hallo Welt«-Programm zu beginnen.

Hallo Welt

Unser erstes Beispiel ist ein einfaches Programm, das die Wörter »Hallo« und »Welt!« zusammenfügt und die Ausgabe anzeigt – den Ausruf »Hallo Welt!«. Dieses Beispiel ist zwar schlicht und überschaubar, zeigt aber viele der Kernelemente von TensorFlow und der Unterschiede zu einem gewöhnlichen Python-Programm.

Wir empfehlen, dass Sie dieses Beispiel auf Ihrem Rechner ausführen und ein wenig damit herumspielen, um zu sehen, was alles möglich ist. Als Nächstes werden wir die Codezeilen durchgehen und jedes Element einzeln besprechen.

Als Erstes führen wir einen einfachen Test der Installation und Version durch. (Falls Sie die virtualenv-Installation gewählt haben, aktivieren Sie die Umgebung, bevor Sie den TensorFlow-Code ausführen.)

import tensorflow as tf

print(tf.__version__)

Wenn alles klappt, wird die Version von TensorFlow angezeigt, die Sie auf Ihrem System installiert haben. Treten bei der weiteren Arbeit Probleme auf, dann liegt das am wahrscheinlichsten an unpassenden Versionen.

Beispiel 2-1 zeigt das vollständige »Hallo Welt«-Beispiel.

Beispiel 2-1: »Hallo Welt« mit TensorFlow

import tensorflow as tf

h = tf.constant("Hallo")

w = tf.constant(" Welt!")

hw = h + w

with tf.Session() as sess:

ans = sess.run(hw)

print(ans)

Wir gehen davon aus, dass Sie mit Python und import-Anweisungen vertraut sind, sodass die erste Zeile:

import tensorflow as tf

keiner Erklärung bedarf.

image

Konfiguration einer IDE

Falls Sie TensorFlow-Code in einer integrierten Entwicklungsumgebung (IDE) laufen lassen, stellen Sie sicher, dass die virtuelle Umgebung verwendet wird, in der das Paket installiert ist. Anderenfalls erhalten Sie folgenden Importfehler:

ImportError: No module named tensorflow

In der IDE PyCharm wählen Sie dazu »Run→Edit Configurations« und stellen den Python-Interpreter auf ~/envs/tensorflow/bin/python um, vorausgesetzt, Sie haben ~/envs/tensorflow als Verzeichnis für die virtuellen Umgebungen verwendet.

Dann definieren wir die Konstanten "Hallo" and " Welt!" und fügen sie zusammen:

import tensorflow as tf

h = tf.constant("Hallo")

w = tf.constant(" Welt!")

hw = h + w

Nun fragen Sie sich vielleicht, inwiefern (und ob überhaupt) sich das von dem einfachen Python-Code für diese Aufgabe unterscheidet:

ph = "Hallo"

pw = " Welt!"

phw = h + w

Der Knackpunkt hierbei ist der Wert der Variablen hw in den beiden Fällen. Wir können ihn uns mit der Funktion print ansehen. Im Fall von reinem Python erhalten wir:

>print(phw)

Hallo Welt!

Im Fall von TensorFlow ist die Ausgabe jedoch etwas völlig anderes:

>print(hw)

Tensor("add:0", shape=(), dtype=string)

Das haben Sie wahrscheinlich nicht erwartet!

Im nächsten Kapitel erklären wir das Konzept der Berechnungsgraphen in TensorFlow im Einzelnen, wobei diese Ausgabe vollkommen verständlich werden wird. Die Grundidee der Berechnungsgraphen in TensorFlow ist, dass wir zuerst festlegen, welche Berechnungen stattfinden sollen, und dann die Rechnung von außen anstoßen. Damit berechnet die TensorFlow-Codezeile

hw = h + w

nicht die Summe von h und w, sondern fügt den Additionsschritt dem Graphen mit den später auszuführenden Berechnungen hinzu.

Im nächsten Schritt tritt das Session-Objekt als Schnittstelle zum äußeren Rechenmechanismus von TensorFlow auf und lässt uns Teile des Berechnungsgraphen ausführen, den wir zuvor aufgebaut haben. Die Zeile

ans = sess.run(hw)

enthält die eigentliche Berechnung von hw (als Summe von h und w, wie es zuvor festgelegt wurde), wonach die Ausgabe von ans die erwartete Botschaft »Hallo Welt!« anzeigt.

Damit ist das erste TensorFlow-Beispiel vollständig. Als Nächstes tauchen wir unmittelbar ein in ein einfaches Beispiel für maschinelles Lernen, das bereits einen großzügigen Einblick in die Verheißungen des TensorFlow-Frameworks gewährt.

MNIST

Der Datensatz handschriftlicher Ziffern des MNIST (Mixed National Institute of Standards and Technology) ist einer der meistuntersuchten Datensätze in Bildverarbeitung und maschinellem Lernen und hat eine wichtige Rolle bei der Entwicklung künstlicher neuronaler Netze gespielt (die heutzutage üblicherweise als Deep Learning bezeichnet werden).

Somit ist es nur passend, dass unser erstes Beispiel für maschinelles Lernen der Klassifikation handschriftlicher Ziffern gewidmet ist. (Abbildung 2-1 zeigt eine zufällige Stichprobe aus dem Datensatz.) Der Einfachheit halber werden wir an dieser Stelle einen sehr simplen Klassifikator anwenden.

image

Abbildung 2-1: 100 zufällig ausgewählte MNIST-Bilder

Dieses einfache Modell genügt, um etwa 92 % des Testdatensatzes richtig zu klassifizieren – die besten derzeit verfügbaren Modelle erreichen eine Trefferquote von mehr als 99,75 %, aber bis dahin haben wir noch ein paar Kapitel vor uns! Weiter hinten im Buch werden wir auf diese Daten zurückkommen und ausgeklügeltere Methoden nutzen.

Softmax-Regression

In diesem Beispiel verwenden wir einen einfachen Klassifikator namens Softmax-Regression. Wir werden nicht allzu detailliert auf die mathematische Formulierung des Modells eingehen. (Es gibt eine Vielzahl guter Quellen für diese Hintergrundinformation, und wir empfehlen Ihnen dringend, sich damit zu beschäftigen, falls Sie diese Dinge noch nie gesehen haben.) Stattdessen werden wir versuchen, Ihnen auf intuitivem Weg aufzuzeigen, wie das Modell die Aufgabe der Ziffernerkennung lösen kann.

Einfach ausgedrückt, untersucht das Softmax-Regressionsmodell für jeden Pixel im Bild, welche Ziffern an der jeweiligen Stelle eher hohe (oder niedrige) Werte haben. Beispielsweise wird die Bildmitte bei Nullen tendenziell weiß sein, bei Sechsen aber schwarz. Damit deutet ein schwarzes Pixel in der Bildmitte darauf hin, dass das Bild keine Null, aber womöglich eine Sechs enthält.

In diesem Modell bedeutet Anlernen, Gewichte zu finden, mit denen die Indizien für das Vorliegen jeder der Ziffern zusammengefasst werden können. Für die Softmax-Regression verzichten wir auf die räumliche Information der Pixelanordnung im Bild. Später werden wir bei der Besprechung von Konvolutionsnetzen sehen, dass in der Nutzung räumlicher Informationen einer der Schlüssel zu starken Modellen für Bildverarbeitung und Objekterkennung liegt.

Da wir an dieser Stelle die räumlichen Informationen nicht nutzen werden, reihen wir unsere Bildpixel zu einem einzelnen langen Vektor auf, den wir x nennen (Abbildung 2-2). Dann ist

image

die Indizienstärke dafür, dass das Bild die Ziffer 0 enthält. (Dementsprechend haben wir Gewichtsvektoren wd für jede der anderen Ziffern d = 1, . . ., 9.)

Wir addieren also die Pixelwerte, jeweils multipliziert mit einem Gewicht, das ausdrückt, wie wichtig das betreffende Pixel dafür ist, ob das Bild die Ziffer Null zeigt.3

image

Abbildung 2-2: MNIST-Bildpixel aufgereiht als Vektoren und in Spalten zusammengestellt (von links nach rechts nach Ziffern geordnet). Während wir durch den Verlust der räumlichen Information die Ziffern nicht wiedererkennen können, erlaubt die Blockstruktur, die in dieser Darstellung erkennbar wird, die Bildklassifikation mit dem Softmax-Modell. Das Wesentliche ist, dass alle Nullen (im linken Block) eine ähnliche Pixelstruktur besitzen, ebenso alle Einsen (im zweiten Block von links) usw.

Beispielsweise wird w038 eine große positive Zahl sein, wenn eine hohe Helligkeit des 38. Pixels stark darauf hindeutet, dass die Ziffer eine Null ist; eine große negative Zahl, wenn hohe Helligkeitswerte an diesem Ort hauptsächlich in anderen Ziffern auftreten; und Null, wenn der Helligkeitswert des 38. Pixels nichts darüber aussagt, ob diese Ziffer eine Null ist oder nicht.4

Die gleichzeitige Ausführung dieser Rechnung für alle Ziffern (also für jede Ziffer die Berechnung der Indizienstärke dafür, dass das Bild die jeweilige Ziffer zeigt) kann als eine einzige Matrixoperation ausgedrückt werden. Wenn wir die Gewichte für jede der Ziffern in die Spalten einer Matrix W eintragen, dann ergibt

[xw0···xw9] = xW

einen Vektor der Länge 10 mit der Indizienstärke für jede der Ziffern.

Einen Klassifikator anzulernen, hat meist den Zweck, anschließend neue Beispiele zu klassifizieren. In unserem Fall würden wir also gern Ziffern in Bildern erkennen, die wir in unseren Lerndaten noch nicht gesehen haben. Dazu bestimmen wir zunächst die Indizienstärke für jede der 10 möglichen Ziffern (wir berechnen also xW). Am Schluss wird dem Bild die Ziffer mit der höchsten Indizienstärke als »Gewinner« zugeordnet:

digit = argmax(xW)

Wir geben nun den gesamten Code für dieses Beispiel wieder (Beispiel 2-2), gehen ihn anschließend Zeile für Zeile durch und sehen uns die Details an. Sie werden viele neue Elemente sehen, und einige Puzzleteile werden an dieser Stelle noch fehlen. Wir schlagen vor, dass Sie das fürs Erste so hinnehmen; es wird alles zu gegebener Zeit klar werden.

Beispiel 2-2: Klassifikation handschriftlicher Ziffern aus MNIST-Daten mittels Softmax-Regression

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

DATA_DIR = '/tmp/data'

NUM_STEPS = 1000

MINIBATCH_SIZE = 100

data = input_data.read_data_sets(DATA_DIR, one_hot=True)

x = tf.placeholder(tf.float32, [None, 784])

W = tf.Variable(tf.zeros([784, 10]))

y_true = tf.placeholder(tf.float32, [None, 10])

y_pred = tf.matmul(x, W)

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(

logits=y_pred, labels=y_true))

gd_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

correct_mask = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_true, 1))

accuracy = tf.reduce_mean(tf.cast(correct_mask, tf.float32))

with tf.Session() as sess:

# Train

sess.run(tf.global_variables_initializer())

for _ in range(NUM_STEPS):

batch_xs, batch_ys = data.train.next_batch(MINIBATCH_SIZE)

sess.run(gd_step, feed_dict={x: batch_xs, y_true: batch_ys})

# Test

ans = sess.run(accuracy, feed_dict={x: data.test.images, y_true: data.test.labels})

print("Genauigkeit: {:.4}%".format(ans*100))

Wenn Sie den Code auf Ihrem Rechner laufen lassen, sollten Sie folgende Ausgabe erhalten:

Extracting /tmp/data/train-images-idx3-ubyte.gz

Extracting /tmp/data/train-labels-idx1-ubyte.gz

Extracting /tmp/data/t10k-images-idx3-ubyte.gz

Extracting /tmp/data/t10k-labels-idx1-ubyte.gz

Genauigkeit: 91.83%

Das ist alles! Falls Sie bereits auf anderen Plattformen ähnliche Modelle erstellt haben, werden Sie die Einfachheit und Lesbarkeit zu schätzen wissen. Das sind jedoch nur Zugaben zu der Effizienz und Flexibilität, die uns die Berechnungsgraphen von TensorFlow ermöglichen und um die es uns eigentlich geht.

Die tatsächliche Genauigkeit, die Sie erhalten, wird knapp unter 92 % liegen. Wenn Sie das Programm noch einmal ausführen, bekommen Sie einen anderen Wert. Dieses stochastische Verhalten ist beim maschinellen Lernen durchaus üblich, und vermutlich kennen Sie so etwas bereits. In diesem Fall liegt es an der wechselnden Reihenfolge, in der das Modell die handschriftlichen Zahlen beim Anlernen vorgelegt bekommt. Das führt dazu, dass die dabei erlernten Parameter von Lauf zu Lauf leicht unterschiedlich sind.

Fünf Durchläufe desselben Programms könnten also etwa folgendes Ergebnis liefern:

Genauigkeit: 91.86%

Genauigkeit: 91.51%

Genauigkeit: 91.62%

Genauigkeit: 91.93%

Genauigkeit: 91.88%

Wir werden nun den Code für dieses Beispiel überfliegen und schauen, was neu gegenüber dem vorhergehenden »Hallo Welt«-Beispiel ist. Wir gehen zeilenweise vor:

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

Die erste Neuerung in diesem Beispiel ist, dass wir externe Daten benutzen! Statt den MNIST-Datensatz (der unter http://yann.lecun.com/exdb/mnist/ frei verfügbar ist) herunterzuladen und in unser Programm einzulesen, verwenden wir eine eingebaute Hilfsfunktion, um den Datensatz bei Bedarf zu holen. Solche Ladefunktionen gibt es für die meisten häufig verwendeten Datensätze, und wenn wir es mit kleineren zu tun haben (in diesem Fall nur ein paar MB), dann ist das ein sehr sinnvolles Vorgehen. Der zweite Import lädt die Hilfsfunktion, die wir dann sowohl nutzen werden, um die Daten für uns herunterzuladen, als auch, um sie zu verwalten und nach Bedarf aufzuteilen:

DATA_DIR = '/tmp/data'

NUM_STEPS = 1000

MINIBATCH_SIZE = 100

Hier definierten wir einige Konstanten, die wir in unserem Programm verwenden – sie werden alle dort erklärt, wo sie zuerst benutzt werden:

data = input_data.read_data_sets(DATA_DIR, one_hot=True)

Die Methode read_data_sets() des MNIST-Laders lädt den Datensatz herunter und speichert ihn lokal, sodass er später im Programm verwendet werden kann. Das erste Argument, DATA_DIR, ist der Ort, an dem wir die Daten lokal gespeichert haben möchten. Wir setzen es auf '/tmp/data', aber jeder andere Ort wäre genauso gut. Das zweite Argument sagt dem Lader, wie wir die Daten markiert haben wollen; darauf gehen wir jetzt nicht näher ein.5