J'ai essayé d'obtenir une estimation du temps de prédiction de mon modèle de kéros et j'ai réalisé quelque chose d'étrange. En plus d'être assez rapide normalement, le modèle a besoin de temps en temps pour établir une prédiction. Et non seulement cela, ces temps augmentent également plus le modèle fonctionne. J'ai ajouté un exemple de travail minimal pour reproduire l'erreur.
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))
Le temps ne dépend pas de l'échantillon (il est prélevé au hasard). Si le test est répété, les indices de la boucle for où la prédiction prend plus de temps seront à nouveau (presque) les mêmes.
J'utilise:
tensorflow 2.0.0
python 3.7.4
Pour ma candidature, je dois garantir l'exécution dans un certain temps. Ceci est cependant impossible compte tenu de ce comportement. Qu'est-ce qui ne va pas? Est-ce un bug dans Keras ou un bug dans le backend tensorflow?
EDIT:
predict_on_batch
montre le même comportement, cependant, plus clairsemé:
y_pred = model(sample, training=False).numpy()
montre également de fortes valeurs aberrantes, mais elles n'augmentent pas.
EDIT 2: J'ai rétrogradé à la dernière version de tensorflow 1 (1.15). Non seulement le problème n'existe plus, mais le temps de prédiction "normal" s'est considérablement amélioré! Je ne vois pas les deux pointes comme problématiques, car elles ne sont pas apparues lorsque j'ai répété le test (du moins pas aux mêmes indices et en augmentant linéairement) et sont en pourcentage pas aussi grandes que dans le premier graphique.
Nous pouvons donc conclure que cela semble être un problème inhérent à tensorflow 2.0, qui montre un comportement similaire dans d'autres situations comme le mentionne @OverLordGoldDragon.
predict_on_batch
place?y_pred = model(sample).numpy()
et avecy_pred = model(sample, training=False).numpy()
?predict_classes
c'est toujours le plus rapide ... semble-t-il. Et justepredict
?Réponses:
TF2 présente généralement une gestion de la mémoire médiocre et semblable à un bogue dans plusieurs cas que j'ai rencontrés - brève description ici et ici . Avec la prédiction en particulier, la méthode d'alimentation la plus performante est via
model(x)
directement - voir ici , et ses discussions liées.En bref:
model(x)
agit par son son__call__
procédé (qui hérite debase_layer.Layer
), tandis quepredict()
,predict_classes()
etc. associer une fonction de boucle via dédié_select_training_loop()
; chacun utilise différentes méthodes de pré et post-traitement de données adaptées à différents cas d'utilisation, etmodel(x)
en 2.1 a été conçu spécifiquement pour fournir des performances plus rapides pour les petits modèles / petits lots (et peut-être n'importe quelle taille) (et toujours les plus rapides en 2.0).Citant un développeur TensorFlow à partir de discussions liées:
Remarque : cela devrait être moins un problème en 2.1, et en particulier en 2.2 - mais testez quand même chaque méthode. Je me rends également compte que cela ne répond pas directement à votre question sur les pics de temps; Je soupçonne que cela est lié aux mécanismes de mise en cache Désireux, mais le moyen le plus sûr de le déterminer est via
TF Profiler
, qui est cassé en 2.1.Mise à jour : concernant l' augmentation des pics, limitation possible du GPU; vous avez fait environ 1 000 itérations, essayez 10 000 à la place - finalement, l'augmentation devrait cesser. Comme vous l'avez noté dans vos commentaires, cela ne se produit pas avec
model(x)
; est logique car une étape GPU en moins est impliquée ("conversion en ensemble de données").Mise à jour2 : vous pouvez ici bugner les développeurs si vous rencontrez ce problème; c'est surtout moi qui chante là-bas
la source
Bien que je ne puisse pas expliquer les incohérences dans le temps d'exécution, je peux vous recommander d'essayer de convertir votre modèle en TensorFlow Lite pour accélérer les prédictions sur des enregistrements de données uniques ou de petits lots.
J'ai réalisé un benchmark sur ce modèle:
Les temps de prédiction pour les enregistrements uniques étaient les suivants:
model.predict(input)
: 18msmodel(input)
: 1,3 msLe temps de conversion du modèle était de 2 secondes.
La classe ci-dessous montre comment convertir et utiliser le modèle et fournit une
predict
méthode comme le modèle Keras. Notez qu'il devrait être modifié pour être utilisé avec des modèles qui n'ont pas seulement une seule entrée 1D et une seule sortie 1D.Le code de référence complet et un graphique peuvent être trouvés ici: https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
la source