[PYTHON] Experiment zur Optimierung der Tensorflow-Daten

Einführung

Better performance with the tf.data API Ich habe den Datenlader für CNN unter Bezugnahme auf die obige Seite entworfen und die Geschwindigkeit des Datenladers in Tensorflow angepasst. Zusammenfassend habe ich einige Beschleunigungstechniken ausprobiert, aber leider konnte ich nicht schneller als die Basisimplementierung werden.

tf.data Tensorflow bietet eine API für die Eingabepipeline mit dem Namen tf.data. Beim Laden von Daten, die nicht in den Arbeitsspeicher passen, z. B. eine Bilddatei, in das Modell können tf.data verwendet werden, um eine Hochgeschwindigkeitsverarbeitung zu erreichen, da Datenvorverarbeitung und NN-Training intern parallel durchgeführt werden. Der grobe Mechanismus ist wie folgt.

pipeline_performance.png

Wenn Sie es mit Python Generator usw. implementieren, ist es ineffizient, da das andere während der Ausführung der CPU oder GPU im Leerlauf ist. Wenn Sie es jedoch mit tf.data implementieren, können Sie die Leerlaufzeit verkürzen. Wird sein.

Die Implementierung wird unter hier erläutert und kann mit relativ geringem Aufwand implementiert werden.

Problemstellung

Das Bild von ImageNet wird in JPEG gespeichert und in Mobilet geladen. Die experimentelle Umgebung ist Google Colaboratory.

Basisimplementierung

Einführung Grundlegende Verwendung von tf.data. Lesen Sie die Pfade der gespeicherten Bilder nacheinander und schneiden Sie sie zufällig in ein 244x244-Bild zu.


train_img_paths = glob.glob(os.path.join(IMAGE_DIR, '*.jpg'))
train_img_paths.sort()

num_train_imgs = len(train_img_paths)
train_label = [1 for path in train_img_paths]

m = tf.keras.Sequential([
    hub.KerasLayer("https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/4", output_shape=[1], trainable=True)
])
m.build([None, IMAGE_SIZE[0], IMAGE_SIZE[1], IMAGE_SIZE[2]])
m.compile(loss=tf.keras.losses.BinaryCrossentropy(), optimizer='Adam')

def preprocessing(img_path, label):
  img = tf.image.decode_image(tf.io.read_file(img_path))
  img = tf.image.random_crop(img, size=IMAGE_SIZE)
  img = tf.cast(img, tf.float32)
  img = img / 255.0
  label = tf.cast(label, tf.float32)
  img.set_shape(IMAGE_SIZE)
  return img, label

train_data = tf.data.Dataset.from_tensor_slices((train_img_paths, train_label))
train_data = train_data.shuffle(num_train_imgs).map(preprocessing).repeat().batch(batch_size).prefetch(buffer_size=AUTOTUNE)

time_start = time.time()
m.fit(train_data, epochs=epochs, steps_per_epoch=steps_per_epoch)

time_end = time.time()

print(f'Total time:{(time_end-time_start)/60.0:.3f}[min]')
print(f'Time per step:{(time_end-time_start)/steps_per_epoch*epochs:.3f} [sec]')

Ergebnis

Total time:0.446[min]
Time per step:0.803 [sec]

Es dauerte ungefähr 0,8 Sekunden pro Schritt. Von hier aus werde ich Wege finden, um das Lernen zu beschleunigen.

Parallele Zuordnung

Führen Sie die Kartenfunktion des Dataset-Objekts parallel aus. Dies sollte schnell gehen, da der Datenextraktionsteil in mehreren Prozessen verarbeitet wird.

Quellcode

Im vorherigen Abschnitt

train_data = tf.data.Dataset.from_tensor_slices((train_img_paths, train_label))
train_data = train_data.shuffle(num_train_imgs).map(preprocessing).repeat().batch(batch_size).prefetch(buffer_size=AUTOTUNE)

Schreiben Sie den Teil wie folgt um.

train_data = tf.data.Dataset.from_tensor_slices((train_img_paths, train_label))
train_data = train_data.shuffle(num_train_imgs).repeat().map(preprocessing, num_parallel_calls=AUTOTUNE).batch(batch_size).prefetch(buffer_size=AUTOTUNE)

Ergebnis

Total time:3.726[min]
Time per step:6.707 [sec]

Aus irgendeinem Grund ist es spät gewesen. Ist es eine Spezifikation von Google Colaboratory? (Untersuchung erforderlich)

Caching

Quellcode

Caching ist eine Funktion, die die gelesenen Daten vorübergehend im RAM oder im Speicher hält.

train_data = tf.data.Dataset.from_tensor_slices((train_img_paths, train_label))
train_data = train_data.shuffle(num_train_imgs).repeat().map(preprocessing, num_parallel_calls=AUTOTUNE).batch(batch_size).cache()

Ergebnis

Total time:7.014[min]
Time per step:12.625 [sec]

Wieder einmal konnten wir es nicht beschleunigen. Ich denke, die Ursache ist, dass die Kartenfunktion so konzipiert ist, dass sie das Bild liest und gleichzeitig die Bilddaten konvertiert. Sie benötigen eine Struktur, die das Lesen von Bildern und die Konvertierung von Bilddaten voneinander trennt. (Zukünftige Aufgaben)

Vektorisierte Zuordnung

Die benutzerdefinierte Kartenfunktion scheint aus Verarbeitungsgründen mit Overhead verbunden zu sein. Daher scheint es schneller zu sein, wenn die benutzerdefinierte Kartenfunktion vektorisiert wird, dh die Eingabe sofort verarbeitet wird. Insbesondere wird empfohlen, durch Stapelverarbeitung → Datenkonvertierung anstelle von Datenkonvertierung → Stapelverarbeitung zu implementieren.

Ich konnte aus Zeitgründen noch nicht experimentieren, aber im Experiment mit der am Anfang des Artikels angegebenen URL ist es bis zu 30-mal schneller.

Zusammenfassung

Ich habe mit Parallelisierung und Caching der Kartenfunktion experimentiert, aber keine davon führte zu einer Beschleunigung.

Ich denke, es gibt mehrere Ursachen, daher ist es notwendig, in Zukunft nachzuforschen. Wenn Sie einen Rat haben, wäre ich Ihnen dankbar, wenn Sie mich wissen lassen könnten.

Recommended Posts

Experiment zur Optimierung der Tensorflow-Daten
Tensorflow / Keras-Zusammenfassung
Daten mit TensorFlow lesen
Vorverarbeitung von Präfekturdaten
Auswahl der Messdaten
TensorFlow Tutorial-MNIST Daten herunterladen (Übersetzung)
Tensorflows praktische Bibliothek TF-Slim
Deep Running 2 Tuning von Deep Learning
Visualisierung von Daten nach Präfektur
Fourier-Transformation von Rohdaten
Durchschnittliche Schätzung der begrenzten Daten
Über die Datenverwaltung von Amboss-App-Server
Wahrscheinlichkeitsvorhersage von unausgeglichenen Daten
Installieren Sie eine ältere Version von Tensorflow
Experimentelle Datenanpassung (Python) wird hinzugefügt ...
Zusammenfassung verschiedener Operationen in Tensorflow
Keras als Wrapper von Theano & TensorFlow
Speichersparende Matrixkonvertierung von Protokolldaten
TensorFlow Tutorial-Vektordarstellung von Wörtern (Übersetzung)
Differenzierung von Zeitreihendaten (diskret)
10 Auswahlen der Datenextraktion durch pandas.DataFrame.query
Animation von Geodaten durch Geopandas
Empfehlung zur Datenanalyse mit MessagePack
Zeitreihenanalyse 3 Vorverarbeitung von Zeitreihendaten
Versuchen Sie Daten parallel zu Distributed TensorFlow
Datenverarbeitung 2 Analyse verschiedener Datenformate