Ich versuchte eine Schätzung der Vorhersagezeit meines Keras-Modells zu erhalten und erkannte etwas Seltsames. Abgesehen davon, dass das Modell normalerweise ziemlich schnell ist, braucht es von Zeit zu Zeit ziemlich lange, um eine Vorhersage zu treffen. Und nicht nur das, diese Zeiten verlängern sich auch, je länger das Modell läuft. Ich habe ein minimales Arbeitsbeispiel hinzugefügt, um den Fehler zu reproduzieren.
import time
import numpy as np
from sklearn.datasets import make_classification
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
# Make a dummy classification problem
X, y = make_classification()
# Make a dummy model
model = Sequential()
model.add(Dense(10, activation='relu',name='input',input_shape=(X.shape[1],)))
model.add(Dense(2, activation='softmax',name='predictions'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X, y, verbose=0, batch_size=20, epochs=100)
for i in range(1000):
# Pick a random sample
sample = np.expand_dims(X[np.random.randint(99), :], axis=0)
# Record the prediction time 10x and then take the average
start = time.time()
for j in range(10):
y_pred = model.predict_classes(sample)
end = time.time()
print('%d, %0.7f' % (i, (end-start)/10))
Die Zeit hängt nicht von der Probe ab (sie wird zufällig ausgewählt). Wenn der Test wiederholt wird, sind die Indizes in der for-Schleife, in denen die Vorhersage länger dauert, wieder (fast) gleich.
Ich benutze:
tensorflow 2.0.0
python 3.7.4
Für meine Bewerbung muss ich die Ausführung in einer bestimmten Zeit garantieren. Dies ist jedoch angesichts dieses Verhaltens unmöglich. Was läuft falsch? Ist es ein Fehler in Keras oder ein Fehler im Tensorflow-Backend?
EDIT:
predict_on_batch
zeigt das gleiche Verhalten, jedoch spärlicher:
y_pred = model(sample, training=False).numpy()
zeigt auch einige starke Ausreißer, die jedoch nicht zunehmen.
EDIT 2: Ich habe auf die neueste Version von Tensorflow 1 (1.15) heruntergestuft. Das Problem besteht nicht nur nicht mehr, auch die "normale" Vorhersagezeit hat sich deutlich verbessert! Ich sehe die beiden Spitzen nicht als problematisch an, da sie bei Wiederholung des Tests nicht aufgetreten sind (zumindest nicht bei denselben Indizes und linear ansteigend) und prozentual nicht so groß sind wie im ersten Diagramm.
Wir können daher den Schluss ziehen, dass dies ein dem Tensorflow 2.0 innewohnendes Problem zu sein scheint, das in anderen Situationen ein ähnliches Verhalten zeigt, wie es @OverLordGoldDragon erwähnt.
quelle
predict_on_batch
stattdessen versuchen ?y_pred = model(sample).numpy()
und mity_pred = model(sample, training=False).numpy()
?predict_classes
aber immer noch der schnellste .... es scheint. Was ist mit nurpredict
?Antworten:
TF2 weist in einigen Fällen, auf die ich gestoßen bin, im Allgemeinen eine schlechte und fehlerhafte Speicherverwaltung auf - kurze Beschreibung hier und hier . Insbesondere bei der Vorhersage erfolgt die leistungsfähigste Fütterungsmethode
model(x)
direkt über - siehe hier und die damit verbundenen Diskussionen.In Kürze:
model(x)
wirkt über seine ihre__call__
Methode (die es erbtbase_layer.Layer
), wohingegenpredict()
,predict_classes()
usw. beinhaltet eine spezielle Schleifenfunktion über_select_training_loop()
; Jedes verwendet unterschiedliche Datenvor- und -nachbearbeitungsmethoden, die für unterschiedliche Anwendungsfälle geeignet sind, und wurdemodel(x)
in 2.1 speziell entwickelt, um die schnellste Leistung bei kleinen Modellen / kleinen Chargen (und möglicherweise bei jeder Größe) zu erzielen (und in 2.0 immer noch die schnellste).Zitieren eines TensorFlow- Entwicklers aus verknüpften Diskussionen:
Hinweis : Dies sollte in 2.1 und insbesondere in 2.2 weniger problematisch sein - testen Sie jedoch jede Methode trotzdem. Mir ist auch klar, dass dies Ihre Frage zu den Zeitspitzen nicht direkt beantwortet. Ich vermute, dass es mit Eager-Caching-Mechanismen zusammenhängt, aber der sicherste Weg, dies festzustellen, ist via
TF Profiler
, das in 2.1 unterbrochen ist .Update : in Bezug auf zunehmende Spitzen, mögliche GPU-Drosselung; Sie haben ~ 1000 Iter gemacht, versuchen Sie stattdessen 10.000 - schließlich sollte die Zunahme aufhören. Wie Sie in Ihren Kommentaren festgestellt haben, tritt dies bei nicht auf
model(x)
. Dies ist sinnvoll, da ein GPU-Schritt weniger erforderlich ist ("Konvertierung in einen Datensatz").Update2 : Sie könnten die Entwickler hier darüber nerven , wenn Sie auf dieses Problem stoßen . Ich singe hauptsächlich dort
quelle
Obwohl ich die Inkonsistenzen in der Ausführungszeit nicht erklären kann, kann ich empfehlen, dass Sie versuchen, Ihr Modell in TensorFlow Lite zu konvertieren, um Vorhersagen für einzelne Datensätze oder kleine Stapel zu beschleunigen.
Ich habe einen Benchmark für dieses Modell durchgeführt:
Die Vorhersagezeiten für einzelne Datensätze waren:
model.predict(input)
: 18 msmodel(input)
: 1,3 msDie Zeit zum Umrüsten des Modells betrug 2 Sekunden.
Die folgende Klasse zeigt, wie das Modell konvertiert und verwendet wird, und bietet eine
predict
Methode wie das Keras-Modell. Beachten Sie, dass es für die Verwendung mit Modellen geändert werden muss, die nicht nur einen einzelnen 1-D-Eingang und einen einzelnen 1-D-Ausgang haben.Den vollständigen Benchmark-Code und ein Diagramm finden Sie hier: https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
quelle