TensorBoard Debugger V2 Kullanarak TensorFlow Programlarındaki Sayısal Sorunlarda Hata Ayıklama,TensorBoard Debugger V2 Kullanarak TensorFlow Programlarındaki Sayısal Sorunlarda Hata Ayıklama

NaN'leri içeren felaket olayları bazen bir TensorFlow programı sırasında meydana gelebilir ve model eğitim süreçlerini sekteye uğratabilir. Bu tür olayların temel nedeni, özellikle önemsiz olmayan boyut ve karmaşıklık modelleri için genellikle belirsizdir. Bu tür model hatalarında hata ayıklamayı kolaylaştırmak için TensorBoard 2.3+ (TensorFlow 2.3+ ile birlikte), Debugger V2 adlı özel bir pano sağlar. Burada, TensorFlow'da yazılmış bir sinir ağında NaN'leri içeren gerçek bir hata üzerinde çalışarak bu aracın nasıl kullanılacağını gösteriyoruz.

Bu öğreticide gösterilen teknikler, karmaşık programlarda çalışma zamanı tensör şekillerini denetleme gibi diğer türdeki hata ayıklama etkinliklerine uygulanabilir. Bu eğitim, nispeten yüksek oluşum sıklığı nedeniyle NaN'lere odaklanmaktadır.

Hatayı gözlemlemek

Hatalarını ayıklayacağımız TF2 programının kaynak kodu GitHub'da mevcut . Örnek program ayrıca tensorflow pip paketine (sürüm 2.3+) paketlenmiştir ve şu şekilde çağrılabilir:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2

Bu TF2 programı, çok katmanlı bir algı (MLP) oluşturur ve onu MNIST görüntülerini tanıması için eğitir. Bu örnek, özel katman yapılarını, kayıp işlevini ve eğitim döngüsünü tanımlamak için TF2'nin düşük seviyeli API'sini kasıtlı olarak kullanır, çünkü bu daha esnek ancak hataya açık API'yi kullandığımızda NaN hatalarının olasılığı daha kolay kullandığımızdan daha fazladır. -kullanım ama biraz daha az esnek üst düzey API'ler tf.keras gibi.

Program, her eğitim adımından sonra bir test doğruluğu yazdırır. İlk adımdan sonra test doğruluğunun şansa yakın bir seviyede (~0.1) takıldığını konsolda görebiliriz. Model eğitiminin kesinlikle böyle davranması beklenmiyor: adım arttıkça doğruluğun kademeli olarak 1,0'a (%100) yaklaşmasını bekliyoruz.

Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...

Eğitimli bir tahmin, bu sorunun NaN veya sonsuz gibi sayısal bir kararsızlıktan kaynaklandığıdır. Ancak, durumun gerçekten böyle olduğunu nasıl doğrularız ve sayısal kararsızlığı oluşturmaktan sorumlu TensorFlow işlemini (op) nasıl bulabiliriz? Bu soruları yanıtlamak için, buggy programını Debugger V2 ile donatalım.

Debugger V2 ile TensorFlow kodunun enstrümantasyonu

tf.debugging.experimental.enable_dump_debug_info() , Hata Ayıklayıcı V2'nin API giriş noktasıdır. Tek bir kod satırı ile bir TF2 programını kontrol eder. Örneğin, programın başına aşağıdaki satırı eklemek, hata ayıklama bilgilerinin /tmp/tfdbg2_logdir konumunda bulunan günlük dizinine (logdir) yazılmasına neden olacaktır. Hata ayıklama bilgileri, TensorFlow çalışma zamanının çeşitli yönlerini kapsar. TF2'de, istekli yürütmenin tam tarihini, @tf.function tarafından gerçekleştirilen grafik oluşturmayı, grafiklerin yürütülmesini, yürütme olayları tarafından oluşturulan tensör değerlerini ve bu olayların kod konumunu (Python yığın izleri) içerir. . Hata ayıklama bilgilerinin zenginliği, kullanıcıların belirsiz hataları daraltmasına olanak tanır.

tf.debugging.experimental.enable_dump_debug_info(
    "/tmp/tfdbg2_logdir",
    tensor_debug_mode="FULL_HEALTH",
    circular_buffer_size=-1)

tensor_debug_mode bağımsız değişkeni, Hata Ayıklayıcı V2'nin her istekli veya grafik içi tensörden hangi bilgileri çıkaracağını kontrol eder. "FULL_HEALTH", her bir kayan tip tensör hakkında aşağıdaki bilgileri yakalayan bir moddur (örneğin, yaygın olarak görülen float32 ve daha az yaygın olan bfloat16 dtype):

  • DType
  • Rütbe
  • Toplam eleman sayısı
  • Kayan tip öğelerin şu kategorilere ayrılması: negatif sonlu ( - ), sıfır ( 0 ), pozitif sonlu ( + ), negatif sonsuz ( -∞ ), pozitif sonsuz ( +∞ ) ve NaN .

“FULL_HEALTH” modu, NaN ve infinity içeren hataların ayıklanması için uygundur. Desteklenen diğer tensor_debug_mode s için aşağıya bakın.

circular_buffer_size bağımsız değişkeni, logdir'e kaç tane tensör olayının kaydedildiğini kontrol eder. Varsayılan olarak 1000'dir, bu da enstrümanlı TF2 programının bitiminden önce yalnızca son 1000 tensörün diske kaydedilmesine neden olur. Bu varsayılan davranış, hata ayıklama verilerinin eksiksizliğinden ödün vererek hata ayıklayıcı ek yükünü azaltır. Tamlık tercih edilirse, bu durumda olduğu gibi, argümanı negatif bir değere ayarlayarak dairesel tamponu devre dışı bırakabiliriz (örneğin, burada -1).

debug_mnist_v2 örneği, komut satırı bayraklarını ileterek enable_dump_debug_info() işlevini çağırır. Bu hata ayıklama araçları etkinken sorunlu TF2 programımızı yeniden çalıştırmak için şunları yapın:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
    --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH

TensorBoard'da Hata Ayıklayıcı V2 GUI'yi Başlatma

Programı hata ayıklayıcı araçlarıyla çalıştırmak /tmp/tfdbg2_logdir konumunda bir logdir oluşturur. TensorBoard'u başlatabilir ve aşağıdakilerle logdir'e yönlendirebiliriz:

tensorboard --logdir /tmp/tfdbg2_logdir

Web tarayıcısında, http://localhost:6006 adresindeki TensorBoard sayfasına gidin. "Debugger V2" eklentisi varsayılan olarak devre dışı olacaktır, bu nedenle sağ üstteki "Etkin olmayan eklentiler" menüsünden onu seçin. Seçildikten sonra, aşağıdaki gibi görünmelidir:

Hata Ayıklayıcı V2 tam görünüm ekran görüntüsü

NaN'lerin temel nedenini bulmak için Hata Ayıklayıcı V2 GUI'yi kullanma

TensorBoard'daki Hata Ayıklayıcı V2 GUI, altı bölüm halinde düzenlenmiştir:

  • Uyarılar : Bu sol üst bölüm, aletli TensorFlow programından alınan hata ayıklama verilerinde hata ayıklayıcı tarafından algılanan "uyarı" olaylarının bir listesini içerir. Her uyarı, dikkat edilmesi gereken belirli bir anormalliği belirtir. Bizim durumumuzda, bu bölüm göze çarpan pembe-kırmızı renkle 499 NaN/∞ olayı vurgulamaktadır. Bu, dahili tensör değerlerinde NaN'lerin ve/veya sonsuzlukların varlığı nedeniyle modelin öğrenemediğine dair şüphemizi doğrular. Bu uyarıları birazdan inceleyeceğiz.
  • Python Yürütme Zaman Çizelgesi : Bu, üst-orta bölümün üst yarısıdır. Operasyonların ve grafiklerin hevesle yürütülmesinin tam tarihini sunar. Zaman çizelgesinin her kutusu, op veya grafiğin adının ilk harfiyle işaretlenir (örneğin, “TensorSliceDataset” op için “T”, “model” tf.function için “m”). Bu zaman çizelgesinde gezinme düğmelerini ve zaman çizelgesinin üzerindeki kaydırma çubuğunu kullanarak gezinebiliriz.
  • Grafik Yürütme : GUI'nin sağ üst köşesinde yer alan bu bölüm, hata ayıklama görevimizin merkezi olacaktır. Grafikler içinde hesaplanan tüm kayan tipli tensörlerin geçmişini içerir (yani, @tf-function s tarafından derlenir).
  • Grafik Yapısı (üst-orta bölümün alt yarısı), Kaynak Kodu (sol alt bölüm) ve Yığın İzleme (sağ alt bölüm) başlangıçta boştur. GUI ile etkileşim kurduğumuzda içerikleri doldurulacaktır. Bu üç bölüm, hata ayıklama görevimizde de önemli roller oynayacaktır.

Kendimizi kullanıcı arayüzünün organizasyonuna yönlendirdikten sonra, NaN'lerin neden ortaya çıktığını anlamak için aşağıdaki adımları atalım. İlk olarak, Uyarılar bölümünde NaN/∞ uyarısını tıklayın. Bu, Grafik Yürütme bölümündeki 600 grafik tensör listesini otomatik olarak kaydırır ve bir Log (doğal logaritma) işlemi tarafından oluşturulan Log:0 adlı bir tensör olan #88'e odaklanır. Göze çarpan bir pembe-kırmızı renk, 2D float32 tensörünün 1000 öğesi arasında bir -∞ öğesini vurgular. Bu, TF2 programının çalışma zamanı geçmişinde herhangi bir NaN veya sonsuz içeren ilk tensördür: ondan önce hesaplanan tensörler NaN veya ∞ içermez; daha sonra hesaplanan birçok (aslında, çoğu) tensör NaN içerir. Bunu Graph Execution listesinde yukarı ve aşağı kaydırarak onaylayabiliriz. Bu gözlem, Log op'un bu TF2 programındaki sayısal kararsızlığın kaynağı olduğuna dair güçlü bir ipucu sağlar.

Hata Ayıklayıcı V2: Nan / Infinity uyarıları ve grafik yürütme listesi

Bu Log işlemi neden -∞ tükürüyor? Bu soruyu cevaplamak, operasyona girdiyi incelemeyi gerektirir. Tensörün adına ( Log:0 ) tıklamak, Log op'un çevresinin Grafik Yapısı bölümündeki TensorFlow grafiğinde basit ama bilgilendirici bir görselleştirmesini getirir. Bilgi akışının yukarıdan aşağıya yönüne dikkat edin. Operasyonun kendisi ortadaki kalın harflerle gösterilmiştir. Hemen üzerinde, Log op'a tek ve tek girdi sağlayan bir Placeholder op'u görebiliriz. Grafik Yürütme listesinde bu probs Yer Tutucusu tarafından oluşturulan tensör nerede? Sarı arka plan rengini görsel bir yardım olarak kullanarak, probs:0 tensörünün Log:0 tensörünün üç satır üstünde, yani 85. satırda olduğunu görebiliriz.

Hata Ayıklayıcı V2: Grafik yapısı görünümü ve giriş tensörüne yönelik izleme

85. satırdaki probs:0 tensörünün sayısal dağılımına daha dikkatli bir bakış, tüketici Log:0 neden bir -∞: ürettiğini ortaya çıkarır probs:0 1000 öğesi arasında, bir öğenin değeri 0'dır. -∞ 0'ın doğal logaritmasını hesaplamanın bir sonucu! Log işleminin yalnızca pozitif girdilere maruz kalmasını bir şekilde sağlayabilirsek, NaN/∞'nin olmasını önleyebiliriz. Bu, Placeholder probs tensörüne kırpma uygulanarak (örneğin, tf.clip_by_value() kullanılarak) gerçekleştirilebilir.

Hatayı çözmeye yaklaşıyoruz, ancak henüz tam olarak bitmedi. Düzeltmeyi uygulamak için, Log op ve onun Placeholder girdisinin Python kaynak kodunda nereden geldiğini bilmemiz gerekiyor. Hata Ayıklayıcı V2, grafik operasyonlarını ve yürütme olaylarını kaynaklarına kadar izlemek için birinci sınıf destek sağlar. Graph Executions'da Log:0 tensörünü tıklattığımızda, Stack Trace bölümü Log op'un yarattığı orijinal stack trace ile dolduruldu. Yığın izlemesi, çoğu hata ayıklama görevinde güvenle göz ardı edebileceğimiz TensorFlow'un dahili kodundan (örneğin, gen_math_ops.py ve dumping_callback.py) birçok kare içerdiğinden biraz büyüktür. İlgilenilen çerçeve, debug_mnist_v2.py'nin 216. satırıdır (yani, aslında hata ayıklamaya çalıştığımız Python dosyası). “Satır 216”ya tıklamak, Kaynak Kodu bölümünde ilgili kod satırının bir görünümünü getirir.

Hata Ayıklayıcı V2: Kaynak kodu ve yığın izleme

Bu nihayet bizi probs girişinden sorunlu Log op'u oluşturan kaynak koduna getiriyor. Bu, @tf.function ile süslenmiş ve dolayısıyla bir TensorFlow grafiğine dönüştürülmüş özel kategorik çapraz entropi kaybı fonksiyonumuzdur. Placeholder op probs , kayıp fonksiyonunun ilk girdi argümanına karşılık gelir. Log işlemi, tf.math.log() API çağrısı ile oluşturulur.

Bu hatanın değer kırpma düzeltmesi şöyle görünecek:

  diff = -(labels *
           tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))

Bu TF2 programındaki sayısal kararsızlığı giderecek ve MLP'nin başarılı bir şekilde eğitilmesine neden olacaktır. Sayısal kararsızlığı düzeltmeye yönelik bir başka olası yaklaşım da tf.keras.losses.CategoricalCrossentropy kullanmaktır.

Bu, bir TF2 model hatasını gözlemlemekten, sayısal özetler de dahil olmak üzere, enstrümanlı TF2 programının istekli ve grafik yürütme geçmişine tam görünürlük sağlayan Hata Ayıklayıcı V2 aracının yardımıyla hatayı düzelten bir kod değişikliği bulmaya kadar olan yolculuğumuza son veriyor. tensör değerleri ve ops, tensörler ve orijinal kaynak kodları arasındaki ilişki.

Hata Ayıklayıcı V2'nin donanım uyumluluğu

Hata Ayıklayıcı V2, CPU ve GPU dahil genel eğitim donanımını destekler. tf.distributed.MirroredStrategy ile çoklu GPU eğitimi de desteklenir. TPU desteği hala erken bir aşamadadır ve arama yapılmasını gerektirir

tf.config.set_soft_device_placement(True)

enable_dump_debug_info() çağırmadan önce. TPU'larda başka sınırlamaları da olabilir. Hata Ayıklayıcı V2'yi kullanırken sorun yaşarsanız, lütfen hataları GitHub sorunları sayfamızdan bildirin .

Hata Ayıklayıcı V2'nin API uyumluluğu

Hata Ayıklayıcı V2, nispeten düşük bir TensorFlow yazılım yığını düzeyinde uygulanır ve bu nedenle tf.keras , tf.data ve TensorFlow'un alt düzeylerinin üzerine inşa edilmiş diğer API'lerle uyumludur. Hata Ayıklayıcı V2, TF1 ile geriye dönük olarak da uyumludur, ancak Eager Yürütme Zaman Çizelgesi, TF1 programları tarafından oluşturulan hata ayıklama günlük dizinleri için boş olacaktır.

API kullanım ipuçları

Bu hata ayıklama API'si hakkında sık sorulan bir soru, TensorFlow kodunda birinin enable_dump_debug_info() çağrısını eklemesi gerektiğidir. Tipik olarak, API, TF2 programınızda, tercihen Python içe aktarma satırlarından sonra ve grafik oluşturma ve yürütme başlamadan önce mümkün olduğunca erken çağrılmalıdır. Bu, modelinize ve eğitimine güç veren tüm operasyonların ve grafiklerin tam olarak kapsanmasını sağlayacaktır.

Şu anda desteklenen tensor_debug_modları şunlardır: NO_TENSOR , CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH ve SHAPE . Her bir tensörden çıkarılan bilgi miktarına ve hata ayıklanmış programın performans yüküne göre değişirler. Lütfen enable_dump_debug_info() 'nın belgelerinin argümanlar bölümüne bakın.

Performans yükü

Hata ayıklama API'si, enstrümanlı TensorFlow programına performans ek yükü getirir. Ek yük, tensor_debug_mode , donanım türü ve enstrümanlı TensorFlow programının doğasına göre değişir. Referans noktası olarak, GPU'da NO_TENSOR modu, toplu iş boyutu 64 altında bir Transformer modelinin eğitimi sırasında %15 ek yük ekler. Diğer tensor_debug_modları için ek yük yüzdesi daha yüksektir: CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH ve SHAPE için yaklaşık %50 modlar. CPU'larda, ek yük biraz daha düşüktür. TPU'larda, ek yük şu anda daha yüksektir.

Diğer TensorFlow hata ayıklama API'leriyle ilişkisi

TensorFlow'un hata ayıklama için başka araçlar ve API'ler sunduğunu unutmayın. API belgeleri sayfasındaki tf.debugging.* ad alanı altında bu tür API'lere göz atabilirsiniz. Bu API'ler arasında en sık kullanılanı tf.print() 'tir. Debugger V2 ne zaman kullanılmalı ve bunun yerine ne zaman tf.print() kullanılmalıdır? tf.print() şu durumlarda uygundur:

  1. tam olarak hangi tensörlerin yazdırılacağını biliyoruz,
  2. bu tf.print() deyimlerini kaynak kodun tam olarak neresine ekleyeceğimizi biliyoruz,
  3. bu tür tensörlerin sayısı çok fazla değildir.

Diğer durumlar için (örneğin, birçok tensör değerinin incelenmesi, TensorFlow'un dahili kodu tarafından oluşturulan tensör değerlerinin incelenmesi ve yukarıda gösterdiğimiz gibi sayısal kararsızlığın kaynağının aranması), Hata Ayıklayıcı V2, hata ayıklamanın daha hızlı bir yolunu sağlar. Ek olarak, Debugger V2, istekli ve grafik tensörleri denetlemek için birleşik bir yaklaşım sağlar. Ayrıca, tf.print() yeteneğinin ötesinde olan grafik yapısı ve kod konumları hakkında bilgi sağlar.

∞ ve NaN içeren sorunların hatalarını ayıklamak için kullanılabilecek başka bir API tf.debugging.enable_check_numerics() 'dir. enable_dump_debug_info() farklı olarak, enable_check_numerics() hata ayıklama bilgilerini diske kaydetmez. Bunun yerine, TensorFlow çalışma zamanı sırasında yalnızca ∞ ve NaN'yi izler ve herhangi bir işlem bu kadar kötü sayısal değerler üretir üretmez orijin kodu konumuyla ilgili hataları giderir. enable_dump_debug_info() ile karşılaştırıldığında daha düşük bir performans yüküne sahiptir, ancak programın yürütme geçmişinin tam izini vermez ve Debugger V2 gibi bir grafik kullanıcı arabirimiyle birlikte gelmez.

,

NaN'leri içeren felaket olayları bazen bir TensorFlow programı sırasında meydana gelebilir ve model eğitim süreçlerini sekteye uğratabilir. Bu tür olayların temel nedeni, özellikle önemsiz olmayan boyut ve karmaşıklık modelleri için genellikle belirsizdir. Bu tür model hatalarında hata ayıklamayı kolaylaştırmak için TensorBoard 2.3+ (TensorFlow 2.3+ ile birlikte), Debugger V2 adlı özel bir pano sağlar. Burada, TensorFlow'da yazılmış bir sinir ağında NaN'leri içeren gerçek bir hata üzerinde çalışarak bu aracın nasıl kullanılacağını gösteriyoruz.

Bu öğreticide gösterilen teknikler, karmaşık programlarda çalışma zamanı tensör şekillerini denetleme gibi diğer türdeki hata ayıklama etkinliklerine uygulanabilir. Bu eğitim, nispeten yüksek oluşum sıklığı nedeniyle NaN'lere odaklanmaktadır.

Hatayı gözlemlemek

Hatalarını ayıklayacağımız TF2 programının kaynak kodu GitHub'da mevcut . Örnek program ayrıca tensorflow pip paketine (sürüm 2.3+) paketlenmiştir ve şu şekilde çağrılabilir:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2

Bu TF2 programı, çok katmanlı bir algı (MLP) oluşturur ve onu MNIST görüntülerini tanıması için eğitir. Bu örnek, özel katman yapılarını, kayıp işlevini ve eğitim döngüsünü tanımlamak için TF2'nin düşük seviyeli API'sini kasıtlı olarak kullanır, çünkü bu daha esnek ancak hataya açık API'yi kullandığımızda NaN hatalarının olasılığı daha kolay kullandığımızdan daha fazladır. -kullanım ama biraz daha az esnek üst düzey API'ler tf.keras gibi.

Program, her eğitim adımından sonra bir test doğruluğu yazdırır. İlk adımdan sonra test doğruluğunun şansa yakın bir seviyede (~0.1) takıldığını konsolda görebiliriz. Model eğitiminin kesinlikle böyle davranması beklenmiyor: adım arttıkça doğruluğun kademeli olarak 1,0'a (%100) yaklaşmasını bekliyoruz.

Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...

Eğitimli bir tahmin, bu sorunun NaN veya sonsuz gibi sayısal bir kararsızlıktan kaynaklandığıdır. Ancak, durumun gerçekten böyle olduğunu nasıl doğrularız ve sayısal kararsızlığı oluşturmaktan sorumlu TensorFlow işlemini (op) nasıl bulabiliriz? Bu soruları yanıtlamak için, buggy programını Debugger V2 ile donatalım.

Debugger V2 ile TensorFlow kodunun enstrümantasyonu

tf.debugging.experimental.enable_dump_debug_info() , Hata Ayıklayıcı V2'nin API giriş noktasıdır. Tek bir kod satırı ile bir TF2 programını kontrol eder. Örneğin, programın başına aşağıdaki satırı eklemek, hata ayıklama bilgilerinin /tmp/tfdbg2_logdir konumunda bulunan günlük dizinine (logdir) yazılmasına neden olacaktır. Hata ayıklama bilgileri, TensorFlow çalışma zamanının çeşitli yönlerini kapsar. TF2'de, istekli yürütmenin tam tarihini, @tf.function tarafından gerçekleştirilen grafik oluşturmayı, grafiklerin yürütülmesini, yürütme olayları tarafından oluşturulan tensör değerlerini ve bu olayların kod konumunu (Python yığın izleri) içerir. . Hata ayıklama bilgilerinin zenginliği, kullanıcıların belirsiz hataları daraltmasına olanak tanır.

tf.debugging.experimental.enable_dump_debug_info(
    "/tmp/tfdbg2_logdir",
    tensor_debug_mode="FULL_HEALTH",
    circular_buffer_size=-1)

tensor_debug_mode bağımsız değişkeni, Hata Ayıklayıcı V2'nin her istekli veya grafik içi tensörden hangi bilgileri çıkaracağını kontrol eder. "FULL_HEALTH", her bir kayan tip tensör hakkında aşağıdaki bilgileri yakalayan bir moddur (örneğin, yaygın olarak görülen float32 ve daha az yaygın olan bfloat16 dtype):

  • DType
  • Rütbe
  • Toplam eleman sayısı
  • Kayan tip öğelerin şu kategorilere ayrılması: negatif sonlu ( - ), sıfır ( 0 ), pozitif sonlu ( + ), negatif sonsuz ( -∞ ), pozitif sonsuz ( +∞ ) ve NaN .

“FULL_HEALTH” modu, NaN ve infinity içeren hataların ayıklanması için uygundur. Desteklenen diğer tensor_debug_mode s için aşağıya bakın.

circular_buffer_size bağımsız değişkeni, logdir'e kaç tane tensör olayının kaydedildiğini kontrol eder. Varsayılan olarak 1000'dir, bu da enstrümanlı TF2 programının bitiminden önce yalnızca son 1000 tensörün diske kaydedilmesine neden olur. Bu varsayılan davranış, hata ayıklama verilerinin eksiksizliğinden ödün vererek hata ayıklayıcı ek yükünü azaltır. Tamlık tercih edilirse, bu durumda olduğu gibi, argümanı negatif bir değere ayarlayarak dairesel tamponu devre dışı bırakabiliriz (örneğin, burada -1).

debug_mnist_v2 örneği, komut satırı bayraklarını ileterek enable_dump_debug_info() işlevini çağırır. Bu hata ayıklama araçları etkinken sorunlu TF2 programımızı yeniden çalıştırmak için şunları yapın:

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
    --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH

TensorBoard'da Hata Ayıklayıcı V2 GUI'yi Başlatma

Programı hata ayıklayıcı araçlarıyla çalıştırmak /tmp/tfdbg2_logdir konumunda bir logdir oluşturur. TensorBoard'u başlatabilir ve aşağıdakilerle logdir'e yönlendirebiliriz:

tensorboard --logdir /tmp/tfdbg2_logdir

Web tarayıcısında, http://localhost:6006 adresindeki TensorBoard sayfasına gidin. "Debugger V2" eklentisi varsayılan olarak devre dışı olacaktır, bu nedenle sağ üstteki "Etkin olmayan eklentiler" menüsünden onu seçin. Seçildikten sonra, aşağıdaki gibi görünmelidir:

Hata Ayıklayıcı V2 tam görünüm ekran görüntüsü

NaN'lerin temel nedenini bulmak için Hata Ayıklayıcı V2 GUI'yi kullanma

TensorBoard'daki Hata Ayıklayıcı V2 GUI, altı bölüm halinde düzenlenmiştir:

  • Uyarılar : Bu sol üst bölüm, aletli TensorFlow programından alınan hata ayıklama verilerinde hata ayıklayıcı tarafından algılanan "uyarı" olaylarının bir listesini içerir. Her uyarı, dikkat edilmesi gereken belirli bir anormalliği belirtir. Bizim durumumuzda, bu bölüm göze çarpan pembe-kırmızı renkle 499 NaN/∞ olayı vurgulamaktadır. Bu, dahili tensör değerlerinde NaN'lerin ve/veya sonsuzlukların varlığı nedeniyle modelin öğrenemediğine dair şüphemizi doğrular. Bu uyarıları birazdan inceleyeceğiz.
  • Python Yürütme Zaman Çizelgesi : Bu, üst-orta bölümün üst yarısıdır. Operasyonların ve grafiklerin hevesle yürütülmesinin tam tarihini sunar. Zaman çizelgesinin her kutusu, op veya grafiğin adının ilk harfiyle işaretlenir (örneğin, “TensorSliceDataset” op için “T”, “model” tf.function için “m”). Bu zaman çizelgesinde gezinme düğmelerini ve zaman çizelgesinin üzerindeki kaydırma çubuğunu kullanarak gezinebiliriz.
  • Grafik Yürütme : GUI'nin sağ üst köşesinde yer alan bu bölüm, hata ayıklama görevimizin merkezi olacaktır. Grafikler içinde hesaplanan tüm kayan tipli tensörlerin geçmişini içerir (yani, @tf-function s tarafından derlenir).
  • Grafik Yapısı (üst-orta bölümün alt yarısı), Kaynak Kodu (sol alt bölüm) ve Yığın İzleme (sağ alt bölüm) başlangıçta boştur. GUI ile etkileşim kurduğumuzda içerikleri doldurulacaktır. Bu üç bölüm, hata ayıklama görevimizde de önemli roller oynayacaktır.

Kendimizi kullanıcı arayüzünün organizasyonuna yönlendirdikten sonra, NaN'lerin neden ortaya çıktığını anlamak için aşağıdaki adımları atalım. İlk olarak, Uyarılar bölümünde NaN/∞ uyarısını tıklayın. Bu, Grafik Yürütme bölümündeki 600 grafik tensör listesini otomatik olarak kaydırır ve bir Log (doğal logaritma) işlemi tarafından oluşturulan Log:0 adlı bir tensör olan #88'e odaklanır. Göze çarpan bir pembe-kırmızı renk, 2D float32 tensörünün 1000 öğesi arasında bir -∞ öğesini vurgular. Bu, TF2 programının çalışma zamanı geçmişinde herhangi bir NaN veya sonsuz içeren ilk tensördür: ondan önce hesaplanan tensörler NaN veya ∞ içermez; daha sonra hesaplanan birçok (aslında, çoğu) tensör NaN içerir. Bunu Graph Execution listesinde yukarı ve aşağı kaydırarak onaylayabiliriz. Bu gözlem, Log op'un bu TF2 programındaki sayısal kararsızlığın kaynağı olduğuna dair güçlü bir ipucu sağlar.

Hata Ayıklayıcı V2: Nan / Infinity uyarıları ve grafik yürütme listesi

Bu Log işlemi neden -∞ tükürüyor? Bu soruyu cevaplamak, operasyona girdiyi incelemeyi gerektirir. Tensörün adına ( Log:0 ) tıklamak, Log op'un çevresinin Grafik Yapısı bölümündeki TensorFlow grafiğinde basit ama bilgilendirici bir görselleştirmesini getirir. Bilgi akışının yukarıdan aşağıya yönüne dikkat edin. Operasyonun kendisi ortadaki kalın harflerle gösterilmiştir. Hemen üzerinde, Log op'a tek ve tek girdi sağlayan bir Placeholder op'u görebiliriz. Grafik Yürütme listesinde bu probs Yer Tutucusu tarafından oluşturulan tensör nerede? Sarı arka plan rengini görsel bir yardım olarak kullanarak, probs:0 tensörünün Log:0 tensörünün üç satır üstünde, yani 85. satırda olduğunu görebiliriz.

Hata Ayıklayıcı V2: Grafik yapısı görünümü ve giriş tensörüne yönelik izleme

85. satırdaki probs:0 tensörünün sayısal dağılımına daha dikkatli bir bakış, tüketici Log:0 neden bir -∞: ürettiğini ortaya çıkarır probs:0 1000 öğesi arasında, bir öğenin değeri 0'dır. -∞ 0'ın doğal logaritmasını hesaplamanın bir sonucu! Log işleminin yalnızca pozitif girdilere maruz kalmasını bir şekilde sağlayabilirsek, NaN/∞'nin olmasını önleyebiliriz. Bu, Placeholder probs tensörüne kırpma uygulanarak (örneğin, tf.clip_by_value() kullanılarak) gerçekleştirilebilir.

Hatayı çözmeye yaklaşıyoruz, ancak henüz tam olarak bitmedi. Düzeltmeyi uygulamak için, Log op ve onun Placeholder girdisinin Python kaynak kodunda nereden geldiğini bilmemiz gerekiyor. Hata Ayıklayıcı V2, grafik operasyonlarını ve yürütme olaylarını kaynaklarına kadar izlemek için birinci sınıf destek sağlar. Graph Executions'da Log:0 tensörünü tıklattığımızda, Stack Trace bölümü Log op'un yarattığı orijinal stack trace ile dolduruldu. Yığın izlemesi, çoğu hata ayıklama görevinde güvenle göz ardı edebileceğimiz TensorFlow'un dahili kodundan (örneğin, gen_math_ops.py ve dumping_callback.py) birçok kare içerdiğinden biraz büyüktür. İlgilenilen çerçeve, debug_mnist_v2.py'nin 216. satırıdır (yani, aslında hata ayıklamaya çalıştığımız Python dosyası). “Satır 216”ya tıklamak, Kaynak Kodu bölümünde ilgili kod satırının bir görünümünü getirir.

Hata Ayıklayıcı V2: Kaynak kodu ve yığın izleme

Bu nihayet bizi probs girişinden sorunlu Log op'u oluşturan kaynak koduna getiriyor. Bu, @tf.function ile süslenmiş ve dolayısıyla bir TensorFlow grafiğine dönüştürülmüş özel kategorik çapraz entropi kaybı fonksiyonumuzdur. Placeholder op probs , kayıp fonksiyonunun ilk girdi argümanına karşılık gelir. Log işlemi, tf.math.log() API çağrısı ile oluşturulur.

Bu hatanın değer kırpma düzeltmesi şöyle görünecek:

  diff = -(labels *
           tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))

Bu TF2 programındaki sayısal kararsızlığı giderecek ve MLP'nin başarılı bir şekilde eğitilmesine neden olacaktır. Sayısal kararsızlığı düzeltmeye yönelik bir başka olası yaklaşım da tf.keras.losses.CategoricalCrossentropy kullanmaktır.

Bu, bir TF2 model hatasını gözlemlemekten, sayısal özetler de dahil olmak üzere, enstrümanlı TF2 programının istekli ve grafik yürütme geçmişine tam görünürlük sağlayan Hata Ayıklayıcı V2 aracının yardımıyla hatayı düzelten bir kod değişikliği bulmaya kadar olan yolculuğumuza son veriyor. tensör değerleri ve ops, tensörler ve orijinal kaynak kodları arasındaki ilişki.

Hata Ayıklayıcı V2'nin donanım uyumluluğu

Hata Ayıklayıcı V2, CPU ve GPU dahil genel eğitim donanımını destekler. tf.distributed.MirroredStrategy ile çoklu GPU eğitimi de desteklenir. TPU desteği hala erken bir aşamadadır ve arama yapılmasını gerektirir

tf.config.set_soft_device_placement(True)

enable_dump_debug_info() çağırmadan önce. TPU'larda başka sınırlamaları da olabilir. Hata Ayıklayıcı V2'yi kullanırken sorun yaşarsanız, lütfen hataları GitHub sorunları sayfamızdan bildirin .

Hata Ayıklayıcı V2'nin API uyumluluğu

Hata Ayıklayıcı V2, nispeten düşük bir TensorFlow yazılım yığını düzeyinde uygulanır ve bu nedenle tf.keras , tf.data ve TensorFlow'un alt düzeylerinin üzerine inşa edilmiş diğer API'lerle uyumludur. Hata Ayıklayıcı V2, TF1 ile geriye dönük olarak da uyumludur, ancak Eager Yürütme Zaman Çizelgesi, TF1 programları tarafından oluşturulan hata ayıklama günlük dizinleri için boş olacaktır.

API kullanım ipuçları

Bu hata ayıklama API'si hakkında sık sorulan bir soru, TensorFlow kodunda birinin enable_dump_debug_info() çağrısını eklemesi gerektiğidir. Tipik olarak, API, TF2 programınızda, tercihen Python içe aktarma satırlarından sonra ve grafik oluşturma ve yürütme başlamadan önce mümkün olduğunca erken çağrılmalıdır. Bu, modelinize ve eğitimine güç veren tüm operasyonların ve grafiklerin tam olarak kapsanmasını sağlayacaktır.

Şu anda desteklenen tensor_debug_modları şunlardır: NO_TENSOR , CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH ve SHAPE . Her bir tensörden çıkarılan bilgi miktarına ve hata ayıklanmış programın performans yüküne göre değişirler. Lütfen enable_dump_debug_info() 'nın belgelerinin argümanlar bölümüne bakın.

Performans yükü

Hata ayıklama API'si, enstrümanlı TensorFlow programına performans ek yükü getirir. Ek yük, tensor_debug_mode , donanım türü ve enstrümanlı TensorFlow programının doğasına göre değişir. Referans noktası olarak, GPU'da NO_TENSOR modu, toplu iş boyutu 64 altında bir Transformer modelinin eğitimi sırasında %15 ek yük ekler. Diğer tensor_debug_modları için ek yük yüzdesi daha yüksektir: CURT_HEALTH , CONCISE_HEALTH , FULL_HEALTH ve SHAPE için yaklaşık %50 modlar. CPU'larda, ek yük biraz daha düşüktür. TPU'larda, ek yük şu anda daha yüksektir.

Diğer TensorFlow hata ayıklama API'leriyle ilişkisi

TensorFlow'un hata ayıklama için başka araçlar ve API'ler sunduğunu unutmayın. API belgeleri sayfasındaki tf.debugging.* ad alanı altında bu tür API'lere göz atabilirsiniz. Bu API'ler arasında en sık kullanılanı tf.print() 'tir. Debugger V2 ne zaman kullanılmalı ve bunun yerine ne zaman tf.print() kullanılmalıdır? tf.print() şu durumlarda uygundur:

  1. tam olarak hangi tensörlerin yazdırılacağını biliyoruz,
  2. bu tf.print() deyimlerini kaynak kodun tam olarak neresine ekleyeceğimizi biliyoruz,
  3. bu tür tensörlerin sayısı çok fazla değildir.

Diğer durumlar için (örneğin, birçok tensör değerinin incelenmesi, TensorFlow'un dahili kodu tarafından oluşturulan tensör değerlerinin incelenmesi ve yukarıda gösterdiğimiz gibi sayısal kararsızlığın kaynağının aranması), Hata Ayıklayıcı V2, hata ayıklamanın daha hızlı bir yolunu sağlar. Ek olarak, Debugger V2, istekli ve grafik tensörleri denetlemek için birleşik bir yaklaşım sağlar. Ayrıca, tf.print() yeteneğinin ötesinde olan grafik yapısı ve kod konumları hakkında bilgi sağlar.

∞ ve NaN içeren sorunların hatalarını ayıklamak için kullanılabilecek başka bir API tf.debugging.enable_check_numerics() 'dir. enable_dump_debug_info() farklı olarak, enable_check_numerics() hata ayıklama bilgilerini diske kaydetmez. Bunun yerine, TensorFlow çalışma zamanı sırasında yalnızca ∞ ve NaN'yi izler ve herhangi bir işlem bu kadar kötü sayısal değerler üretir üretmez orijin kodu konumuyla ilgili hataları giderir. enable_dump_debug_info() ile karşılaştırıldığında daha düşük bir performans yüküne sahiptir, ancak programın yürütme geçmişinin tam izini vermez ve Debugger V2 gibi bir grafik kullanıcı arabirimiyle birlikte gelmez.