Moderne Convnets, Squeezenet, Xception, mit Keras und TPUs

1. Übersicht

In diesem Lab lernen Sie die moderne Convolutional Architektur kennen und nutzen Ihr Wissen, um ein einfaches, aber effektives Convnet namens „Squeezenet“ zu implementieren.

Dieses Lab enthält die notwendigen theoretischen Erläuterungen zu Convolutional Neural Networks und ist ein guter Ausgangspunkt für Entwickler, die sich mit Deep Learning vertraut machen.

Dieses Lab ist Teil 4 von „Keras on TPU“ . Sie können sie in der folgenden Reihenfolge oder einzeln durchführen.

ca8cc21f6838eccc.png

Lerninhalte

  • Den funktionalen Keras-Stil perfektionieren
  • Modell mit der Squeezenet-Architektur erstellen
  • Verwendung von TPUs, um schnell zu trainieren und Ihre Architektur zu iterieren
  • Zum Implementieren der Datenerweiterung mit tf.data.dataset
  • Zum Optimieren eines vortrainierten großen Modells (Xception) auf TPU

Feedback

Bitte teilen Sie uns mit, wenn Sie in diesem Code-Lab etwas nicht erkennen. Sie können Feedback über GitHub-Probleme [ feedback link] geben.

2. Kurzanleitung für Google Colaboratory

Für dieses Lab wird Google Collaboratory verwendet. Sie müssen nichts einrichten. Colaboratory ist eine Online-Notebook-Plattform für Bildungszwecke. Sie bietet kostenloses CPU-, GPU- und TPU-Training.

688858c21e3beff2.png

Sie können dieses Beispielnotebook öffnen und einige Zellen durchgehen, um sich mit Colaboratory vertraut zu machen.

c3df49e90e5a654f.png Welcome to Colab.ipynb

TPU-Back-End auswählen

8832c6208c99687d.png

Wählen Sie im Colab-Menü Laufzeit > Laufzeittyp ändern und dann „TPU“ auswählen. In diesem Code-Lab verwenden Sie eine leistungsstarke TPU (Tensor Processing Unit), die für hardwarebeschleunigtes Training unterstützt wird. Die Verbindung zur Laufzeit erfolgt bei der ersten Ausführung automatisch. Alternativ können Sie „Verbinden“ verwenden oben rechts auf die Schaltfläche.

Notebook-Ausführung

76d05caa8b4db6da.png

Führen Sie einzelne Zellen aus, indem Sie auf eine Zelle klicken und die Umschalttaste und die Eingabetaste drücken. Sie können auch das gesamte Notebook ausführen. Wählen Sie dazu Laufzeit > Alle ausführen

Inhaltsverzeichnis

429f106990037ec4.png

Alle Notebooks haben ein Inhaltsverzeichnis. Sie können ihn mit dem schwarzen Pfeil auf der linken Seite öffnen.

Ausgeblendete Zellen

edc3dba45d26f12a.png

Bei einigen Zellen wird nur der Titel angezeigt. Dies ist eine Colab-spezifische Notebook-Funktion. Sie können darauf doppelklicken, um den darin enthaltenen Code anzuzeigen, aber normalerweise ist er nicht sehr interessant. In der Regel Support- oder Visualisierungsfunktionen. Sie müssen diese Zellen trotzdem ausführen, damit die darin enthaltenen Funktionen definiert werden.

Authentifizierung

cdd4b41413100543.png

Colab kann auf Ihre privaten Google Cloud Storage-Buckets zugreifen, sofern Sie sich mit einem autorisierten Konto authentifizieren. Das obige Code-Snippet löst einen Authentifizierungsprozess aus.

3. [INFO] Was sind Tensor Processing Units (TPUs)?

Kurz und bündig

f88cf6facfc70166.png

Der Code zum Trainieren eines Modells auf einer TPU in Keras (und für den Fallback auf die GPU oder CPU, wenn keine TPU verfügbar ist):

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

Wir verwenden TPUs heute, um einen Blumenklassifikator mit interaktiven Geschwindigkeiten (Minuten pro Trainingslauf) zu entwickeln und zu optimieren.

688858c21e3beff2.png

Warum TPUs?

Moderne GPUs sind um programmierbare „Kerne“ organisiert, eine sehr flexible Architektur, mit der eine Vielzahl von Aufgaben wie 3D-Rendering, Deep Learning, physische Simulationen usw. ausgeführt werden können. TPUs hingegen kombinieren einen klassischen Vektorprozessor mit einer dedizierten Matrixmultiplikationseinheit. Sie eignen sich für alle Aufgaben, bei denen große Matrixmultiplikationen dominieren, z. B. neuronale Netzwerke.

8eb3e718b8e2ed08.png

Illustration: Eine dichte neuronale Netzwerkschicht als Matrixmultiplikation mit einem Batch von acht Bildern, die gleichzeitig durch das neuronale Netzwerk verarbeitet werden. Führen Sie die Multiplikation einer Zeile x Spalten durch, um zu überprüfen, ob wirklich eine gewichtete Summe aller Pixelwerte eines Bildes erstellt wird. Faltungsschichten können auch als Matrixmultiplikationen dargestellt werden, obwohl dies etwas komplizierter ist ( Erläuterung in Abschnitt 1).

Die Hardware

MXU und VPU

Ein TPU v2-Kern besteht aus einer Matrix Multiply Unit (MXU), die Matrixmultiplikationen ausführt, und einer Vector Processing Unit (VPU) für alle anderen Aufgaben wie Aktivierungen, Softmax usw. Die VPU verarbeitet float32- und int32-Berechnungen. Die MXU hingegen arbeitet in einem Gleitkommaformat mit gemischter Präzision von 16–32 Bit.

7d68944718f76b18.png

Gemischte Precision-/Gleitkommazahlen und bfloat16

Die MXU berechnet Matrixmultiplikationen mit bfloat16-Eingaben und float32-Ausgaben. Zwischenakkumulierungen werden mit der Genauigkeit float32 ausgeführt.

19c5fc432840c714.png

Das Training eines neuronalen Netzwerks ist in der Regel gegen Rauschen resistent, die durch eine reduzierte Gleitkommagenauigkeit entstehen. Es gibt Fälle, in denen das Rauschen dem Optimierungstool sogar beim Konvergieren hilft. Üblicherweise wurde 16-Bit-Gleitkommagenauigkeit zur Beschleunigung von Berechnungen verwendet, aber die Formate float16 und float32 haben sehr unterschiedliche Bereiche. Die Reduzierung der Precision von float32 auf float16 führt in der Regel zu Über- und Unterflüssen. Es gibt Lösungen, aber in der Regel ist zusätzliche Arbeit erforderlich, damit float16 funktioniert.

Aus diesem Grund hat Google das bfloat16-Format für TPUs eingeführt. bfloat16 ist eine abgeschnittene Gleitkommazahl von Gleitkommazahl32 mit genau denselben Exponentenbits und demselben Bereich wie float32. Hinzu kommt, dass TPUs Matrixmultiplikationen mit gemischter Präzision mit bfloat16-Eingaben und float32-Ausgaben berechnen, was dazu führt, dass normalerweise keine Codeänderungen erforderlich sind, um von den Leistungssteigerungen durch reduzierte Genauigkeit zu profitieren.

Systolic Array

Die MXU implementiert Matrixmultiplikationen in der Hardware mithilfe eines sogenannten „systolischen Arrays“. Architektur, in der Datenelemente durch eine Reihe von Hardware-Recheneinheiten fließen (In der Medizin bezieht sich „systolisch“ auf Herzkontraktionen und den Blutfluss, hier der Datenfluss.)

Das Grundelement einer Matrixmultiplikation ist ein Punktprodukt zwischen einer Linie aus einer Matrix und einer Spalte aus der anderen Matrix (siehe Abbildung oben in diesem Abschnitt). Für eine Matrixmultiplikation Y=X*W wäre ein Element des Ergebnisses:

Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]

Auf einer GPU würde man dieses Punktprodukt in einen GPU-„Kern“ programmieren. und dann auf so vielen „Kernen“ die parallel zur Verfügung stehen, um jeden Wert der Matrix auf einmal zu berechnen. Wenn die resultierende Matrix 128 x 128 groß ist, sind 128 x 128=16.000 Kerne erforderlich. was normalerweise nicht möglich ist. Die größten GPUs haben etwa 4.000 Kerne. Eine TPU verwendet dagegen nur das absolute Minimum an Hardware für die Recheneinheiten in der MXU: nur bfloat16 x bfloat16 => float32 Multiplikationsakkumulatoren, sonst nichts. Sie sind so klein, dass eine TPU 16.000 davon in einer 128 x 128 MXU implementieren und diese Matrixmultiplikation in einem Schritt verarbeiten kann.

f1b283fc45966717.gif

Illustration: Das systolische Array von MXU. Die Rechenelemente sind Multiplikatoren. Die Werte einer Matrix werden in das Array geladen (rote Punkte). Die Werte der anderen Matrix fließen durch das Array (graue Punkte). Vertikale Linien bringen die Werte nach oben. Horizontale Linien geben Teilsummen weiter. Es bleibt dem Nutzer als Übung überlassen, um zu prüfen, ob Sie das Ergebnis der Matrixmultiplikation auf der rechten Seite erhalten, während die Daten durch das Array fließen.

Während die Punktprodukte in einer MXU berechnet werden, fließen Zwischensummen einfach zwischen benachbarten Recheneinheiten. Sie müssen nicht gespeichert und aus dem Speicher oder aus einer Registrierungsdatei abgerufen werden. Das Endergebnis ist, dass die systolische TPU-Array-Architektur bei der Berechnung von Matrixmultiplikationen einen erheblichen Dichte- und Leistungsvorteil sowie einen nicht vernachlässigbaren Geschwindigkeitsvorteil gegenüber einer GPU hat.

Cloud TPU

Wenn Sie eine " Cloud TPU v2" auf der Google Cloud Platform erhalten Sie eine virtuelle Maschine (VM) mit einer mit PCI verbundenen TPU-Platine. Die TPU-Platine hat vier Dual-Core-TPU-Chips. Jeder TPU-Kern verfügt über eine VPU (Vector Processing Unit) und eine 128 × 128 MXU (MatriX Multiplikation Unit). Diese „Cloud TPU“ normalerweise über das Netzwerk mit der VM verbunden, die sie angefordert hat. Das vollständige Bild sieht also so aus:

dfce5522ed644ece.png

Abbildung: VM mit einer mit dem Netzwerk verbundenen „Cloud TPU“ Beschleuniger. „Die Cloud TPU“ aus einer VM mit einer PCI-angehängten TPU-Platine mit vier Dual-Core-TPU-Chips.

TPU-Pods

In den Rechenzentren von Google sind TPUs mit einer Hochleistungs-Computing-Verbindung (High Performance Computing, HPC) verbunden, wodurch sie wie ein sehr großer Beschleuniger erscheinen können. Google nennt sie Pods und sie können bis zu 512 TPU v2-Kerne oder 2048 TPU v3-Kerne umfassen.

2ec1e0d341e7fc34.jpeg

Illustration: Ein TPU v3-Pod. TPU-Boards und -Racks, die über HPC Interconnect verbunden sind.

Während des Trainings werden Gradienten zwischen TPU-Kernen mit dem Algorithmus zur vollständigen Reduzierung ausgetauscht ( hier eine gute Erklärung von All-Reduce). Das trainierte Modell kann die Hardware nutzen, indem es mit großen Batchgrößen trainiert wird.

d97b9cc5d40fdb1d.gif

Illustration: Synchronisierung von Gradienten während des Trainings mit dem Algorithmus „All-Reduce“ im 2-D-Toroidal-Mesh-HPC-Netzwerk von Google TPU.

Die Software

Training mit großen Batchgrößen

Die ideale Batchgröße für TPUs liegt bei 128 Datenelementen pro TPU-Kern, aber die Hardware kann bereits mit 8 Datenelementen pro TPU-Kern eine gute Auslastung nachweisen. Denken Sie daran, dass eine Cloud TPU 8 Kerne hat.

In diesem Code-Lab verwenden wir die Keras API. In Keras ist der von Ihnen angegebene Batch die globale Batchgröße für die gesamte TPU. Ihre Batches werden automatisch in acht aufgeteilt und auf den 8 Kernen der TPU ausgeführt.

da534407825f01e3.png

Weitere Tipps zur Leistung finden Sie im TPU-Leistungsleitfaden. Bei sehr großen Batchgrößen sind bei einigen Modellen besondere Sorgfalt erforderlich. Weitere Informationen finden Sie unter LARSOptimizer.

Details: XLA

TensorFlow-Programme definieren Berechnungsgrafiken. Auf der TPU wird Python-Code nicht direkt ausgeführt, sondern der von Ihrem Tensorflow-Programm definierte Berechnungsgraph. Intern wandelt ein Compiler namens XLA (beschleunigte lineare Algebra-Compiler-) den Tensorflow-Graphen von Rechenknoten in TPU-Maschinencode um. Dieser Compiler führt auch viele erweiterte Optimierungen an Ihrem Code und Ihrem Speicherlayout durch. Die Kompilierung erfolgt automatisch, während die Arbeit an die TPU gesendet wird. Sie müssen XLA nicht explizit in Ihre Build-Kette aufnehmen.

edce61112cd57972.png

Illustration: Zur Ausführung auf TPU wird der von Ihrem Tensorflow-Programm definierte Berechnungsgraph zuerst in eine XLA-Darstellung (beschleunigte lineare Algebra-Compiler-Darstellung) übersetzt und dann von XLA in TPU-Maschinencode kompiliert.

TPUs in Keras verwenden

TPUs werden ab Tensorflow 2.1 durch die Keras API unterstützt. Keras-Unterstützung funktioniert auf TPUs und TPU-Pods. Das folgende Beispiel funktioniert mit TPU, GPU(s) und CPU:

try: # detect TPUs
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model = tf.keras.Sequential( ... )
  model.compile( ... )

# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

In diesem Code-Snippet gilt Folgendes:

  • TPUClusterResolver().connect() findet die TPU im Netzwerk. Die Funktion funktioniert ohne Parameter in den meisten Google Cloud-Systemen (AI Platform-Jobs, Colaboratory, Kubeflow sowie Deep-Learning-VMs, die mit dem Dienstprogramm „ctpu up“ erstellt wurden). Diese Systeme wissen dank einer TPU_NAME-Umgebungsvariable, wo sich ihre TPU befindet. Wenn Sie eine TPU manuell erstellen, legen Sie entweder die TPU_NAME-Umgebung fest. Variable auf der VM, von der aus Sie sie verwenden, oder rufen Sie TPUClusterResolver mit expliziten Parametern auf: TPUClusterResolver(tp_uname, zone, project)
  • TPUStrategy ist der Teil, der die Verteilung und die „all-reduce“ implementiert. Algorithmus der Gradientensynchronisierung.
  • Die Strategie wird über einen Umfang angewendet. Das Modell muss innerhalb des Strategiebereichs (Scope()) definiert werden.
  • Die Funktion tpu_model.fit erwartet ein tf.data.Dataset-Objekt als Eingabe für das TPU-Training.

Häufige TPU-Portierungsaufgaben

  • Es gibt viele Möglichkeiten, Daten in ein TensorFlow-Modell zu laden. Für TPUs ist jedoch die Verwendung der tf.data.Dataset API erforderlich.
  • TPUs sind sehr schnell und die Datenaufnahme führt bei der Ausführung oft zum Engpass. Im TPU-Leistungsleitfaden finden Sie Tools, mit denen Sie Datenengpässe erkennen können, sowie weitere Leistungstipps.
  • int8- oder int16-Zahlen werden als int32 behandelt. Die TPU hat keine Ganzzahl-Hardware, die mit weniger als 32 Bit arbeitet.
  • Einige TensorFlow-Vorgänge werden nicht unterstützt. Die Liste finden Sie hier. Die gute Nachricht ist, dass diese Einschränkung nur für Trainingscode gilt, d.h. für den Vorwärts- und Rückwärtsdurchlauf durch Ihr Modell. Sie können weiterhin alle Tensorflow-Vorgänge in Ihrer Dateneingabepipeline verwenden, da sie auf der CPU ausgeführt werden.
  • tf.py_func wird auf TPUs nicht unterstützt.

4. [INFO] Klassifikator für neuronale Netzwerke – erste Schritte

Kurz und bündig

Wenn Ihnen alle im nächsten Absatz fett formatierten Begriffe bereits bekannt sind, können Sie mit der nächsten Übung fortfahren. Wenn Sie gerade erst mit dem Thema "Deep Learning" beginnen, ist dies willkommen. Bitte lesen Sie weiter.

Für Modelle, die als Folge von Ebenen erstellt wurden, bietet Keras die Sequential API an. Ein Bildklassifikator mit drei dichten Schichten kann beispielsweise in Keras so geschrieben werden:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

Kompaktes neuronales Netzwerk

Dies ist das einfachste neuronale Netzwerk zum Klassifizieren von Bildern. Es besteht aus „Neuronen“. in Schichten angeordnet sein. Die erste Ebene verarbeitet Eingabedaten und speist ihre Ausgaben in andere Ebenen ein. Sie nennt sich „dichte“ da jedes Neuron mit allen Neuronen aus der vorherigen Schicht verbunden ist.

c21bae6dade487bc.png

Sie können ein Bild in ein solches Netzwerk einspeisen, indem Sie die RGB-Werte aller seiner Pixel zu einem langen Vektor zusammenfassen und als Eingabe verwenden. Es ist nicht die beste Technik für die Bilderkennung, aber wir werden sie später verbessern.

Neuronen, Aktivierungen, RELU

Ein „Neuron“ berechnet eine gewichtete Summe aller Eingaben und addiert einen Wert namens „Verzerrung“ Das Ergebnis wird in eine sogenannte „Aktivierungsfunktion“ eingespeist. Die Gewichtungen und Verzerrungen sind zunächst unbekannt. Sie werden zufällig initialisiert und „erlernt“. indem Sie das neuronale Netzwerk mit vielen bekannten Daten trainieren.

644f4213a4ee70e5.png

Die am häufigsten verwendete Aktivierungsfunktion ist RELU für die korrigierte Lineareinheit. Wie Sie in der Grafik oben sehen können, ist dies eine sehr einfache Funktion.

Softmax-Aktivierung

Das obige Netzwerk endet mit einer Schicht mit 5 Neuronen, da wir Blumen in fünf Kategorien unterteilen: Rose, Tulpe, Löwenzahn, Gänseblümchen, Sonnenblume. Neuronen in Zwischenschichten werden mit der klassischen RELU-Aktivierungsfunktion aktiviert. In der letzten Ebene möchten wir jedoch Zahlen zwischen 0 und 1 berechnen, die die Wahrscheinlichkeit darstellen, dass diese Blume eine Rose, eine Tulpe usw. ist. Dazu verwenden wir eine Aktivierungsfunktion namens „Softmax“.

Die Anwendung von Softmax auf einen Vektor erfolgt, indem die Exponentialfunktion jedes Elements ermittelt und dann der Vektor normalisiert wird. Normalerweise wird die L1-Norm (Summe der absoluten Werte) verwendet, sodass die Werte addiert 1 ergeben und als Wahrscheinlichkeiten interpretiert werden können.

ef0d98c0952c262d.png d51252f75894479e.gif

Kreuzentropieverlust

Nachdem nun unser neuronales Netzwerk Vorhersagen aus Eingabebildern produziert, müssen wir messen, wie gut sie sind, d.h. den Abstand zwischen dem, was uns das Netzwerk mitteilt, und den richtigen Antworten, die oft als „Labels“ bezeichnet werden. Denken Sie daran, dass wir die korrekten Labels für alle Bilder im Dataset haben.

Jede Entfernung würde funktionieren, aber für Klassifizierungsprobleme wäre die sogenannte „Kreuzentropie-Distanz“. ist am effektivsten. Wir bezeichnen dies als Fehler oder „Verlust“. :

7bdf8753d20617fb.png

Gradientenabstieg

„Schulung“ Das neuronale Netzwerk bedeutet, Trainingsbilder und -labels zu verwenden, um Gewichtungen und Verzerrungen so anzupassen, dass die Kreuzentropie-Verlustfunktion minimiert wird. Und so funktioniert es:

Die Kreuzentropie ist eine Funktion von Gewichtungen, Verzerrungen, Pixeln des Trainingsbilds und seiner bekannten Klasse.

Wenn wir die partiellen Ableitungen der Kreuzentropie relativ zu allen Gewichtungen und allen Verzerrungen berechnen, erhalten wir einen "Gradienten", der für ein bestimmtes Bild, Label und den Gegenwartswert von Gewichtungen und Verzerrungen berechnet wird. Denken Sie daran, dass wir Millionen von Gewichtungen und Verzerrungen haben können, sodass die Berechnung des Farbverlaufs wie eine Menge Arbeit klingt. Zum Glück macht Tensorflow das für uns. Die mathematische Eigenschaft eines Farbverlaufs besteht darin, dass er nach oben zeigt. Da wir hingehen möchten, wo die Kreuzentropie gering ist, gehen wir in die entgegengesetzte Richtung. Gewichtungen und Verzerrungen werden um einen Bruchteil des Farbverlaufs aktualisiert. Dann wiederholen wir das und verwenden die nächsten Batches von Trainingsbildern und ‐labels in einer Trainingsschleife. Hoffentlich nähert sich dies einem Punkt an, an dem die Kreuzentropie minimal ist, obwohl nichts garantiert, dass dieses Minimum einzigartig ist.

Gradientenabstieg2.png

Mini-Batching und Impuls

Sie können Ihren Gradienten nur für ein Beispielbild berechnen und die Gewichtungen und Gewichtungen sofort aktualisieren. Bei einem Batch von beispielsweise 128 Bildern ergibt sich jedoch ein Farbverlauf, der die Einschränkungen durch verschiedene Beispielbilder besser darstellt und daher wahrscheinlich schneller der Lösung näherkommt. Die Größe des Mini-Batches ist ein anpassbarer Parameter.

Diese Technik, die manchmal auch als „stochastisches Gradientenabstieg“ bezeichnet wird hat einen weiteren, pragmatischeren Vorteil: Die Arbeit mit Batches bedeutet auch, mit größeren Matrizen zu arbeiten, und diese lassen sich in der Regel einfacher für GPUs und TPUs optimieren.

Die Konvergenz kann jedoch immer noch etwas chaotisch sein und sogar aufhören, wenn der Gradientenvektor nur Nullen enthält. Bedeutet das, dass wir ein Minimum gefunden haben? Nimmt immer. Eine Farbverlaufskomponente kann bei einem Mindest- oder Höchstwert null sein. Bei einem Gradientenvektor mit Millionen von Elementen ist die Wahrscheinlichkeit, dass jede Null einem Minimum und keines von ihnen einem Höchstpunkt entspricht, ziemlich gering, wenn alle Nullen sind. In einem Raum mit vielen Dimensionen kommen Sattelpunkte häufig vor, sodass wir nicht bei ihnen anhalten möchten.

52e824fe4716c4a0.png

Illustration: ein Sattelpunkt. Der Farbverlauf ist 0, aber kein Mindestwert in alle Richtungen. (Bildzuordnung Wikimedia: By Nicoguaro – Own work, CC BY 3.0)

Die Lösung besteht darin, dem Optimierungsalgorithmus etwas Schwung zu verleihen, damit er die Sattelpunkte überwinden kann, ohne anzuhalten.

Glossar

batch oder mini-batch: Das Training wird immer mit Batches von Trainingsdaten und Labels durchgeführt. So kann der Algorithmus konvergieren. Der „Batch“ Dimension ist in der Regel die erste Dimension von Datentensoren. Zum Beispiel enthält ein Tensor mit der Form [100, 192, 192, 3] 100 Bilder mit 192 × 192 Pixeln mit drei Werten pro Pixel (RGB).

Kreuzentropieverlust: eine spezielle Verlustfunktion, die häufig in Klassifikatoren verwendet wird.

dichte Schicht: Eine Schicht aus Neuronen, bei der jedes Neuron mit allen Neuronen aus der vorherigen Schicht verbunden ist.

features: Die Eingaben eines neuronalen Netzwerks werden manchmal als „Features“ bezeichnet. Die Kunst, herauszufinden, welche Teile eines Datasets (oder Kombinationen von Teilen) in ein neuronales Netzwerk eingespeist werden sollen, um gute Vorhersagen zu erhalten, wird als „Feature Engineering“ bezeichnet.

labels: ein anderer Name für "Klassen" oder richtige Antworten bei einem beaufsichtigten Klassifizierungsproblem

Lernrate: Anteil des Gradienten, um den Gewichtungen und Verzerrungen bei jeder Iteration der Trainingsschleife aktualisiert werden.

Logits: Die Ausgaben einer Neuronenschicht vor Anwendung der Aktivierungsfunktion werden als "Logits" bezeichnet. Der Begriff leitet sich von der „logistischen Funktion“ ab, auch bekannt als die „Sigmoidfunktion“ Dies war früher die am häufigsten verwendete Aktivierungsfunktion. „Neuron gibt vor logistische Funktion aus“ als „logits“ abgekürzt.

loss: die Fehlerfunktion, die die Ausgaben neuronaler Netzwerke mit den richtigen Antworten vergleicht

neuron: berechnet die gewichtete Summe der Eingaben, fügt eine Verzerrung hinzu und speist das Ergebnis über eine Aktivierungsfunktion ein.

One-Hot-Codierung: Klasse 3 von 5 wird als Vektor aus 5 Elementen codiert, alle Nullen mit Ausnahme des dritten, also 1.

relu: korrigierte lineare Einheit. Eine beliebte Aktivierungsfunktion für Neuronen.

Sigmoid: Eine weitere Aktivierungsfunktion, die früher häufig verwendet wurde und in Sonderfällen immer noch nützlich ist.

Softmax-Parameter: eine spezielle Aktivierungsfunktion, die auf einen Vektor wirkt, die Differenz zwischen der größten und allen anderen Komponenten erhöht und außerdem den Vektor auf die Summe 1 normalisiert, sodass er als Vektor von Wahrscheinlichkeiten interpretiert werden kann. Wird als letzter Schritt in Klassifikatoren verwendet.

tensor: Ein "Tensor" ist wie eine Matrix, aber mit einer beliebigen Anzahl von Dimensionen. Ein eindimensionaler Tensor ist ein Vektor. Ein zweidimensionaler Tensor ist eine Matrix. Dann können Sie Tensoren mit 3, 4, 5 oder mehr Dimensionen haben.

5. [INFO] Convolutional Neural Networks

Kurz und bündig

Wenn Ihnen alle im nächsten Absatz fett formatierten Begriffe bereits bekannt sind, können Sie mit der nächsten Übung fortfahren. Wenn Sie gerade erst mit Convolutional Neural Networks anfangen, lesen Sie bitte weiter.

convolutional.gif

Illustration: Bildfilterung mit zwei aufeinanderfolgenden Filtern aus jeweils 4 × 3=48 lernbaren Gewichten.

So sieht ein einfaches Convolutional Neural Network in Keras aus:

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

688858c21e3beff2.png

Convolutional Neural Nets – Grundlagen

In einer Schicht eines Convolutional Network, ein "Neuron" eine gewichtete Summe der direkt darüber liegenden Pixel, nur über einen kleinen Bereich des Bildes hinweg. Sie fügt eine Verzerrung hinzu und füttert die Summe durch eine Aktivierungsfunktion, so wie es ein Neuron in einer regulären dichten Schicht tun würde. Dieser Vorgang wird dann für das gesamte Bild mit denselben Gewichtungen wiederholt. Denken Sie daran, dass in dichten Schichten jedes Neuron eine eigene Gewichtung hatte. Hier wird ein einzelnes "Patch" von Gewichtungen gleitet in beide Richtungen über das Bild (eine "Faltung"). Die Ausgabe hat so viele Werte, wie Pixel im Bild enthalten sind. An den Rändern ist jedoch ein gewisser Abstand erforderlich. Es handelt sich um einen Filtervorgang, bei dem ein Filter mit einer Gewichtung von 4x4x3=48 verwendet wird.

48 Gewichtungen reichen jedoch nicht aus. Um weitere Freiheitsgrade hinzuzufügen, wiederholen wir denselben Vorgang mit einem neuen Satz von Gewichtungen. Dies erzeugt einen neuen Satz von Filterausgaben. Nennen wir es einen „Kanal“, der Ausgabewerte analog zu den R-, G- und B-Kanälen im Eingabebild.

Screen Shot 2016-07-29 at 16.02.37.png

Die zwei (oder mehr) Gewichtungssätze können durch Hinzufügen einer neuen Dimension zu einem Tensor addiert werden. Damit erhalten wir die generische Form des Tensors für die Gewichtung für eine Faltungsschicht. Da die Anzahl der Eingabe- und Ausgabekanäle Parameter sind, können wir mit dem Stapeln und Verketten von Faltungsschichten beginnen.

d1b557707bcd1cb9.png

Illustration: Ein Convolutional Neural Network transformiert „Cubes“ von Daten in andere „Cubs“ von Daten.

Schrittweise Faltungen, max. Pooling

Wenn wir die Faltungen mit einer Schrittzahl von 2 oder 3 ausführen, können wir den resultierenden Datenwürfel auch in seiner horizontalen Dimension verkleinern. Hierfür gibt es zwei gängige Methoden:

  • Gestrichelte Faltung: ein gleitender Filter wie oben, aber mit einer Schrittlänge > 1
  • Max. Pooling: ein gleitendes Fenster, in dem der MAX-Vorgang angewendet wird (in der Regel auf 2 x 2 Patches, wiederholt alle 2 Pixel)

2b2d4263bb8470b.gif

Illustration: Das Verschieben des Rechenfensters um 3 Pixel führt zu weniger Ausgabewerten. Gestrichelte Faltungen oder Max-Pooling (Maximum auf einem 2 x 2-Fenster, das in einem Schritt von 2 verschoben wird) sind eine Möglichkeit, den Datenwürfel in horizontalen Dimensionen zu verkleinern.

Konvolutionärer Klassifikator

Schließlich fügen wir einen Klassifizierungskopf an, indem wir den letzten Datenwürfel vereinfachen und durch eine dichte, Softmax-aktivierte Ebene speisen. Ein typischer Convolutional Klassifikator kann beispielsweise so aussehen:

4a61aaffb6cba3d1.png

Abbildung: Bildklassifikator mit Convolutional- und Softmax-Layers. Es werden 3x3- und 1x1-Filter verwendet. Die Maxpool-Ebenen verwenden das Maximum von Gruppen von 2 x 2 Datenpunkten. Der Klassifizierungskopf ist mit einer dichten Schicht mit Softmax-Aktivierung implementiert.

In Keras

Der oben dargestellte Convolutional Stack kann in Keras wie folgt geschrieben werden:

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)    
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

6. [NEW INFO] Moderne Convolutional-Architekturen

Kurz und bündig

7968830b57b708c0.png

Illustration: Ein Faltungsmodul. Was ist an diesem Punkt am besten? Eine Max-Pool-Ebene gefolgt von einer 1x1-Faltungsschicht oder einer anderen Kombination von Ebenen? Probieren Sie alle aus, verketten Sie die Ergebnisse und lassen Sie das Netzwerk entscheiden. Auf der rechten Seite: die Einführung“ Convolutional Architecture mit solchen Modulen.

Um in Keras Modelle zu erstellen, bei denen sich der Datenfluss verzweigen kann, müssen Sie die „funktionale“ Modellstil. Hier ein Beispiel:

l = tf.keras.layers # syntax shortcut

y = l.Conv2D(filters=32, kernel_size=3, padding='same',
             activation='relu', input_shape=[192, 192, 3])(x) # x=input image

# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation

# many more layers ...

# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)

688858c21e3beff2.png

Weitere günstige Tricks

Kleine 3x3-Filter

40a7b15fb7dbe75c.png

In dieser Abbildung sehen Sie das Ergebnis von zwei aufeinanderfolgenden 3 × 3-Filtern. Versuchen Sie herauszufinden, welche Datenpunkte zum Ergebnis beigetragen haben: Diese beiden aufeinanderfolgenden 3 x 3-Filter berechnen eine Kombination einer 5 x 5-Region. Dies ist nicht genau dieselbe Kombination, die ein 5x5-Filter berechnen würde, aber es lohnt sich, es auszuprobieren, da zwei aufeinanderfolgende 3x3-Filter günstiger sind als ein einzelner 5x5-Filter.

1 × 1-Faltungen?

fd7cac16f8ecb423.png

Mathematische Bezeichnungen sind "1x1" Faltung ist eine Multiplikation mit einer Konstanten, kein sehr nützliches Konzept. Denken Sie bei Convolutional Neural Networks jedoch daran, dass der Filter auf einen Datenwürfel und nicht nur auf ein 2D-Bild angewendet wird. Dementsprechend wird ein „1x1“- filter berechnet eine gewichtete Summe einer 1-x-1-Datenspalte (siehe Abbildung). Wenn Sie sie über die Daten schieben, erhalten Sie eine lineare Kombination der Kanäle der Eingabe. Das ist tatsächlich nützlich. Stellen Sie sich die Channels als Ergebnisse einzelner Filtervorgänge vor, z. B. einen Filter für "spitze Ohren" und einen für "Whisker". und ein drittes für „Schlitzaugen“, dann ein „1 x 1“ wird die Convolutional-Ebene mehrere mögliche lineare Kombinationen dieser Merkmale berechnet, was bei der Suche nach einer „Katze“ nützlich sein kann. Außerdem verbrauchen 1 x 1-Ebenen weniger Gewichte.

7. Quetschzette

Eine einfache Möglichkeit, diese Ideen zusammenzuführen, wurde in "Squeezenet" gezeigt. auf Papier. Die Autoren schlagen ein sehr einfaches Faltungsmoduldesign vor, das nur 1x1- und 3x3-Faltungsebenen verwendet.

1730ac375379269b.png

Illustration: Squeezenet-Architektur, die auf „Feuermodulen“ basiert. Sie wechseln zu einer 1:1-Schicht, die „drückt“, die eingehenden Daten in der vertikalen Dimension gefolgt von zwei parallelen 1 x 1- und 3 x 3-Faltungsebenen, die „erweitern“ werden um die Tiefe der Daten wieder zu analysieren.

Praktische Übung

Fahren Sie mit Ihrem vorherigen Notebook fort und erstellen Sie ein von Squeezenet inspiriertes Convolutional Neural Network. Sie müssen den Modellcode in den „funktionalen Stil“ von Keras ändern.

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

Weitere Informationen

Für diese Übung ist es hilfreich, eine Hilfsfunktion für ein Squeezenet-Modul zu definieren:

def fire(x, squeeze, expand):
  y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
  y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
  y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
  return tf.keras.layers.concatenate([y1, y3])

# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
  return lambda x: fire(x, squeeze, expand)

# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)

Dieses Mal besteht das Ziel darin, eine Genauigkeit von 80% zu erreichen.

Jetzt ausprobieren

Beginnen Sie mit einer einzelnen Convolutional Layer, gefolgt von „fire_modules“, abwechselnd mit MaxPooling2D(pool_size=2) Ebenen. Sie können mit 2 bis 4 max. Pooling-Ebenen im Netzwerk und auch mit 1, 2 oder 3 aufeinanderfolgenden Brandmodulen zwischen den maximalen Pooling-Ebenen experimentieren.

In den Feuermodulen ist das „Quetschen“ sollte normalerweise kleiner sein als der Parameter "expand". . Bei diesen Parametern handelt es sich eigentlich um die Anzahl der Filter. Sie können in der Regel zwischen 8 und 196 liegen. Sie können mit Architekturen experimentieren, bei denen die Anzahl der Filter im Netzwerk allmählich zunimmt, oder mit einfachen Architekturen, bei denen alle Feuermodule die gleiche Anzahl von Filtern haben.

Hier ein Beispiel:

x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB

y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)

model = tf.keras.Model(x, y)

An dieser Stelle stellen Sie vielleicht fest, dass Ihre Tests nicht so gut verlaufen und das Ziel einer Genauigkeit von 80% unwahrscheinlich erscheint. Zeit für ein paar weitere günstige Tricks.

Batch-Normalisierung

Die Batch-Norm hilft bei den Konvergenzproblemen, die bei Ihnen auftreten. Im nächsten Workshop erhalten Sie detaillierte Erläuterungen zu dieser Technik. Bitte verwenden Sie sie vorerst als Blackbox-„Magie“. Hilfsprogramm, indem Sie diese Zeile nach jeder Convolutional Layer in Ihrem Netzwerk einfügen, einschließlich der Layers innerhalb Ihrer Fire_module-Funktion:

y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context

Der Momentum-Parameter muss von seinem Standardwert von 0,99 auf 0,9 gesenkt werden, da unser Datensatz klein ist. Kümmern Sie sich vorerst nicht um dieses Detail.

Datenerweiterung

Sie erhalten ein paar weitere Prozentpunkte, wenn Sie die Daten mit einfachen Transformationen wie Links-Rechts-Umdrehungen von Sättigungsänderungen anreichern:

4ed2958e09b487ca.png

ad795b70334e0d6b.png

In TensorFlow lässt sich das ganz einfach mit der tf.data.Dataset API tun. Definieren Sie eine neue Transformationsfunktion für Ihre Daten:

def data_augment(image, label):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_saturation(image, lower=0, upper=2)
    return image, label

Verwenden Sie ihn dann für die abschließende Datentransformation (Zelle "Trainings- und Validierungs-Datasets", Funktion "get_batched_dataset"):

dataset = dataset.repeat() # existing line
# insert this
if augment_data:
  dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line

Vergessen Sie nicht, die Datenerweiterung optional zu machen und den erforderlichen Code hinzuzufügen, damit nur das Trainings-Dataset erweitert wird. Es ist nicht sinnvoll, das Validierungs-Dataset zu erweitern.

Jetzt sollte eine Genauigkeit von 80% in 35 Epochen erreicht werden.

Lösung

Hier ist das Lösungs-Notebook. Sie können sie verwenden, wenn Sie nicht weiterkommen.

c3df49e90e5a654f.png Keras_Flowers_TPU_squeezenet.ipynb

Behandelte Themen

  • 🤔 Keras – „Funktionaler Stil“ Modelle
  • 🤓 Squeezenet-Architektur
  • 🤓 Datenerweiterung mit tf.data.datset

Bitte nehmen Sie sich einen Moment Zeit und gehen Sie diese Checkliste durch.

8. Xception optimiert

Teilbare Faltungen

In letzter Zeit wurde eine andere Methode zur Implementierung von Faltschichten immer beliebter: tieftrennbare Faltungen. Ich weiß, es ist ein Bissen, aber das Konzept ist recht einfach. Sie sind in Tensorflow und Keras als tf.keras.layers.SeparableConv2D implementiert.

Eine trennbare Faltung führt ebenfalls einen Filter auf das Bild aus, verwendet jedoch einen speziellen Satz von Gewichtungen für jeden Kanal des Eingabebilds. Darauf folgt eine „1x1-Faltung“, eine Reihe von Punktprodukten, die zu einer gewichteten Summe der gefilterten Kanäle führt. Bei jeder neuen Gewichtung werden so viele gewichtete Neukombinationen der Kanäle wie nötig berechnet.

615720b803bf8dda.gif

Illustration: Trennbare Faltungen. Phase 1: Faltungen mit einem separaten Filter für jeden Kanal. Phase 2: Lineare Neukombinationen von Kanälen. Wird mit einem neuen Satz von Gewichtungen wiederholt, bis die gewünschte Anzahl von Ausgabekanälen erreicht ist. Phase 1 kann ebenfalls wiederholt werden, wobei jedes Mal eine neue Gewichtung erfolgt, aber in der Praxis ist dies selten der Fall.

Trennbare Faltungen werden in den neuesten Convolutional-Network-Architekturen verwendet: MobileNetV2, Xception, EffectiveNet. Übrigens haben Sie bisher MobileNetV2 für Lerntransfers verwendet.

Sie sind kostengünstiger als reguläre Faltungen und in der Praxis hat sich als genauso effektiv erwiesen. Hier sehen Sie die Anzahl der Gewichtungen für das obige Beispiel:

Convolutional Layer: 4 x 4 x 3 x 5 = 240

Teilbare Faltungsschicht: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63

Der Leser muss die Anzahl der Multiplikationen berechnen, die erforderlich sind, um die einzelnen Stile der Faltungsebene auf ähnliche Weise anzuwenden. Trennbare Faltungen sind kleiner und rechenintensiver.

Praktische Übung

„Lerntransfer“ neu starten Playground-Notebook, aber wählen Sie diesmal Xception als vortrainiertes Modell aus. Xception verwendet nur trennbare Faltungen. Lass alle Gewichte trainierbar. Wir werden die vortrainierten Gewichtungen für unsere Daten optimieren, anstatt die vortrainierten Ebenen als solche zu verwenden.

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

Ziel: Genauigkeit > 95% (Nein, wirklich, es ist möglich!)

Dies ist die letzte Übung. Sie erfordert etwas mehr Arbeit im Code und in Data Science.

Weitere Informationen zur Feinabstimmung

Xception ist in den standardmäßigen vortrainierten Modellen in tf.keras.application verfügbar.* Vergiss nicht, dieses Mal alle Gewichte trainierbar zu machen.

pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
                                                  include_top=False)
pretrained_model.trainable = True

Um bei der Feinabstimmung eines Modells gute Ergebnisse zu erzielen, müssen Sie auf die Lernrate achten und einen Lernratenplan mit einer Anlaufzeit verwenden. Ein Beispiel:

9b1af213b2b36d47.png

Wenn Sie mit einer Standard-Lernrate beginnen, würden die vortrainierten Gewichtungen des Modells gestört werden. Beim Starten werden sie nach und nach beibehalten, bis das Modell Ihre Daten gespeichert hat und sie sinnvoll ändern kann. Nach der Erhöhung können Sie mit einer konstanten oder exponentiell abnehmenden Lernrate fortfahren.

In Keras wird die Lernrate über einen Callback angegeben, mit dem Sie die entsprechende Lernrate für jede Epoche berechnen können. Keras übergibt für jede Epoche die richtige Lernrate an den Optimierungstool.

def lr_fn(epoch):
  lr = ...
  return lr

lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)

model.fit(..., callbacks=[lr_callback])

Lösung

Hier ist das Lösungs-Notebook. Sie können sie verwenden, wenn Sie nicht weiterkommen.

c3df49e90e5a654f.png 07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb

Behandelte Themen

  • 🤔 Tiefentrennbare Faltung
  • 🤓 Lernpläne
  • 😈 Ein vortrainiertes Modell optimieren.

Bitte nehmen Sie sich einen Moment Zeit und gehen Sie diese Checkliste durch.

9. Glückwunsch!

Sie haben Ihr erstes modernes Convolutional Neural Network erstellt und es mit einer Genauigkeit von über 90% trainiert. Dabei iterieren Sie dank TPUs in nur wenigen Minuten aufeinanderfolgendem Training. Damit sind die vier Codelabs „Keras auf TPU-Codelabs“ abgeschlossen:

TPUs in der Praxis

TPUs und GPUs sind auf der Cloud AI Platform verfügbar:

Zu guter Letzt freuen wir uns über Feedback. Bitte teilen Sie uns mit, wenn Ihnen in diesem Lab etwas fehlt oder Sie der Meinung sind, dass es verbessert werden sollte. Sie können Feedback über GitHub-Probleme [ feedback link] geben.

HR.png

Martin Görner ID, klein.jpg
Der Autor: Martin Görner
Twitter: @martin_gorner

TensorFlow-Logo.jpg
www.tensorflow.org