Dobre pytanie.
Z tym zjawiskiem spotkałem się kilkakrotnie. Oto moje spostrzeżenia:
Gradientowy wysadzenie
Powód: duże wzniesienia utrudniają naukę.
Czego powinieneś się spodziewać: Patrząc na dziennik czasu wykonywania, powinieneś spojrzeć na wartości strat na iterację. Zauważysz, że strata zaczyna znacznie rosnąć od iteracji do iteracji, ostatecznie strata będzie zbyt duża, aby była reprezentowana przez zmienną zmiennoprzecinkową i stanie się nan
.
Co możesz zrobić: Zmniejsz base_lr
(w solver.prototxt) o rząd wielkości (przynajmniej). Jeśli masz kilka warstw strat, powinieneś sprawdzić dziennik, aby zobaczyć, która warstwa jest odpowiedzialna za wysadzenie gradientu i zmniejszyć loss_weight
(w train_val.prototxt) dla tej konkretnej warstwy, zamiast ogólnej base_lr
.
Zasady i parametry dotyczące nieprawidłowego tempa uczenia się
Powód: caffe nie może obliczyć prawidłowego współczynnika uczenia się i pobiera 'inf'
lub 'nan'
zamiast tego, ta nieprawidłowa stawka mnoży wszystkie aktualizacje, a tym samym unieważnia wszystkie parametry.
Czego powinieneś się spodziewać: Patrząc na dziennik czasu działania, powinieneś zobaczyć, że sam współczynnik uczenia się zmienia się 'nan'
na przykład:
... sgd_solver.cpp:106] Iteration 0, lr = -nan
Co możesz zrobić: naprawić wszystkie parametry wpływające na szybkość uczenia się w 'solver.prototxt'
pliku.
Na przykład, jeśli użyjesz lr_policy: "poly"
i zapomnisz zdefiniować max_iter
parametr, otrzymasz lr = nan
...
Więcej informacji o tempie uczenia się w kawie znajdziesz w tym wątku .
Wadliwa funkcja utraty
Przyczyna: czasami obliczenia strat w warstwach strat powodują nan
pojawienie się s. Na przykład InfogainLoss
warstwa karmienia z nieznormalizowanymi wartościami , używanie niestandardowej warstwy strat z błędami itp.
Czego powinieneś się spodziewać: Patrząc na dziennik działania, prawdopodobnie nie zauważysz niczego niezwykłego: utrata stopniowo maleje i nagle nan
pojawia się.
Co możesz zrobić: Sprawdź, czy możesz odtworzyć błąd, dodaj wydruk do warstwy strat i zdebuguj błąd.
Na przykład: Kiedyś zastosowałem stratę, która znormalizowała karę na podstawie częstotliwości występowania etykiety w partii. Tak się złożyło, że jeśli jedna z etykiet uczących w ogóle nie pojawiła się w partii - obliczona strata wyprodukowana nan
s. W takim przypadku wystarczyła praca z odpowiednio dużymi partiami (biorąc pod uwagę liczbę etykiet w zestawie), aby uniknąć tego błędu.
Wadliwe wejście
Powód: masz w tym wkład nan
!
Czego powinieneś się spodziewać: gdy proces uczenia się „trafi” na to błędne dane wejściowe - wyjście staje się nan
. Patrząc na dziennik działania, prawdopodobnie nie zauważysz nic niezwykłego: strata stopniowo maleje i nagle nan
pojawia się.
Co możesz zrobić: odbuduj swoje wejściowe zbiory danych (lmdb / leveldn / hdf5 ...) upewnij się, że nie masz złych plików graficznych w swoim zestawie treningowym / walidacyjnym. W celu debugowania możesz zbudować prostą sieć, która odczytuje warstwę wejściową, ma na sobie fałszywą stratę i przechodzi przez wszystkie dane wejściowe: jeśli jedno z nich jest wadliwe, ta atrapa sieci również powinna produkować nan
.
krok większy niż rozmiar jądra w "Pooling"
warstwie
Z jakiegoś powodu wybranie stride
> kernel_size
do łączenia może skutkować nan
s. Na przykład:
layer {
name: "faulty_pooling"
type: "Pooling"
bottom: "x"
top: "y"
pooling_param {
pool: AVE
stride: 5
kernel: 3
}
}
wyniki z nan
s in y
.
Niestabilności w "BatchNorm"
Zgłoszono, że pod niektórymi ustawieniami "BatchNorm"
warstwa może wyprowadzać nan
s z powodu niestabilności numerycznych.
Ten problem został zgłoszony w bvlc / caffe i PR # 5136 próbuje go naprawić.
Ostatnio zdałem sobie sprawę z debug_info
flagą: ustawienie debug_info: true
w 'solver.prototxt'
uczyni drukiem caffe zalogowania więcej informacji debugowania (w tym wielkości i wartości gradientu aktywacja) podczas treningu: Ta informacja może pomóc w plamienie wybuchy gradientu i inne problemy w procesie szkolenia .