[PYTHON] Da ImageDataGenerator nicht mehr verwendet werden kann, eine Geschichte zum Erstellen einer Datenerweiterungsklasse für Tensorflow> = 2.0

Hintergrund

In Tensorflow wurde der ImageDataGenerator von Keras häufig zum Erweitern von Bilddaten verwendet. Dies wurde häufig verwendet, da Sie damit das Tensorflow-Modell trainieren können, während Sie in einem Mehrfachprozess verschiedene Datenerweiterungen auf das Eingabebild anwenden.

Da die Mehrfachverarbeitung seit Tensorflow 2.0 veraltet ist, stoppt der Fortschrittsbalken beim Lernen mit Tensorflow beim Erweitern von Daten durch Mehrprozessverarbeitung, ohne plötzlich einen Fehler auszulösen. Besonders schmerzhaft ist, dass Sie keine Fehler erhalten. Wenn Sie also einen Dienst nutzen, der Ihnen stündlich Gebühren berechnet, verschwenden Sie Geld, obwohl Sie nicht lernen ...

Ich habe einen Generator verwendet, der beim Lesen aus einer HDF5-Datei lernt, die in mehrere Dateien unterteilt und in mehreren Prozessen geschrieben wurde. Selbst bei Tensorflow <2.0 konnte das Lernen bei Verwendung von Multiprocessing in etwa 2 Tagen beendet werden. Nach Tensorflow> = 2,0 hörte es noch häufiger auf, beispielsweise für etwa 2 Stunden.

Deshalb...

Wie ImageDataGenerator haben wir eine Klasse erstellt, die mit Tensorflow leicht </ strong> erlernt werden kann, während verschiedene Datenerweiterungen in einem Multiprozess auf Bilder angewendet werden.

Politik

Die empfohlene Dateneingabemethode für Tensorflow ist die Verwendung von tensorflow.data.Dataset (im Folgenden als tf.data.Dataset bezeichnet). Auf diese Weise ist es möglich, eine Hochgeschwindigkeits- und Mehrprozess-Dateneingabeverarbeitung zu erstellen, wie beispielsweise in hier erwähnt. Werden. Tf.data enthält jedoch nicht viele Informationen zum Stapelüberlauf usw., und obwohl es eine Schrift gibt, die anscheinend jede Datenerweiterung versucht, lernt sie, während verschiedene Daten wie ImageDataGenerator problemlos auf das Eingabebild erweitert werden Ich konnte keinen Weg finden, es zu tun ...

Sie können tf.data verwenden, um eine schnelle Dateneingabeverarbeitung zu erstellen. Die offizielle Dokumentation zeigt jedoch einige Fallstricke.

1. tf.data.Dataset.from_generator erweitert Daten nicht in mehreren Prozessen

Sie können tf.data.Dataset.from_generator verwenden, um einen Python-Generator zu verpacken und ihn mit der Funktion fit () als tf.data zu trainieren. Wickeln Sie zuerst ImageDataGenerator mit dieser Funktion ein! Ich dachte leicht. Im offiziellen Dokument, Hinweis von from_generator, ist jedoch die folgende Beschreibung enthalten.

Note: The current implementation of Dataset.from_generator() uses tf.numpy_function and inherits the same constraints. In particular, it requires the Dataset- and Iterator-related operations to be placed on a device in the same process as the Python program that called Dataset.from_generator(). The body of generator will not be serialized in a GraphDef, and you should not use this method if you need to serialize your model and restore it in a different environment.

Durch die Verwendung von tf.numpy_function habe ich aufgegeben, weil es keine Multiprozesse unterstützt.

2. Implementieren Sie mit tf nur so viel wie möglich

Es ist in offizielles Dokument tf.function beschrieben, aber wenn Sie es aus Leistungsgründen in @ tf.function decorator einschließen, lautet der gesamte Code tf Wird automatisch in den Code von konvertiert. Wenn Sie zu diesem Zeitpunkt eine externe Bibliothek oder Numpy verwenden, werden Sie in tf.numpy_function, tf.py_func usw. eingeschlossen und haben dieselben Einschränkungen wie in 1. Daher habe ich versucht, den Typ tf.Tensor so weit wie möglich für die Verarbeitung und den Datentyp zu verwenden, und selbst wenn dies nicht der Fall war, habe ich versucht, nur den Python-Standardtyp zu verwenden.

3. Erweitern Sie gleichzeitig das Etikettenbild

Wenn das Eingabebild wie durch Drehen transformiert wird, muss das Bild, aus dem das Etikett stammt, genauso transformiert werden? Ich habe versucht, genau die gleichen Transformationen auf das (optionale) Beschriftungsbild anzuwenden wie auf das Eingabebild.

Wie installiert man

python -m pip install git+https://github.com/piyop/tfaug

Wie benutzt man

1. Initialisierung

from tfaug import augment_img 
#set your augment parameters below:
arg_fun = augment_img(rotation=0, 
                      standardize=False,
                      random_flip_left_right=True,
                      random_flip_up_down=True, 
                      random_shift=(.1,.1), 
                      random_zoom=.1,
                      random_brightness=.2,
                      random_saturation=None,
                      training=True) 
                      
"""
augment_img.__init__() setting up the parameters for augmantation.

Parameters
----------
rotation : float, optional
    rotation angle(degree). The default is 0.
standardize : bool, optional
    image standardization. The default is True.
random_flip_left_right : bool, optional
    The default is False.
random_flip_up_down : bool, optional
    The default is False.
random_shift : Tuple[float, float], optional
    random shift images.
    vartical direction (-list[0], list[0])
    holizontal direction  (-list[1], list[1])
    Each values shows ratio of image size.
    The default is None.
random_zoom : float, optional
    random zoom range -random_zoom to random_zoom.
    value of random_zoom is ratio of image size
    The default is None.
random_brightness : float, optional
    randomely adjust image brightness range 
    [-max_delta, max_delta). 
     The default is None.
random_saturation : Tuple[float, float], optional
    randomely adjust image brightness range between [lower, upper]. 
    The default is None.
training : bool, optional
    If false, this class don't augment image except standardize. 
    The default is False.
Returns
-------
class instance : Callable[[tf.Tensor, tf.Tensor, bool], Tuple[tf.Tensor,tf.Tensor]]
"""                     

2. Wird in tf.data.Dataset.map () verwendet.

ds=tf.data.Dataset.zip((tf.data.Dataset.from_tensor_slices(image),
                      tf.data.Dataset.from_tensor_slices(label))) \
                    .shuffle(BATCH_SIZE*10).batch(BATCH_SIZE)\
                    .map(arg_fun, num_parallel_calls=tf.data.experimental.AUTOTUNE)
model.fit(ds)

Ein detailliertes Verwendungsbeispiel finden Sie im Test. (https://github.com/piyop/tfaug)

Recommended Posts

Da ImageDataGenerator nicht mehr verwendet werden kann, eine Geschichte zum Erstellen einer Datenerweiterungsklasse für Tensorflow> = 2.0
Bei der Entwicklung mit Ipython kann Scrapy nicht mehr gelesen werden
[2015.02.22] Youtube-dl wurde aktualisiert und kann in früheren Versionen nicht mehr verwendet werden.
Der Jupiter-Notebook-Kernel kann keine Verbindung mehr herstellen
Die Sonnenfinsternis beginnt nicht mehr.
Da ImageDataGenerator nicht mehr verwendet werden kann, eine Geschichte zum Erstellen einer Datenerweiterungsklasse für Tensorflow> = 2.0
Was tun, wenn Linux VLC nicht mehr rotieren kann?
Kann ich Datenwissenschaftler werden?
Ich habe es gemacht, weil ich JSON-Daten möchte, die in Demos und Prototypen frei verwendet werden können
Ich habe eine generische Python-Projektvorlage erstellt
[Atcoder] [C ++] Ich habe ein Testautomatisierungstool erstellt, das während des Wettbewerbs verwendet werden kann
Ich habe ein Tool erstellt, um automatisch ein Zustandsübergangsdiagramm zu generieren, das sowohl für die Webentwicklung als auch für die Anwendungsentwicklung verwendet werden kann
Ich habe ein Shuffle gemacht, das mit Python zurückgesetzt (zurückgesetzt) werden kann
[Python] Ich habe eine Klasse erstellt, die schnell einen Dateibaum schreiben kann
Ich habe einen Tri-Tree geschrieben, der für die Implementierung von Hochgeschwindigkeitswörterbüchern in D-Sprache und Python verwendet werden kann
[Ver1.3.1 Update] Ich habe DataLiner erstellt, eine Datenvorverarbeitungsbibliothek für maschinelles Lernen.
Ich habe einen einfachen Timer erstellt, der vom Terminal aus gestartet werden kann
Ich habe ein Dash-Docset für Holoviews erstellt
Ich habe eine Bibliothek für versicherungsmathematische Versicherungen erstellt
Klasse für PYTHON, die ohne Kenntnis von LDAP betrieben werden kann
[2015.02.22] Youtube-dl wurde aktualisiert und kann in früheren Versionen nicht mehr verwendet werden.
Ich habe eine Python-Wörterbuchdatei für Neocomplete erstellt
Ich habe ein nützliches Tool für Digital Ocean erstellt
Ich habe einen Downloader für wortverteilte Ausdrücke erstellt
Wir haben ein Peeping-Prevention-Produkt für die Telearbeit entwickelt.
Mit Raspberry Pi erstellter Dateifreigabeserver, der für Remote-Arbeiten verwendet werden kann