Próbowałem oszacować czas prognozy mojego modelu Keras i zdałem sobie sprawę z czegoś dziwnego. Poza tym, że normalnie jest dość szybki, co jakiś czas model potrzebuje dość długo, aby wymyślić prognozę. Co więcej, czasy te również wydłużają się wraz z dłuższym działaniem modelu. Dodałem minimalny działający przykład, aby odtworzyć błąd.
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))
Czas nie zależy od próbki (jest ona wybierana losowo). Jeśli test się powtórzy, wskaźniki w pętli for, w przypadku których przewidywanie trwa dłużej, będą (prawie) takie same.
Używam:
tensorflow 2.0.0
python 3.7.4
W przypadku mojej aplikacji muszę zagwarantować wykonanie w określonym czasie. Jest to jednak niemożliwe, biorąc pod uwagę takie zachowanie. Co idzie nie tak? Czy to błąd w Kerasie czy błąd w backendzie tensorflow?
EDYCJA:
predict_on_batch
pokazuje to samo zachowanie, jednak bardziej rzadkie:
y_pred = model(sample, training=False).numpy()
pokazuje również pewne duże wartości odstające, jednak nie rosną.
EDYCJA 2: Uaktualniłem do najnowszej wersji tensorflow 1 (1.15). Nie tylko problem już nie istnieje, ale znacznie poprawiono „normalny” czas przewidywania! Nie uważam tych dwóch skoków za problematyczne, ponieważ nie pojawiły się, gdy powtórzyłem test (przynajmniej nie przy tych samych wskaźnikach i liniowo rosną) i są procentowe nie tak duże jak na pierwszym wykresie.
Możemy zatem stwierdzić, że wydaje się, że jest to problem nieodłączny od tensorflow 2.0, który wykazuje podobne zachowanie w innych sytuacjach, jak wspomniano w @OverLordGoldDragon.
źródło
predict_on_batch
zamiast tego?y_pred = model(sample).numpy()
zy_pred = model(sample, training=False).numpy()
?predict_classes
wciąż jest najszybszy ... wydaje się. Co powiesz na tylkopredict
?Odpowiedzi:
TF2 ogólnie wykazuje słabe i podobne do błędów zarządzanie pamięcią w kilku przypadkach, które napotkałem - krótki opis tu i tutaj . W szczególności w przypadku prognoz najbardziej wydajną metodą karmienia jest metoda
model(x)
bezpośrednia - patrz tutaj i powiązane dyskusje.W skrócie:
model(x)
działa za pośrednictwem jego ITS__call__
metodą (które dziedziczybase_layer.Layer
), apredict()
,predict_classes()
itp wiązać się specjalną funkcję pętli poprzez_select_training_loop()
; każda z nich wykorzystuje inne metody przetwarzania i przetwarzania danych odpowiednie dla różnych przypadków użycia, amodel(x)
w 2.1 został zaprojektowany specjalnie w celu uzyskania najszybszej wydajności małego modelu / małej partii (i być może dowolnej wielkości) (i wciąż najszybszej w 2.0).Cytując programistę TensorFlow z powiązanych dyskusji:
Uwaga : nie powinno to stanowić problemu w 2.1, a zwłaszcza 2.2 - ale przetestuj każdą metodę. Zdaję sobie również sprawę, że nie odpowiada to bezpośrednio na twoje pytanie dotyczące skoków czasu; Podejrzewam, że ma to związek z mechanizmami buforowania Eager, ale najpewniejszym sposobem na określenie tego jest użycie
TF Profiler
, które jest zepsute w 2.1.Aktualizacja : w związku z rosnącymi skokami, możliwym ograniczeniem GPU; wykonałeś ~ 1000 iterów, zamiast tego spróbuj 10 000 - w końcu wzrost powinien się skończyć. Jak zauważyłeś w swoich komentarzach, nie dzieje się tak z
model(x)
; ma sens, gdy w grę wchodzi jeden krok GPU („konwersja do zestawu danych”).Aktualizacja 2 : możesz napotkać tutaj błąd deweloperów , jeśli napotkasz ten problem; głównie śpiewam tam
źródło
Chociaż nie potrafię wyjaśnić niespójności w czasie wykonywania, mogę zalecić, aby spróbować przekonwertować model na TensorFlow Lite, aby przyspieszyć przewidywania dotyczące pojedynczych rekordów danych lub małych partii.
Przeprowadziłem test porównawczy dla tego modelu:
Czasy prognoz dla pojedynczych rekordów były następujące:
model.predict(input)
: 18msmodel(input)
: 1,3 msCzas konwersji modelu wynosił 2 sekundy.
Poniższa klasa pokazuje, jak przekonwertować i korzystać z modelu oraz zapewnia
predict
metodę podobną do modelu Keras. Należy pamiętać, że należy go zmodyfikować w celu użycia z modelami, które nie mają tylko jednego wejścia 1-D i jednego wyjścia 1-D.Pełny kod testu i wykres można znaleźć tutaj: https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
źródło