Eğitim sırasında nans'ın yaygın nedenleri


86

Eğitim sırasında sık sık karşılaşılan bir olay olduğunu fark ettim NAN.

Çoğu zaman, iç üründeki / tam bağlantılı veya şişen evrişim katmanlarındaki ağırlıklar tarafından ortaya çıkarılmış gibi görünmektedir.

Bu, gradyan hesaplaması patladığı için mi oluyor? Yoksa bunun nedeni ağırlık başlatma mıdır (öyleyse, ağırlık başlatma neden bu etkiye sahiptir)? Yoksa giriş verilerinin doğasından mı kaynaklanıyor olabilir?

Buradaki kapsayıcı soru basitçe şudur: Eğitim sırasında NAN'ların ortaya çıkmasının en yaygın nedeni nedir? İkincisi, bununla mücadele için bazı yöntemler nelerdir (ve neden işe yarıyorlar)?


Belirli MATLAB işlevlerini mi arıyorsunuz? Hepsi kendi kodunuz mu?
Matthew Gunn

2
@MatthewGunn Bu sorunun matlab'a özgü olduğunu düşünmüyorum, daha çok caffeilişkili.
Shai

Yanıtlar:


137

İyi soru.
Bu fenomenle birkaç kez karşılaştım. İşte gözlemlerim:


Gradyan patlaması

Sebep: Büyük gradyanlar öğrenme sürecini yoldan çıkarır.

Beklemeniz gerekenler: Çalışma zamanı günlüğüne baktığınızda, yineleme başına kayıp değerlerine bakmalısınız. Kaybın yinelemeden yinelemeye önemli ölçüde artmaya başladığını fark edeceksiniz , sonunda kayıp bir kayan nokta değişkeni ile temsil edilemeyecek kadar büyük olacak ve bu hale gelecektir nan.

Ne yapabilirsiniz:base_lr (çözücü.prototxt dosyasında) bir büyüklük sırasıyla (en azından) azaltın . Birkaç kayıp katmanınız varsa, gradyan patlamasından hangi katmanın sorumlu olduğunu görmek için günlüğü incelemeniz loss_weightve genel katman yerine o belirli katman için (in train_val.prototxt) değerini azaltmanız gerekir base_lr.


Kötü öğrenme oranı politikası ve parametreleri

Sebep: caffe geçerli bir öğrenme oranını hesaplayamaz ve alır 'inf'veya 'nan'onun yerine, bu geçersiz oran tüm güncellemeleri çarparak tüm parametreleri geçersiz kılar.

Beklemeniz gerekenler: Çalışma zamanı günlüğüne baktığınızda, öğrenme oranının kendisinin olduğunu görmelisiniz 'nan', örneğin:

... sgd_solver.cpp:106] Iteration 0, lr = -nan

Ne yapabilirsiniz:'solver.prototxt' Dosyanızdaki öğrenme oranını etkileyen tüm parametreleri düzeltin .
Örneğin, kullanırsanız lr_policy: "poly"ve max_iterparametre tanımlamayı unutursanız , sonuçta lr = nan...
Kafede öğrenme oranı hakkında daha fazla bilgi için bu konuya bakın .


Hatalı Kayıp işlevi

Sebep: Bazen kayıp katmanlarındaki kayıp hesaplamaları nans görünmesine neden olur . Örneğin, InfogainLossnormalize edilmemiş değerlere sahip Besleme katmanı, hatalarla özel kayıp katmanı kullanma vb.

Beklemeniz gerekenler: Çalışma zamanı günlüğüne baktığınızda muhtemelen olağandışı bir şey fark etmeyeceksiniz: kayıp yavaş yavaş azalıyor ve aniden bir nanbeliriyor.

Ne yapabilirsiniz: Hatayı yeniden üretip üretemeyeceğinizi görün, çıktıyı kayıp katmanına ekleyin ve hatayı ayıklayın.

Örneğin: Bir keresinde cezayı bir partide etiket oluşma sıklığına göre normalleştiren bir kayıp kullandım. Öyle oldu ki, eğitim etiketlerinden biri partide hiç görünmüyorsa - hesaplanan kayıp nans. Bu durumda, yeterince büyük partilerle çalışmak (setteki etiketlerin sayısına göre) bu hatayı önlemek için yeterliydi.


Hatalı giriş

Sebep:nan İçinde bir girdiniz var!

Beklemeniz gerekenler: öğrenme süreci bu hatalı girdiye "ulaştığında" - çıktı olur nan. Çalışma zamanı günlüğüne baktığınızda muhtemelen olağandışı bir şey fark etmeyeceksiniz: kayıp yavaş yavaş azalıyor ve birdenbire nanortaya çıkıyor.

Ne yapabilirsiniz: giriş veri kümelerinizi yeniden oluşturun (lmdb / leveldn / hdf5 ...) eğitim / doğrulama kümenizde kötü görüntü dosyalarının bulunmadığından emin olun. Hata ayıklama için, giriş katmanını okuyan, üzerinde sahte bir kayıp olan ve tüm girişleri çalıştıran basit bir ağ oluşturabilirsiniz: eğer bunlardan biri hatalıysa, bu sahte ağ da üretmelidir nan.


"Pooling"katmanda çekirdek boyutundan daha büyük adımlarla ilerlemek

Bazı nedenlerden dolayı, havuzlama için stride> seçilmesi s kernel_sizeile sonuçlanabilir nan. Örneğin:

layer {
  name: "faulty_pooling"
  type: "Pooling"
  bottom: "x"
  top: "y"
  pooling_param {
    pool: AVE
    stride: 5
    kernel: 3
  }
}

nans ile sonuçlanır y.


Dengesizlikler "BatchNorm"

Bazı ayarlar "BatchNorm"katmanında nansayısal kararsızlıklardan dolayı çıktı verilebileceği bildirildi .
Bu sorun bvlc / caffe'de ortaya çıktı ve PR # 5136 bunu düzeltmeye çalışıyor.


Kısa bir süre önce, debug_infoişaretin ayarlanması debug_info: true, 'solver.prototxt'caffe print'in eğitim sırasında daha fazla hata ayıklama bilgisini (gradyan büyüklükleri ve aktivasyon değerleri dahil) günlüğe kaydetmesini sağlayacaktır: Bu bilgi , eğitim sürecindeki gradyan patlamalarını ve diğer sorunları tespit etmeye yardımcı olabilir .


Teşekkürler, bu rakamlar nasıl yorumlanır? Bu numaralar nedir? pastebin.com/DLYgXK5v neden katman çıktısı başına yalnızca bir sayı var !? Bu sayılar nasıl görünmeli ki birisi bir problem olduğunu veya olmadığını anlasın !?
Rika

Bu @Hossein tam olarak ne bu yazı tüm ilgili.
Shai

Bu cevap için teşekkürler. DICE kaybıyla eğitilmiş bir görüntü bölütleme uygulaması için NAN kaybı alıyorum (küçük bir epsilon / pürüzsüzlük sabiti ekledikten sonra bile). Veri setim, ilgili temel gerçekleri herhangi bir ön plan etiketi içermeyen bazı görüntüler içeriyor ve bu görüntüleri eğitimden çıkardığımda, kayıp dengelendi. Bunun neden olduğundan emin değilim?
samra irshad

@samrairshad DICE kaybında epsilon'u artırmayı denediniz mi?
Shai

Evet yaptım. Yazıyı stack-overflow'da açtım ve bazı dönemler için kayıp evrimini yapıştırdım. İşte referans: stackoverflow.com/questions/62259112/…
samra irshad

5

Benim durumumda, neden evrişim / ters evrişim katmanlarında önyargının ayarlanmamasıydı.

Çözüm: Aşağıdakileri evrişim katmanı parametrelerine ekleyin.

bias_filler {tür: "sabit" değer: 0}


bu matconvnet'te nasıl görünür? 'Önyargılar' gibi bir şeyim var. İnit_bias * ones (1,4, single)
h612

4

Bu yanıt, yanıtın nedeniyle ilgili değildir nan, daha çok hata ayıklamaya yardımcı olacak bir yol önerir. Bu python katmanına sahip olabilirsiniz:

class checkFiniteLayer(caffe.Layer):
  def setup(self, bottom, top):
    self.prefix = self.param_str
  def reshape(self, bottom, top):
    pass
  def forward(self, bottom, top):
    for i in xrange(len(bottom)):
      isbad = np.sum(1-np.isfinite(bottom[i].data[...]))
      if isbad>0:
        raise Exception("checkFiniteLayer: %s forward pass bottom %d has %.2f%% non-finite elements" %
                        (self.prefix,i,100*float(isbad)/bottom[i].count))
  def backward(self, top, propagate_down, bottom):
    for i in xrange(len(top)):
      if not propagate_down[i]:
        continue
      isf = np.sum(1-np.isfinite(top[i].diff[...]))
        if isf>0:
          raise Exception("checkFiniteLayer: %s backward pass top %d has %.2f%% non-finite elements" %
                          (self.prefix,i,100*float(isf)/top[i].count))

Bu katmanı train_val.prototxtşüphelendiğiniz belirli noktalarda eklemek sorunlara neden olabilir:

layer {
  type: "Python"
  name: "check_loss"
  bottom: "fc2"
  top: "fc2"  # "in-place" layer
  python_param {
    module: "/path/to/python/file/check_finite_layer.py" # must be in $PYTHONPATH
    layer: "checkFiniteLayer"
    param_str: "prefix-check_loss" # string for printouts
  }
}

1

öğrenme hızı yüksektir ve azaltılmalıdır RNN kodundaki doğruluk nan idi, düzelttiği öğrenme hızı için düşük değeri seçin


-1

Seyrek bir otomatik kodlayıcı oluşturmaya çalışıyordum ve seyrekliği tetiklemek için içinde birkaç katman vardı. Ağımı çalıştırırken NaN'lerle karşılaştım. Bazı katmanları kaldırırken (benim durumumda aslında 1'i kaldırmak zorunda kaldım), NaN'nin kaybolduğunu gördüm. Bu yüzden, çok fazla seyreklik de NaN'lere yol açabilir (bazı 0/0 hesaplamaları başlatılmış olabilir !?)


Biraz daha spesifik olabilir misiniz? 'e sahip konfigürasyon nanve sabit konfigürasyon hakkında ayrıntılar verebilir misiniz ? ne tür katmanlar? hangi parametreler?
Shai

1
@shai Birkaç InnerProduct (lr_mult 1, decay_mult 1, lr_mult 2, decay_mult 0, xavier, std: 0.01) katmanı kullandım ve ardından ReLU (sonuncusu hariç). MNIST ile çalışıyordum ve doğru hatırlıyorsam mimari 784 -> 1000 -> 500 -> 250 -> 100 -> 30'du (ve simetrik bir kod çözücü aşaması); 30 katmanı ReLU ile birlikte kaldırmak, NaN'leri yok etti.
LKB
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.