Saya mencoba mendapatkan perkiraan waktu prediksi model keras saya dan menyadari sesuatu yang aneh. Terlepas dari menjadi cukup cepat secara normal, sesekali model membutuhkan waktu yang cukup lama untuk menghasilkan prediksi. Dan tidak hanya itu, saat-saat itu juga meningkatkan semakin lama model berjalan. Saya menambahkan contoh kerja minimal untuk mereproduksi kesalahan.
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))
Waktu tidak tergantung pada sampel (dipilih secara acak). Jika tes diulangi, indeks dalam for loop tempat prediksi membutuhkan waktu lebih lama akan (hampir) sama lagi.
Saya menggunakan:
tensorflow 2.0.0
python 3.7.4
Untuk aplikasi saya, saya perlu menjamin eksekusi dalam waktu tertentu. Namun ini tidak mungkin mengingat perilaku itu. Apa yang salah? Apakah itu bug di Keras atau bug di backend tensorflow?
EDIT:
predict_on_batch
menunjukkan perilaku yang sama, namun lebih jarang:
y_pred = model(sample, training=False).numpy()
menunjukkan beberapa outlier berat juga, namun, mereka tidak meningkat.
EDIT 2: Saya diturunkan ke versi tensorflow 1 terbaru (1.15). Tidak hanya masalahnya tidak ada lagi, juga waktu prediksi "normal" meningkat secara signifikan! Saya tidak melihat kedua paku sebagai masalah, karena mereka tidak muncul ketika saya mengulangi tes (setidaknya tidak pada indeks yang sama dan meningkat secara linear) dan persentasi tidak sebesar seperti pada plot pertama.
Dengan demikian kita dapat menyimpulkan bahwa ini tampaknya menjadi masalah yang melekat pada tensorflow 2.0, yang menunjukkan perilaku serupa dalam situasi lain seperti yang disebutkan @OverLordGoldDragon.
sumber
predict_on_batch
?y_pred = model(sample).numpy()
dan dengany_pred = model(sample, training=False).numpy()
?predict_classes
tetap saja yang tercepat .... sepertinya. Bagaimana dengan adilpredict
?Jawaban:
TF2 umumnya menunjukkan manajemen memori yang buruk dan seperti bug dalam beberapa kasus yang saya temui - deskripsi singkat di sini dan di sini . Dengan prediksi pada khususnya, metode pemberian makan yang paling berkinerja adalah melalui
model(x)
langsung - lihat di sini , dan diskusi terkait.Singkatnya:
model(x)
bertindak melalui nya nya__call__
metode (yang mewarisi daribase_layer.Layer
), sedangkanpredict()
,predict_classes()
, dll melibatkan fungsi loop dedicated via_select_training_loop()
; masing-masing menggunakan metode pra-dan pasca-pemrosesan data yang berbeda yang cocok untuk berbagai kasus penggunaan, danmodel(x)
pada 2.1 dirancang khusus untuk menghasilkan kinerja model-kecil / batch-kecil tercepat (dan mungkin ukuran apa saja) (dan masih tercepat di 2.0).Mengutip seorang pengembang TensorFlow dari diskusi terkait:
Catatan : ini seharusnya tidak terlalu menjadi masalah di 2.1, dan terutama 2.2 - tetapi tetap uji setiap metode. Saya juga menyadari ini tidak langsung menjawab pertanyaan Anda tentang lonjakan waktu; Saya menduga itu terkait dengan mekanisme caching Eager, tetapi cara paling pasti untuk menentukan adalah melalui
TF Profiler
, yang rusak di 2.1.Pembaruan : terkait peningkatan lonjakan, kemungkinan pelambatan GPU; Anda sudah melakukan ~ 1000 iters, coba 10.000 sebagai gantinya - akhirnya, peningkatan akan berhenti. Seperti yang Anda catat dalam komentar Anda, ini tidak terjadi dengan
model(x)
; masuk akal karena satu langkah GPU lebih sedikit terlibat ("konversi ke dataset").Update2 : Anda bisa bug devs di sini tentang hal itu jika Anda menghadapi masalah ini; kebanyakan saya bernyanyi di sana
sumber
Meskipun saya tidak dapat menjelaskan ketidakkonsistenan dalam waktu eksekusi, saya dapat merekomendasikan agar Anda mencoba mengubah model Anda menjadi TensorFlow Lite untuk mempercepat prediksi pada catatan data tunggal atau batch kecil.
Saya menjalankan tolok ukur pada model ini:
Waktu prediksi untuk catatan tunggal adalah:
model.predict(input)
: 18msmodel(input)
: 1.3msWaktu untuk mengonversi model adalah 2 detik.
Kelas di bawah ini menunjukkan cara mengkonversi dan menggunakan model dan menyediakan
predict
metode seperti model Keras. Perhatikan bahwa itu perlu dimodifikasi untuk digunakan dengan model yang tidak hanya memiliki input 1-D tunggal dan output 1-D tunggal.Kode benchmark lengkap dan plot dapat ditemukan di sini: https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
sumber