[PYTHON] Hinweise zur Funktion und Rückverfolgung

Einführung

Dieser Artikel ist der Artikel zum 20. Tag von TensorFlow 2.0 Adventskalender 2019. Ich denke, die wichtigste Änderung in TensorFlow 2.0 ist, dass EagerExecution zum Standard geworden ist, sodass Sie in einer zwingenden Sprache schreiben und freier im pythonischen Stil schreiben können. Auf der anderen Seite gibt es jedoch das Problem, dass Leistung und Portabilität beeinträchtigt werden, aber um es so zu lösen, dass Sie sowohl vom Grafikmodus in 1.x als auch vom Eager-Modus in 2.x profitieren können. Eingeführt in tf.function. In diesem Artikel möchte ich Ihnen die Verwendung von "tf.function" und Punkte vorstellen, die Sie bei der Verwendung beachten sollten. Grundsätzlich handelt es sich um eine Zusammenfassung von Official Site. Wenn Sie also mehr wissen möchten, lesen Sie bitte auch diese.

Verwendung von tf.function

Es ist einfach zu bedienen. Sie können der Funktion, die die zu optimierende Verarbeitung beschreibt, einen Kollator mit "@ tf.function" hinzufügen oder eine Funktion definieren und der Methode "tf.function" zuweisen, um eine Funktion für den Grafikmodus separat hinzuzufügen. Es ist eine Methode zum Erstellen.

function_test.py


import tensorflow as tf

@tf.function
def f(x,y):
  return x + y

#Oder

def g(x,y):
  return x * y

h = tf.function(g)

Wenn Sie eine andere Funktion in "@ tf.function" aufrufen, erstreckt sich der Bereich auch auf diese Funktion, sodass Sie nicht alle Funktionen überprüfen und "@ tf.function" hinzufügen müssen (oder besser gesagt, wir empfehlen es). Sinn). Daher scheint es, dass Sie leicht vom Grafikmodus profitieren können, indem Sie ihn vorerst dem schweren Verarbeitungsteil hinzufügen. Wenn es sich jedoch um einen einfachen Schreibstil wie den im Tutorial handelt, ist dies keine große Sache. Wenn Sie jedoch versuchen, etwas Kompliziertes zu tun, werden Sie nicht glauben, dass Sie die Spezifikation von "tf.function" nicht kennen. Sie müssen vorsichtig sein, weil Sie es tun. Am Anfang von Offizielle Website steht die folgende Beschreibung.

Es gibt einige Punkte, die schwer zu interpretieren sind, aber ich denke, es ist einfacher zu verstehen, wenn Sie sich ein konkretes Beispiel ansehen. Schauen wir uns das an.

Experiment

Bereiten Sie der Einfachheit halber zunächst die folgende einfache Funktion vor.

tracing_test.py


import tensorflow as tf

@tf.function
def double(a):
    print("Tracing with, {}".format(a) )
    return a + a

Es ist eine einfache Funktion, die das Eingabeargument verdoppelt und zurückgibt und auch das Drucken des Eingabearguments umfasst. Das Argument funktioniert mit ganzen Zahlen, reellen Zahlen und Zeichenfolgen. Lassen Sie uns dies mit einigen Mustern tun.

tracing_test.py


print(double(3))
print()
print(double(2))
print()
print(double(tf.constant(1.1)))
print()
print(double(tf.constant('a')))
print()
print(double(tf.constant('b')))

Das Ergebnis ist wie folgt.

Tracing with, 3
tf.Tensor(6, shape=(), dtype=int32)

Tracing with, 2
tf.Tensor(4, shape=(), dtype=int32)

Tracing with, Tensor("a:0", shape=(), dtype=float32)
tf.Tensor(2.2, shape=(), dtype=float32)

Tracing with, Tensor("a:0", shape=(), dtype=string)
tf.Tensor(b'aa', shape=(), dtype=string)

tf.Tensor(b'bb', shape=(), dtype=string)

Das Ergebnis ist etwas seltsam. Die print-Anweisung wird nicht nur ausgeführt, wenn die letzte "tf.constant (" b ")" als Argument ausgeführt wird. Wenn Sie versuchen, das obige Programm erneut auszuführen, erhalten Sie noch seltsamere Ergebnisse.

tracing_test.py


print(double(3))
print()
print(double(2))
print()
print(double(tf.constant(1.1)))
print()
print(double(tf.constant('a')))
print()
print(double(tf.constant('b')))

Das Ergebnis ist wie folgt.

tf.Tensor(6, shape=(), dtype=int32)

tf.Tensor(4, shape=(), dtype=int32)

tf.Tensor(2.2, shape=(), dtype=float32)

tf.Tensor(b'aa', shape=(), dtype=string)

tf.Tensor(b'bb', shape=(), dtype=string)

Der korrekte Wert wird zurückgegeben, aber die in der Mitte geschriebene Druckanweisung wird überhaupt nicht ausgeführt. Was bedeutet das?

Tracing Tatsächlich beinhaltet dieses seltsame Verhalten einen Prozess namens Tracing, wenn "tf.function" eine Funktion in einem Rechengraphen erstellt und optimiert. tf.function konvertiert eine Funktion, die nicht nur die von TensorFlow abgeleitete, sondern auch die Python-spezifische Verarbeitung beschreibt, in einen Rechengraphen. Außerdem wird die Python-spezifische Verarbeitung (in diesem Fall die Druckanweisung) weggelassen, die nicht mit der Ausführung des Berechnungsdiagramms zusammenhängt. Aber warum wurde es zuerst gemacht? Das liegt daran, dass ein Prozess namens Tracing ausgeführt wird, wenn tf.function eine Funktion in einen Rechengraphen konvertiert. In Python geschriebene Funktionen haben keinen expliziten Typ in ihren Argumenten. Während es praktisch ist, verschiedene Werte eingeben zu können, ist es daher ein Problem von der Seite "tf.function", ein optimales Berechnungsdiagramm zu erstellen. Wenn daher ein Wert oder Typ eingegeben wird, der nicht in das Argument eingegeben wurde, und die Funktion zum ersten Mal aufgerufen wird, wird ein Prozess namens Tracing ausgeführt, um die gesamte Python-spezifische Verarbeitung in der Funktion auszuführen. Ich sagte "Werte und Typen, die nie in das Argument aufgenommen wurden", aber genau genommen lauten die Kriterien wie folgt.

Daher ist das seltsame Verhalten des vorherigen wie folgt.

tracing_test.py


print(double(3)) #Rückverfolgung, weil es der Wert ist, den ich zum ersten Mal sehe
print()
print(double(2)) #Rückverfolgung, weil es der Wert ist, den ich zum ersten Mal sehe
print()
print(double(tf.constant(1.1))) #Rückverfolgung, weil es der Wert ist, den ich zum ersten Mal sehe
print()
print(double(tf.constant('a'))) #Verfolgung, weil es die erste Form ist, die man sieht
print()
print(double(tf.constant('b'))) #Optimierte Diagrammausführung, da es sich um die zuvor gesehene Typform handelt

Sobald Sie Tracing ausführen, speichert TensorFlow das resultierende Berechnungsdiagramm intern. Wenn dann das nächste Mal ein zuvor verfolgter Wert oder ein Typ / Form-Argument eingegeben wird, wird das optimierte Berechnungsdiagramm ausgeführt. Daher wurde im obigen Programm die Python-Druckanweisung beim letzten Aufruf nicht ausgeführt, und alle Druckanweisungen wurden nicht ausgeführt, als sie erneut ausgeführt wurden.

Also, was sollten wir tun?

Also werde ich zum Anfang zurückkehren,

Es bedeutet das. Es ist früher drucken, aber wenn Sie es stattdessen in "tf.print" schreiben, wird es jedes Mal ausgeführt. Sie können auch seltsames Verhalten verhindern, indem Sie von TensorFlow abgeleitete Funktionen vollständig nutzen, z. B. "tf.summary" oder "tf.Variable", wenn Sie verschiedene Werte in einer Funktion aktualisieren möchten. Es verbessert auch die Leistung. Bitte beachten Sie jedoch, dass wir nicht sagen, dass wir keine Python-spezifische Verarbeitung einbeziehen sollten. Der Vorteil, flexibler programmieren zu können, indem man es zusammen mit pythonischem Schreiben verwenden kann, ist groß. Beachten Sie jedoch, dass sich eine Funktion seltsam verhält, wenn Sie sie definieren, ohne an irgendetwas zu denken, und "tf.function" hinzufügen.

Zusammenfassung

Es ist schön, TensorFlow 2.0 zu haben und sowohl vom Graph- als auch vom Eager-Modus profitieren zu können, aber es werden Funktionen erstellt, die zu stark von Python-spezifischen Funktionen abhängen, die nicht den oben genannten Fallstricken entsprechen. Sie können auf einen unerwarteten Fehler treten. Wenn Sie TensorFlow verwenden, verwenden Sie so oft wie möglich von TensorFlow abgeleitete Methoden. Wenn Sie Python-spezifische Funktionen verwenden, sollten Sie das AutoGraph-Verhalten und die Ablaufverfolgung berücksichtigen. Auf der offiziellen Website müssen Sie noch viele andere Dinge beachten und wie Sie diese Verhaltensweisen steuern können. Wenn Sie von nun an Ihr eigenes Modell implementieren und tf.function verwenden müssen, lesen Sie es bitte.

Recommended Posts

Hinweise zur Funktion und Rückverfolgung
Anmerkungen zu * args und ** kargs
Anmerkungen zu Pyenv und Atom
Hinweise zu Python- und Wörterbuchtypen
Hinweise zur Verwendung von Post-Receive und Post-Merge
Hinweise zur Flasche
Hinweise zum Erstellen von Python und Pyenv auf dem Mac
Hinweise zur Installation von Python3 und zur Verwendung von pip unter Windows7
Hinweise zu neuronalen Netzen
Sellerie-Notizen zu Django
Hinweise zur Installation von PycURL
Hinweise zur Verwendung von Alembic
Hinweise zu Funktionen der SciPy.linalg-Familie
Hinweise und Tipps zum vertikalen Verbinden von PySpark DataFrame
Hinweise zur HDR- und RAW-Bildverarbeitung mit Python
Hinweise zum Erstellen von TinyEMU und zum Booten des Linux-Kernels auf Emscripten
Python auf Ruby und wütend Ruby auf Python
Hinweise zur Installation von dlib auf einem Mac
Hinweise zum SQLite3-Modul von Python
Hinweise zum Definieren von PySide-Steckplätzen (2)
[Django] Hinweise zur Verwendung der Django-Debug-Symbolleiste
Aufnahme und Wiedergabe unter Linux
Vorsichtsmaßnahmen beim Definieren von Slots für PySide
[Python] Hinweise zur Datenanalyse
Hinweise zur Optimierung mit Pytorch
Hinweise zur Installation von Python auf Ihrem Mac
Hinweise zur Installation von pipenv auf Ihrem Mac
Hinweise zum Bereitstellen von pyenv mit Homebrew und zum Verwalten von Python-Versionen
Catalina auf Mac und Pyenv
Hinweise zur Installation von Anaconda 3 unter Windows
Hinweise zu imshow () von OpenCV
[Python] Hinweise zu while-Anweisungen (Schreibstil und Endlosschleife)
Hinweise zur Installation von Python unter CentOS
Hinweise zum Lesen und Schreiben von float32 TIFF-Bildern mit Python
Python 3.6 unter Windows ... und zu Xamarin.
Hinweise zur Paketverwaltung mit conda
MQTT auf Raspberry Pi und Mac
Installieren Sie Mecab und mecab-python3 unter Ubuntu 14.04
Installieren Sie Dropbox und führen Sie es unter Ubuntu 20.04 aus
Installieren Sie OpenCV und Chainer unter Ubuntu
Installieren Sie CUDA 8.0 und Chainer unter Ubuntu 16.04
Hinweise zur Verwendung von MeCab aus Python
Hinweise zur Verwendung von Pywinauto
Erstellen und installieren Sie OpenCV unter Windows
Umfrage zum Aufbau und Betrieb von Kivi
Verknüpfen Sie Modelica und Python unter Windows
Hinweise zur Verwendung von featuretools
Für mich: Infrastruktur- und Netzwerknotizen
Hinweise zur Installation von Python mit PyEnv
Installieren Sie Fabric unter Ubuntu und versuchen Sie es
Rohr und Rad in Fenstern beherrschen
Fehlerklassifizierung (python3.x) und Debugging-Hinweise
Hinweise zur Verwendung von rstrip mit Python.
Hinweise zum Zugriff auf dashDB über Python
(Persönliche Notizen) Python-Metaklassen und Metaprogrammierung
Hinweise zur Installation von Homebrew und Pycharm
Hinweise zur Verwendung von matplotlib auf dem Server
Hinweise zum Schreiben von require.txt