TensorFlow 2 neden TensorFlow 1 'den daha yavaş?


137

Birçok kullanıcı tarafından Pytorch'a geçmenin nedeni olarak belirtildi, ancak henüz istekli uygulama için en önemli pratik kaliteden, hızdan ödün vermek için bir gerekçe / açıklama bulamadım.

Aşağıda, TF1 ile TF2 arasındaki kod karşılaştırma performansı bulunmaktadır; TF1, % 47'den% 276'ya kadar daha hızlı çalışır .

Sorum şu: grafik veya donanım düzeyinde, bu kadar önemli bir yavaşlama sağlayan nedir?


Ayrıntılı bir cevap arıyorum - zaten geniş kavramlara aşinayım. İlgili Git

Özellikler : CUDA 10.0.130, cuDNN 7.4.2, Python 3.7.4, Windows 10, GTX 1070


Deney sonuçları :


GÜNCELLEME : Aşağıdaki kod başına Eager Yürütmeyi devre dışı bırakmak yardımcı olmaz . Bununla birlikte, davranış tutarsızdır: bazen grafik modunda çalıştırmak önemli ölçüde yardımcı olur, diğer zamanlarda Eager'e göre daha yavaş çalışır .

TF geliştiricileri hiçbir yerde görünmediğinden, bu konuyu kendim araştıracağım - bağlantılı Github konusundaki ilerlemeyi takip edebilirim.

GÜNCELLEME 2 : açıklamalar boyunca paylaşılacak tonlarca deneysel sonuç; bugün yapılmalı.


Karşılaştırma kodu :

# use tensorflow.keras... to benchmark tf.keras; used GPU for all above benchmarks
from keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from keras.layers import Flatten, Dropout
from keras.models import Model
from keras.optimizers import Adam
import keras.backend as K
import numpy as np
from time import time

batch_shape = (32, 400, 16)
X, y = make_data(batch_shape)

model_small = make_small_model(batch_shape)
model_small.train_on_batch(X, y)  # skip first iteration which builds graph
timeit(model_small.train_on_batch, 200, X, y)

K.clear_session()  # in my testing, kernel was restarted instead

model_medium = make_medium_model(batch_shape)
model_medium.train_on_batch(X, y)  # skip first iteration which builds graph
timeit(model_medium.train_on_batch, 10, X, y)

Kullanılan fonksiyonlar :

def timeit(func, iterations, *args):
    t0 = time()
    for _ in range(iterations):
        func(*args)
    print("Time/iter: %.4f sec" % ((time() - t0) / iterations))

def make_small_model(batch_shape):
    ipt   = Input(batch_shape=batch_shape)
    x     = Conv1D(128, 400, strides=4, padding='same')(ipt)
    x     = Flatten()(x)
    x     = Dropout(0.5)(x)
    x     = Dense(64, activation='relu')(x)
    out   = Dense(1,  activation='sigmoid')(x)
    model = Model(ipt, out)
    model.compile(Adam(lr=1e-4), 'binary_crossentropy')
    return model

def make_medium_model(batch_shape):
    ipt   = Input(batch_shape=batch_shape)
    x     = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
    x     = LSTM(512, activation='relu', return_sequences=True)(x)
    x     = Conv1D(128, 400, strides=4, 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)
    model.compile(Adam(lr=1e-4), 'binary_crossentropy')
    return model

def make_data(batch_shape):
    return np.random.randn(*batch_shape), np.random.randint(0, 2, (batch_shape[0], 1))

Hangi parçayı onları bu kadar farklı yapan analiz etmek için cProfile bu tür bir araç kullandınız mı?
zihaozhihao

@zihaozhihao Ben , özellikle bunun için olmasa da; önceki bağlantıya ve özel bir optimize edici yazarken, aramalardaki farklılıklara zaten aşinayım, ancak birinin neden diğerinden daha yavaş olduğunu anlamıyorum - TF dışı uzmanlar bunu kaynaktan anlayamazlar. karışık bir karmaşa, göreceli performansları belgelemez. Grafik / donanım düzeyinde intel gereklidir, bu
profilciler

her iki testte numpy versiyonu aynı mıdır?
chabir

Ah .... Eski Keras tek başına PyTorch'tan çok daha yavaş olsaydı, şimdi hayal edin.
Daniel Möller

model boyutuna göre ölçek nedir? ayrıca diğer işletim sistemlerinde de aynı ölçütü çalıştırmayı denediniz mi?
okawo

Yanıtlar:


76

GÜNCELLEME 2/18/2020 : Ben 2.1 ve 2.1-gecelik bankamıştım ; sonuçlar karıştırılır. Bir yapılandırma hariç tümü (model ve veri boyutu), TF2 ve TF1'in en iyilerinden daha hızlı veya çok daha hızlıdır. Daha yavaş ve dramatik olarak yavaş olan Büyük-Büyük - esp. Grafik yürütmede ( 1.6x ila 2.5x daha yavaş ).

Ayrıca, test ettiğim büyük bir model için Graph ve Eager arasında aşırı tekrarlanabilirlik farklılıkları vardır - biri rastgelelik / hesaplama paralelliğiyle açıklanamaz. Şu anda zaman kısıtlamaları için bu hak talepleri için tekrarlanabilir kod sunamıyorum, bunun yerine bunu kendi modelleriniz için test etmenizi şiddetle tavsiye ederim.

Henüz bir Git sorunu açmadım, ama orijinal hakkında yorum yaptım - henüz yanıt yok. İlerleme kaydedildikten sonra cevapları güncelleyeceğim.


DİKKAT : değil , eğer ne yaptığını biliyorsan. Ancak bunu yapmazsanız , ortalama olarak birkaç GPU yükseltmesi ve en kötü durumdaki birden fazla GPU tarafından size çok pahalıya mal olabilir.


BU CEVAP : sorunun üst düzey bir açıklamasını ve ihtiyaçlarınıza özel eğitim yapılandırmasına nasıl karar vereceğinize ilişkin yönergeler sağlamayı amaçlamaktadır. Tüm kıyaslama sonuçlarını + kullanılan kodu içeren ayrıntılı, düşük düzeyli bir açıklama için diğer cevabıma bakın.

Ben daha fazla bilgi w / daha fazla bilgi varsa ben güncelleme olacak - referans için bu soruya yer işareti / "yıldız" olabilir.


SAYI ÖZETİ : olarak teyit bir TensorFlow geliştirici tarafından, S. Scott Zhu, TF2 istekli yürütme ve TF kaynağı temizlik operasyonu katılan / keras w sıkı entegrasyonu geliştirme odaklı - grafik seviyesinde dahil olmak üzere. Avantajlar: büyük ölçüde genişletilmiş işleme, dağıtım, hata ayıklama ve dağıtım özellikleri. Bununla birlikte, bazılarının maliyeti hızdır.

Ancak mesele oldukça karmaşıktır. Sadece TF1'e karşı TF2'ye değil - tren hızında önemli farklılıklar sağlayan faktörler şunlardır:

  1. TF2 ve TF1
  2. Istekli ve Grafik modu
  3. keras vs. tf.keras
  4. numpyvs. tf.data.Datasetvs.
  5. train_on_batch() vs. fit()
  6. GPU ve CPU Karşılaştırması
  7. model(x)vs. model.predict(x)vs.

Ne yazık ki, yukarıdakilerin neredeyse hiçbiri diğerinden bağımsız değildir ve her biri diğerine göre en az iki kez yürütme süresine sahip olabilir. Neyse ki, neyin en iyi çalışacağını sistematik olarak ve birkaç kısayolla belirleyeceğim - göstereceğim gibi.


NE YAPMALIYIM? Şu anda, tek yol - özel modeliniz, verileriniz ve donanımınız için deneme yapmaktır. Tek başına hiçbir konfigürasyon her zaman en iyi çalışacaktır - ama orada olan en uymaya arama kolaylaştırmak için var yapın:

>> YAPIN:

  • train_on_batch()+ numpy+ tf.keras+ TF1 + Eager / Grafik
  • train_on_batch()+ numpy+ tf.keras+ TF2 + Grafiği
  • fit()+ numpy+ tf.keras+ TF1 / TF2 + Grafik + büyük model ve veriler

>> YAPMAYIN:

  • fit()küçük ve orta modeller ve veriler için + numpy+keras
  • fit()+ numpy+ tf.keras+ TF1 / TF2 + İstekli
  • train_on_batch()+ numpy+ keras+ TF1 + İstekli

  • [Binbaşı] tf.python.keras ; 10-100x daha yavaş çalışabilir ve w / bol miktarda hata; Daha fazla bilgi

    • Bu içerir layers, models, optimizers, ve ilgili "üzerinden kutudan" kullanım ithalat; ops, utils ve ilgili 'özel' ithalatlar iyi - ancak emin olmak için değişiklikleri kontrol edip etmediklerini vetf.keras

Örnek bir kıyaslama kurulumu için diğer cevabımın altındaki koda bakın. Yukarıdaki liste esas olarak diğer cevaptaki "BENCHMARKS" tablolarına dayanmaktadır.


Yukarıdaki DO ve SINIRLAMALARIN SINIRLAMALARI :

  • Bu soru "TF2 neden TF1'den çok daha yavaştır?" Başlıklıdır ve bedeni açıkça eğitim ile ilgili olsa da, mesele bununla sınırlı değildir; çıkarım da, aynı TF sürümü, içe aktarma, veri formatı, vb. içinde bile büyük hız farklılıklarına tabidir - bu cevaba bakınız .
  • RNN'lerin TF2'de iyileştirildikleri için diğer cevaptaki veri ızgarasını önemli ölçüde değiştirmesi muhtemeldir
  • Öncelikle kullanılan modeller Conv1Dve Dense- RNN'ler, seyrek veri / hedefler, 4 / 5D girişler ve diğer yapılandırmalar yok
  • Girdi verileri numpyve tf.data.Datasetdiğer birçok format mevcutken; diğer cevabı gör
  • GPU kullanıldı; CPU'da sonuçlar farklı olacaktır . Aslında, soruyu sorduğumda, CUDA'm düzgün bir şekilde yapılandırılmamıştı ve sonuçların bazıları CPU tabanlıydı.

TF2 neden istekli uygulama için en pratik kaliteyi, hızı feda etti? Açıkça görülmüyor - grafik hala mevcut. Ama soru "neden hiç istekli" ise:

  • Üstün hata ayıklama : "ara katman çıktılarını nasıl alabilirim" veya "ağırlıkları nasıl incelerim?" istekli olarak, (neredeyse) kadar basit .__dict__. Grafik, aksine, özel arka uç işlevlerine aşina olmayı gerektirir - tüm hata ayıklama ve içgözlem sürecini büyük ölçüde karmaşıklaştırır.
  • Daha hızlı prototip oluşturma : yukarıdakine benzer fikirler başına; daha hızlı anlama = gerçek DL için daha fazla zaman kaldı.

EAGER NASIL ETKİNLEŞTİRİLMELİ / DEVRE DIŞI BIRAKILIR?

tf.enable_eager_execution()  # TF1; must be done before any model/tensor creation
tf.compat.v1.disable_eager_execution() # TF2; above holds

EK BİLGİ :

  • _on_batch()TF2'deki yöntemlere dikkat edin ; TF dev'e göre, hala daha yavaş bir uygulama kullanıyorlar, ancak kasıtlı olarak değil - yani düzeltilmesi gerekiyor. Ayrıntılar için diğer cevaba bakınız.

TENSORFLOW DEVS GEREKSİNİMLERİ :

  1. Lütfen düzeltin train_on_batch()ve fit()yinelemeli olarak çağırmanın performans yönü ; Özel tren döngüleri birçokları için özellikle benim için önemlidir.
  2. Kullanıcıların bilgisi için bu performans farklılıklarından söz eden belgeler / dokümanlar ekleyin.
  3. Peeplerin Pytorch'a atlamasını önlemek için genel yürütme hızını artırın.

TEŞEKKÜRLER : Teşekkürler


GÜNCELLEME :

  • 14/14/19 - Numpy giriş verileri ile tüm * yapılandırmalar için TF2'de daha yavaş çalışan bir model (gerçek uygulamamda) bulundu . Farklar% 13-19, ortalama% 17 idi. Bununla birlikte kerasve arasındaki farklar tf.kerasdaha dramatikti: % 18-40 , ort. % 32 (TF1 ve 2'nin ikisi de). (* - TF2 OOM'un yaptığı Eager hariç)

  • 17/17/19 - devs , TF 2.1'de piyasaya sürülecek veya şu anda mevcut olacak şekilde, iyileştirilmiş hıza sahip olduğunu belirten son bir taahhütte güncellenmiş on_batch()yöntemleri güncellendi . İkincisini çalıştıramadım, tezgahı 2.1'e kadar erteleyecek.tf-nightly

  • 2/20/20 - tahmin performansı da karşılaştırmaya değer; TF2'de, örneğin, CPU tahmin süreleri periyodik ani yükselmeler içerebilir

3
Ne olmuş fit_generator? ... Ben neredeyse hiç istemiyorum train_on_batchve gruplar arasında kendi eğitim döngümü yönetmek büyük maliyetle bile kaçınılması gereken devasa, devasa bir anti-model.
ely

@ Diğer testte belirtildiği gibi test edilmeye devam ediyor - ancak herhangi bir şey varsa, fitek veri işleme yükü w / küçük olduğunu tahmin ediyorum . Tren döngülerine gelince, nihayetinde bir tür API'ye dönüşen kendi özel olanımı yazdım; fit_generatoriçgözlem, özelleştirilebilirlik ve kaydetme / yükleme eksik - bu yüzden benim için mutlak bir ip. Sonunda eğitim döngümü Github'da yayınlayacağım.
OverLordGoldDragon

İçgözlem ve özelleştirilebilirlik eksikliği benim için bir özellik, bir hata değil. IDK kaydetme / yükleme yorumunun ne anlama geldiğini? Veri üreticisi tarafından kontrol edilmeyen bir döngü sırasında ara kaydetme / yükleme? (Ayrıca kişisel olarak sadece bunun için geri aramalara güveniyorum ve eğitim döngümün yanlış tasarlandığı bir kod kokusu olarak daha fazla özelleştirilebilirlik ihtiyacı görecektim).
ely

@ Basit değil, ancak karmaşık girdi veri boru hatları, objektif fonksiyonlar ve API olmayan model konfigürasyonları (örn. topluluklar) ile eğitim almak için gereklidir. İç hata, hata ayıklama ve özellik mühendisliği amaçları için bir zorunluluktur. Harici bir kaydetme / yük olmaması ve hesaplamalı olarak pahalı modeller için döngü duraklaması ve sürdürülebilirliğini eğitmek - bir kabus. Ne olursa olsun, nihayetinde sizin özel ihtiyaçlarınıza ve konu dışı kalmanıza bağlıdır; fit_generatorUygulamanız için performansı test etmenin en kesin yolu, bunu test etmektir.
OverLordGoldDragon

47

BU CEVAP : TF2 ve TF1 tren döngüleri, giriş veri işlemcileri ve Eager - Grafik modu uygulamaları dahil olmak üzere, sorunun ayrıntılı, grafik / donanım düzeyinde bir açıklamasını sağlamayı amaçlamaktadır. Sorun özeti ve çözüm yönergeleri için diğer cevabıma bakın.


PERFORMANS KARARI : yapılandırmaya bağlı olarak bazen biri daha hızlı, bazen diğeri daha hızlıdır. TF2'ye karşı TF1'e gelince, ortalama olarak eşitler, ancak önemli konfigürasyon tabanlı farklılıklar var ve TF1, TF2'yi tersine göre daha sık koyar. Aşağıdaki "BENCHMARKING" bölümüne bakın.


EAGER VS. GRAFİK : Bazıları için tüm bu cevabın eti: TF2'nin istekli TF1'lerden daha yavaş , benim testime göre. Ayrıntılar daha da aşağı.

Bu ikisi arasındaki temel fark şudur: Grafik proaktif olarak bir hesaplama ağı kurar ve 'söylendiğinde' yürütülür - oysa Eager yaratılış üzerine her şeyi yürütür. Ancak hikaye sadece burada başlıyor:

  • Istekli Grafikten yoksun değildir ve aslında beklentilerin aksine çoğunlukla Grafik olabilir . Büyük ölçüde nedir, yürütülür Grafik - bu, grafiğin büyük bir bölümünü içeren model ve optimize edici ağırlıkları içerir.

  • Istekli yürütme sırasında kendi grafiğin bir bölümünü yeniden oluşturur ; Grafiğin tam olarak oluşturulmamasının doğrudan sonucu - profiler sonuçlarına bakın. Bunun hesaplama yükü var.

  • İstekli Numpy girişleri ile daha yavaştır ; başına bu Git açıklama ve kod, istekli olarak Numpy girişleri CPU'dan GPU'ya tansörlerine kopyalama genel maliyet içerir. Kaynak kodu ile adım adım veri işleme farklılıkları açıktır; Eager doğrudan Numpy'yi geçerken Graph, daha sonra Numpy'yi değerlendiren tensörleri geçer; kesin işlemden emin değilsiniz ancak ikincisi GPU düzeyinde optimizasyonları içermelidir

  • TF2 Eager, TF1 Eager'den daha yavaş - bu ... beklenmedik. Aşağıdaki kıyaslama sonuçlarına bakın. Farklılıklar ihmal edilebilirden anlamlıya uzanır, ancak tutarlıdır. Durumun neden olduğundan emin değilsiniz - eğer bir TF geliştiricisi açıklarsa cevabı güncelleyecektir.


TF2 vs TF1 : Bir TF dev en, S. Scott Zhu'nun, ilgili bölümlerini alıntı tepki - w / my vurgu & rewording bit:

İstekli olarak, çalışma zamanının op'ları yürütmesi ve her python kodu satırı için sayısal değeri döndürmesi gerekir. Tek adımlı yürütmenin doğası yavaş olmasına neden olur .

TF2'de Keras, eğitim, değerlendirme ve tahmin için grafiğini oluşturmak üzere tf.fonksiyonundan yararlanır. Onlara model için "yürütme işlevi" diyoruz. TF1'de "yürütme işlevi", bazı ortak bileşenleri TF işlevi olarak paylaşan ancak farklı bir uygulamaya sahip olan bir FuncGraph'dı.

İşlem sırasında, bir şekilde train_on_batch (), test_on_batch () ve predict_on_batch () için yanlış bir uygulama bıraktık . Hala sayısal olarak doğrudurlar , ancak x_on_batch için yürütme işlevi, tf.function ile sarılmış bir python işlevi yerine saf bir python işlevidir. Bu yavaşlığa neden olur

TF2'de, tüm giriş verilerini bir tek giriş tipini işlemek için yürütme fonksiyonumuzu birleştirebileceğimiz bir tf.data.Dataset'e dönüştürürüz. Veri kümesi dönüşümünde bazı ek yükler olabilir ve bunun bir toplu işlem maliyeti yerine bir kerelik yalnızca ek yük olduğunu düşünüyorum

Yukarıdaki son paragrafın son cümlesi ve aşağıdaki paragrafın son cümlesi ile:

İstekli moddaki yavaşlığın üstesinden gelmek için, bir python işlevini grafiğe dönüştürecek @ tf.function var. Np dizisi gibi sayısal veri değeri beslendiğinde, tf.function işlevinin gövdesi, optimize edilen statik grafiğe dönüştürülür ve hızlı olan ve TF1 grafik modu ile benzer performansa sahip olması gereken son değeri döndürür.

Kabul etmiyorum - Eager'in girdi veri işlemesinin Graph'lardan çok daha yavaş olduğunu gösteren profil oluşturma sonuçlarıma göre. Ayrıca, tf.data.Datasetözellikle emin değilsiniz, ancak Eager tekrar tekrar aynı veri dönüştürme yöntemlerinin birden çoğunu çağırır - bkz profiler.

Son olarak, dev'in bağlantılı taahhüdü: Keras v2 döngülerini desteklemek için önemli sayıda değişiklik .


Tren Döngüsü : (1) Eager - Graph; (2) giriş veri formatı, eğitim farklı bir tren döngüsüyle devam edecektir - TF2'de _select_training_loop(), training.py , şunlardan biri:

training_v2.Loop()
training_distributed.DistributionMultiWorkerTrainingLoop(
              training_v2.Loop()) # multi-worker mode
# Case 1: distribution strategy
training_distributed.DistributionMultiWorkerTrainingLoop(
            training_distributed.DistributionSingleWorkerTrainingLoop())
# Case 2: generator-like. Input is Python generator, or Sequence object,
# or a non-distributed Dataset or iterator in eager execution.
training_generator.GeneratorOrSequenceTrainingLoop()
training_generator.EagerDatasetOrIteratorTrainingLoop()
# Case 3: Symbolic tensors or Numpy array-like. This includes Datasets and iterators 
# in graph mode (since they generate symbolic tensors).
training_generator.GeneratorLikeTrainingLoop() # Eager
training_arrays.ArrayLikeTrainingLoop() # Graph

Her biri kaynak tahsisini farklı şekilde ele alır ve performans ve yetenek üzerinde sonuçlar doğurur.


Tren Döngüsü: fitvs train_on_batch, kerasvstf.keras .: her dört kombinasyon da farklı tren döngülerini kullanır, ancak her olası kombinasyonda olmayabilir. keras' fit, Örneğin, bir formu kullanır fit_loop, örneğin, training_arrays.fit_loop()ve onun train_on_batchkullanabilir K.function(). tf.kerasönceki bölümde kısmen açıklanan daha karmaşık bir hiyerarşiye sahiptir.


Train Loops: belgeler - farklı yürütme yöntemlerinden bazıları hakkında ilgili kaynak öğretimi :

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

function Her benzersiz giriş şekli ve veri türü kümesi için ayrı bir grafik başlatır .

Tek bir tf.function nesnesinin kaputun altındaki birden çok hesaplama grafiğine eşlenmesi gerekebilir. Bu yalnızca performans olarak görünür olmalıdır (izleme grafiklerinde sıfır dışında bir hesaplama ve bellek maliyeti vardır )


Giriş veri işlemcileri : yukarıdakine benzer şekilde, çalışma zamanı yapılandırmalarına (yürütme modu, veri biçimi, dağıtım stratejisi) göre ayarlanan dahili bayraklara bağlı olarak işlemci duruma göre seçilir. En basit durum, Numpy dizileriyle doğrudan çalışan Eager ile. Bazı özel örnekler için bu cevaba bakınız .


MODEL BOYUTU, VERİ BOYUTU:

  • Belirleyicidir; tek bir yapılandırma tüm model ve veri boyutlarının üstüne çıkmadı.
  • Model boyutuna göre veri boyutu önemlidir; küçük veri ve model için veri aktarımı (örn. CPU'dan GPU'ya) ek yüke hakim olabilir. Benzer şekilde, küçük havai işlemciler, veri dönüştürme süresi baskın olan büyük veriler üzerinde daha yavaş çalışabilir (bkz convert_to_tensor. "PROFILER")
  • Hız, tren döngülerine ve giriş veri işlemcilerinin kaynakları idare etmenin farklı araçlarına göre değişir.

BENCHMARKS : öğütülmüş et. - Word Belgesi - Excel Elektronik Tablosu


Terminoloji :

  • % -less sayıların tümü saniyelerdir
  • % olarak hesaplanır (1 - longer_time / shorter_time)*100; gerekçe: Birinin diğerinden daha hızlı olduğu faktörle ilgileniyoruz ; shorter / longeraslında doğrusal olmayan bir ilişkidir, doğrudan karşılaştırma için yararlı değildir
  • % işaretinin belirlenmesi:
    • TF2 ve TF1: +TF2 daha hızlıysa
    • GvE (Grafik ve Eager): +Grafik daha hızlıysa
  • TF2 = TensorFlow 2.0.0 + Keras 2.3.1; TF1 = Tensör Akışı 1.14.0 + Keras 2.2.5

PROFİL :


PROFILER - Açıklama : Spyder 3.3.6 IDE profiler.

  • Bazı fonksiyonlar diğerlerinin yuvalarında tekrarlanır; bu nedenle, "veri işleme" ve "eğitim" işlevleri arasındaki kesin ayrımı izlemek zordur, bu nedenle en son sonuçta belirtildiği gibi bir miktar çakışma olacaktır.

  • çalışma zamanı eksi derleme süresinden hesaplanan% rakamları

  • 1 veya 2 kez olarak adlandırılan tüm (benzersiz) çalışma zamanlarının toplanmasıyla hesaplanan oluşturma süresi
  • # Yineleme sayısıyla aynı kez adlandırılan tüm (benzersiz) çalışma zamanlarını ve yuvalarının çalışma zamanlarının bazılarını toplayarak hesaplanan tren zamanı
  • İşlevler , maalesef , oluşturma süresinde karışan orijinal adlarına göre profillenir (yani _func = funcprofil olarak gönderilir func) - bu nedenle hariç tutma ihtiyacı

TEST ORTAMI :

  • En az arka plan görevi çalışarak alt kısımda yürütülen kod
  • GPU, bu yayında önerildiği gibi, zamanlama tekrarlarından önce birkaç tekrarlamayla "ısındı"
  • CUDA 10.0.130, cuDNN 7.6.0, TensorFlow 1.14.0 ve kaynaktan oluşturulan TensorFlow 2.0.0 ve Anaconda
  • Python 3.7.4, Spyder 3.3.6 IDE
  • GTX 1070, Windows 10, 24 GB DDR4 2,4 MHz RAM, i7-7700HQ 2,8 GHz CPU

METODOLOJİ :

  • Karşılaştırma ölçütü 'küçük', 'orta' ve 'büyük' ​​model ve veri boyutları
  • Giriş veri boyutundan bağımsız olarak her model boyutu için parametre sayısını düzeltin
  • "Daha büyük" modelde daha fazla parametre ve katman vardır
  • "Daha büyük" veriler daha uzun bir diziye sahiptir, ancak aynı batch_sizevenum_channels
  • Modeller sadece kullanım Conv1D, Dense'öğrenilebilir' katmanları; TF versiyon implanna göre RNN'lerden kaçınıldı. farklar
  • Model ve optimize edici grafik oluşturmayı atlamak için her zaman kıyaslama döngüsünün dışında bir tren uyumu gerçekleştirdi
  • Seyrek veriler (ör. layers.Embedding()) Veya seyrek hedefler (ör.SparseCategoricalCrossEntropy()

SINIRLAMALAR : "tam" bir cevap, olası her tren döngüsünü ve yineleyiciyi açıklayacaktır, ancak bu kesinlikle benim zaman yeteneğimin, var olmayan maaş kontrolünün veya genel zorunluluğun ötesinde. Sonuçlar sadece metodoloji kadar iyidir - açık bir zihinle yorumlayın.


KOD :

import numpy as np
import tensorflow as tf
import random
from termcolor import cprint
from time import time

from tensorflow.keras.layers import Input, Dense, Conv1D
from tensorflow.keras.layers import Dropout, GlobalAveragePooling1D
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
import tensorflow.keras.backend as K
#from keras.layers import Input, Dense, Conv1D
#from keras.layers import Dropout, GlobalAveragePooling1D
#from keras.models import Model 
#from keras.optimizers import Adam
#import keras.backend as K

#tf.compat.v1.disable_eager_execution()
#tf.enable_eager_execution()

def reset_seeds(reset_graph_with_backend=None, verbose=1):
    if reset_graph_with_backend is not None:
        K = reset_graph_with_backend
        K.clear_session()
        tf.compat.v1.reset_default_graph()
        if verbose:
            print("KERAS AND TENSORFLOW GRAPHS RESET")

    np.random.seed(1)
    random.seed(2)
    if tf.__version__[0] == '2':
        tf.random.set_seed(3)
    else:
        tf.set_random_seed(3)
    if verbose:
        print("RANDOM SEEDS RESET")

print("TF version: {}".format(tf.__version__))
reset_seeds()

def timeit(func, iterations, *args, _verbose=0, **kwargs):
    t0 = time()
    for _ in range(iterations):
        func(*args, **kwargs)
        print(end='.'*int(_verbose))
    print("Time/iter: %.4f sec" % ((time() - t0) / iterations))

def make_model_small(batch_shape):
    ipt   = Input(batch_shape=batch_shape)
    x     = Conv1D(128, 40, strides=4, padding='same')(ipt)
    x     = GlobalAveragePooling1D()(x)
    x     = Dropout(0.5)(x)
    x     = Dense(64, activation='relu')(x)
    out   = Dense(1,  activation='sigmoid')(x)
    model = Model(ipt, out)
    model.compile(Adam(lr=1e-4), 'binary_crossentropy')
    return model

def make_model_medium(batch_shape):
    ipt = Input(batch_shape=batch_shape)
    x = ipt
    for filters in [64, 128, 256, 256, 128, 64]:
        x  = Conv1D(filters, 20, strides=1, padding='valid')(x)
    x     = GlobalAveragePooling1D()(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)
    model.compile(Adam(lr=1e-4), 'binary_crossentropy')
    return model

def make_model_large(batch_shape):
    ipt   = Input(batch_shape=batch_shape)
    x     = Conv1D(64,  400, strides=4, padding='valid')(ipt)
    x     = Conv1D(128, 200, strides=1, padding='valid')(x)
    for _ in range(40):
        x = Conv1D(256,  12, strides=1, padding='same')(x)
    x     = Conv1D(512,  20, strides=2, padding='valid')(x)
    x     = Conv1D(1028, 10, strides=2, padding='valid')(x)
    x     = Conv1D(256,   1, strides=1, padding='valid')(x)
    x     = GlobalAveragePooling1D()(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)
    model.compile(Adam(lr=1e-4), 'binary_crossentropy')
    return model

def make_data(batch_shape):
    return np.random.randn(*batch_shape), \
           np.random.randint(0, 2, (batch_shape[0], 1))

def make_data_tf(batch_shape, n_batches, iters):
    data = np.random.randn(n_batches, *batch_shape),
    trgt = np.random.randint(0, 2, (n_batches, batch_shape[0], 1))
    return tf.data.Dataset.from_tensor_slices((data, trgt))#.repeat(iters)

batch_shape_small  = (32, 140,   30)
batch_shape_medium = (32, 1400,  30)
batch_shape_large  = (32, 14000, 30)

batch_shapes = batch_shape_small, batch_shape_medium, batch_shape_large
make_model_fns = make_model_small, make_model_medium, make_model_large
iterations = [200, 100, 50]
shape_names = ["Small data",  "Medium data",  "Large data"]
model_names = ["Small model", "Medium model", "Large model"]

def test_all(fit=False, tf_dataset=False):
    for model_fn, model_name, iters in zip(make_model_fns, model_names, iterations):
        for batch_shape, shape_name in zip(batch_shapes, shape_names):
            if (model_fn is make_model_large) and (batch_shape is batch_shape_small):
                continue
            reset_seeds(reset_graph_with_backend=K)
            if tf_dataset:
                data = make_data_tf(batch_shape, iters, iters)
            else:
                data = make_data(batch_shape)
            model = model_fn(batch_shape)

            if fit:
                if tf_dataset:
                    model.train_on_batch(data.take(1))
                    t0 = time()
                    model.fit(data, steps_per_epoch=iters)
                    print("Time/iter: %.4f sec" % ((time() - t0) / iters))
                else:
                    model.train_on_batch(*data)
                    timeit(model.fit, iters, *data, _verbose=1, verbose=0)
            else:
                model.train_on_batch(*data)
                timeit(model.train_on_batch, iters, *data, _verbose=1)
            cprint(">> {}, {} done <<\n".format(model_name, shape_name), 'blue')
            del model

test_all(fit=True, tf_dataset=False)

Kodunuzun doğru olup olmadığından emin değilim. Ben aramak beri modelleri her zaman grafik modunda çalıştırmak düşünüyorum model.compileolmadan run_eagerly=Trueargüman. İstekli moddaysa, kodunuzun bir kısmını kullanarak grafik modunda çalıştırabilirsiniz tf.function. Bu nedenle, varsayılan uygulamasının compileperformans nedenleriyle hevesle çalıştırmak yerine hesaplama grafiği oluşturmak olduğunu düşünüyorum . Ayrıca, modeliniz kıvrımlıysa, python etkileşimi minimum olduğundan grafik modunda hızlanma görmüyorsunuz. Eğer çok fazla matematik op yaparsanız (fark bellek kullanımı da) büyük fark yaratabilir.
user2781994

@OverLordGoldDragon ama TF 2'de, istekli modu, varsayılan olarak ama model.compileolmadan run_eagerly=Trueolmasını sağlar grafik modunda veya olmasın?
user2781994

@OverLordGoldDragon Tüm içe aktarılan yöntemlerin grafik modunda çalışmadığını kabul ediyorum, ancak eğitimin grafik modunda dahili olarak çalışmasını sağlamak ya model.compileda model.fitolması gerektiğini düşünüyorum .
user2781994

@OverLordGoldDragon TRUE - "tf.keras.Model.compile üç önemli argüman alır: ... Ayrıca, modelin istekli bir şekilde eğitildiğinden ve değerlendirildiğinden emin olmak için run_eagerly=True, derlenecek bir parametre olarak geçtiğinizden emin olabilirsiniz ." (source tensorflow.org/guide/keras/overview ) Bu yüzden geçemezseniz run_eagerly=Truemodel grafik modunda çalışabilir. Karar verme faktörünün ne olduğundan emin değilim ama neden istekli olmaktan daha verimli ise neden grafik modunda çalışmaz?
user2781994

Daha fazla kanıt ister misiniz? :) "Varsayılan olarak, en iyi yürütme performansını sunmak için modelinizi statik bir grafiğe derlemeye çalışacağız." ( github.com/tensorflow/tensorflow/blob/r2.0/tensorflow/python/… )
user2781994
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.