Я попытался получить оценку времени предсказания моей модели керас и понял что-то странное. Помимо того, что обычно достаточно быстро, время от времени модели требуется довольно много времени, чтобы составить прогноз. И не только это, эти времена также увеличиваются, чем дольше модель работает. Я добавил минимальный рабочий пример, чтобы воспроизвести ошибку.
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))
Время не зависит от образца (оно выбирается случайным образом). Если тест повторяется, индексы в цикле for, где прогнозирование занимает больше времени, будут (почти) снова такими же.
Я использую:
tensorflow 2.0.0
python 3.7.4
Для моего заявления мне нужно гарантировать исполнение в определенное время. Это, однако, невозможно, учитывая такое поведение. Что не так? Это ошибка в Keras или ошибка в бэкэнде tenorflow?
РЕДАКТИРОВАТЬ:
predict_on_batch
показывает то же поведение, однако, более разреженный:
y_pred = model(sample, training=False).numpy()
также показывает некоторые сильные выбросы, но они не увеличиваются.
РЕДАКТИРОВАТЬ 2: Я понизил до последней версии TenorFlow 1 (1.15). Мало того, что проблема больше не существует, также значительно улучшилось «нормальное» время прогнозирования! Я не считаю эти два всплеска проблематичными, так как они не появлялись, когда я повторял тест (по крайней мере, не с теми же показателями и линейно увеличивающимися), и в процентах они не такие большие, как на первом графике.
Таким образом, мы можем сделать вывод, что это, похоже, проблема, присущая tenorflow 2.0, который демонстрирует поведение, подобное в других ситуациях, как упоминает @OverLordGoldDragon.
predict_on_batch
вместо этого?y_pred = model(sample).numpy()
и сy_pred = model(sample, training=False).numpy()
?predict_classes
все еще самый быстрый .... кажется. Как насчет простоpredict
?Ответы:
В некоторых случаях TF2 демонстрирует плохое и ошибочное управление памятью - краткое описание здесь и здесь . В частности, с помощью прогнозирования, наиболее эффективный метод кормления - это
model(x)
прямой способ - см. Здесь и связанные с ним обсуждения.В двух словах:
model(x)
действует через свой__call__
метод (который он наследует отbase_layer.Layer
), тогда какpredict()
,predict_classes()
и т. Д. Задействует специальную функцию цикла via_select_training_loop()
; каждый из них использует разные методы предварительной и последующей обработки данных, подходящие для разных вариантов использования, иmodel(x)
в 2.1 был разработан специально для обеспечения максимальной производительности для малых моделей / небольших партий (и, возможно, любого размера) (и при этом все еще быстрее в 2.0).Цитирую разработчика TensorFlow из связанных обсуждений:
Примечание : это должно быть менее проблематично в 2.1, и особенно в 2.2, но все равно тестируйте каждый метод. Также я понимаю, что это не дает прямого ответа на ваш вопрос о скачках времени; Я подозреваю, что это связано с механизмами кэширования Eager, но самый надежный способ определить это через
TF Profiler
, которая сломана в 2.1.Обновить : относительно увеличения пиков, возможного дросселирования графического процессора; вы сделали ~ 1000 итеров, попробуйте вместо 10 000 - в конце концов, рост должен прекратиться. Как вы отметили в ваших комментариях, это не происходит с
model(x)
; имеет смысл, так как задействован еще один шаг графического процессора («преобразование в набор данных»).Update2 : вы могли бы ошибка в УБС здесь об этом , если вы сталкиваетесь этот вопрос; это в основном я пою там
источник
Хотя я не могу объяснить несоответствия во времени выполнения, я могу рекомендовать вам попытаться преобразовать вашу модель в TensorFlow Lite, чтобы ускорить прогнозирование для отдельных записей данных или небольших пакетов.
Я провел тест на этой модели:
Время прогнозирования для отдельных записей было:
model.predict(input)
: 18 мсmodel(input)
: 1,3 мсВремя на конвертацию модели составило 2 секунды.
Класс ниже показывает, как преобразовать и использовать модель, и предоставляет
predict
метод, подобный модели Keras. Обратите внимание, что его необходимо модифицировать для использования с моделями, которые не имеют только один 1-D вход и 1-D выход.Полный код теста и график можно найти здесь: https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
источник