GÜNCELLEME - 1/15/2020 : küçük parti boyutları için mevcut en iyi uygulama, girdileri modele doğrudan beslemek olmalıdır - yani preds = model(x)
, katmanlar tren / çıkarımda farklı davranıyorsa model(x, training=False)
. Son işlem başına, bu artık belgelenmiştir .
Bunları karşılaştırmadım, ancak Git tartışmasına göre , predict_on_batch()
özellikle TF 2.1'deki iyileştirmelerle de denemeye değer .
SON Suçlu : self._experimental_run_tf_function = True
. Bu var deneysel . Ama aslında kötü değil.
Herhangi bir TensorFlow geliştirici okumasına: kodunuzu temizleyin . Bu bir karmaşa. Ve bir işlev bir şey yapar gibi önemli kodlama uygulamalarını ihlal eder ; "işlem girdileri" den çok daha fazlasını _process_inputs
yapar . "Yeterince maaş almıyorum" - ama sen bunu kendi eşyalarını anlamak harcanan uzatmalarda, ödeme ve böcek ile Sorunlar sayfasına dolum kullanıcıların daha kolay daha net koduyla çözüldü._standardize_user_data
Özet : sadece biraz daha yavaş compile()
.
compile()
için farklı bir tahmin işlevi atayan dahili bir bayrak ayarlar predict
. Bu işlev her çağrı üzerine yeni bir grafik oluşturur ve derlenmemiş olana göre yavaşlar. Ancak, fark sadece tren süresi veri işleme süresinden çok daha kısa olduğunda belirgindir . Biz ise artış için model boyutunu en azından orta ölçekli, iki eşit hale gelir. En alttaki koda bakın.
Veri işleme süresindeki bu küçük artış, güçlendirilmiş grafik kapasitesi ile telafi edilenden daha fazladır. Sadece bir model grafiğini tutmak daha verimli olduğu için, bir ön derleme atılır. Bununla birlikte : modeliniz verilere göre küçükse, compile()
model çıkarımı olmadan daha iyi durumda olursunuz . Geçici çözüm için diğer cevabıma bakın.
NE YAPMALIYIM?
Altta kod var gibi derlenmemiş vs derlenmiş model performansını karşılaştırın.
- Derlenmiş daha hızlı :
predict
derlenmiş bir model üzerinde çalıştırın .
- Derlenmiş daha yavaş :
predict
derlenmemiş bir modelde çalıştırın .
Evet, her ikisi de mümkündür ve (1) veri boyutuna bağlı olacaktır; (2) model boyutu; (3) donanım. Alttaki kod aslında derlenmiş modelin daha hızlı olduğunu gösterir , ancak 10 yineleme küçük bir örnektir. "Nasıl yapılır" konusundaki diğer yanıtımda "geçici çözümler" konusuna bakın.
DETAYLAR :
Bu hata ayıklamak biraz zaman aldı, ama eğlenceliydi. Aşağıda, keşfettiğim önemli suçluları tarif ediyorum, bazı ilgili belgeleri belirtiyorum ve nihai darboğa yol açan profiler sonuçlarını gösteriyoruz.
( FLAG == self.experimental_run_tf_function
, kısalık için)
Model
varsayılan olarak ile başlar FLAG=False
. compile()
olarak ayarlar True
.
predict()
tahmin işlevini edinmeyi içerir, func = self._select_training_loop(x)
- Herhangi bir özel kwarg geçmeden
predict
ve compile
diğer tüm bayraklar şöyledir:
- (A)
FLAG==True
->func = training_v2.Loop()
- (B)
FLAG==False
->func = training_arrays.ArrayLikeTrainingLoop()
- Kaynaktan kaynak kodu docstringe , (A) ' , ağırlıklı olarak grafik güvenen daha dağıtım stratejisi kullanır ve op oluşturma ve (do) "olabilir" grafik elementleri, darbe performansı yok yatkındır.
Gerçek suçlu : _process_inputs()
, muhasebesi çalışma zamanının% 81 . Ana bileşeni mi? _create_graph_function()
, Çalışma süresinin% 72'si . Bu yöntem (B) için bile mevcut değildir . Bununla birlikte, orta boyutlu bir modelin kullanılması, çalışma süresinin% 1'inden daha azını içerir . En alttaki kod ve profil oluşturma sonuçları aşağıdadır._process_inputs
VERİ İŞLEMCİLERİ :
(A) :, <class 'tensorflow.python.keras.engine.data_adapter.TensorLikeDataAdapter'>
içinde kullanılır _process_inputs()
. İlgili kaynak kodu
(B) :, numpy.ndarray
tarafından döndürüldü convert_eager_tensors_to_numpy
. İlgili kaynak kodu ve burada
MODEL YÜRÜTME FONKSİYONU (örn. Tahmin)
(A) : dağıtım fonksiyonu ve burada
(B) : dağıtım fonksiyonu (farklı) ve burada
PROFILER : diğer cevabımdaki "minik model" ve bu cevaba "orta model" deki kod sonuçları:
Küçük model : 1000 iterasyon,compile()
Küçük model : 1000 iterasyon, hayır compile()
Orta model : 10 iterasyon
DOKÜMANTASYON (dolaylı olarak) etkileri compile()
: kaynak
Diğer TensorFlow işlemlerinden farklı olarak, python sayısal girişlerini tensörlere dönüştürmüyoruz. Ayrıca, her farklı python sayısal değeri için yeni bir grafik oluşturulur , örneğin çağrı g(2)
ve g(3)
iki yeni grafik oluşturur
function
Her benzersiz giriş şekli ve veri türü kümesi için ayrı bir grafik başlatır . Örneğin, aşağıdaki kod snippet'i, her bir girişin farklı bir şekli olduğundan üç ayrı grafiğin izlenmesine neden olur
Tek bir tf.function nesnesinin kaputun altındaki birden çok hesaplama grafiğine eşlenmesi gerekebilir. Bu yalnızca performans olarak görünmelidir (izleme grafiklerinde sıfır olmayan bir hesaplama ve bellek maliyeti vardır ), ancak programın doğruluğunu etkilememelidir
KARŞI ÖRNEK :
from tensorflow.keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from tensorflow.keras.layers import Flatten, Dropout
from tensorflow.keras.models import Model
import numpy as np
from time import time
def timeit(func, arg, iterations):
t0 = time()
for _ in range(iterations):
func(arg)
print("%.4f sec" % (time() - t0))
batch_size = 32
batch_shape = (batch_size, 400, 16)
ipt = Input(batch_shape=batch_shape)
x = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
x = LSTM(512, activation='relu', return_sequences=True)(ipt)
x = Conv1D(128, 400, 1, padding='same')(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
X = np.random.randn(*batch_shape)
timeit(model.predict, X, 10)
model.compile('adam', loss='binary_crossentropy')
timeit(model.predict, X, 10)
Çıktılar :
34.8542 sec
34.7435 sec