Buona domanda.
Mi sono imbattuto in questo fenomeno più volte. Ecco le mie osservazioni:
Gradiente esplodere
Motivo: grandi gradienti mettono fuori strada il processo di apprendimento.
Cosa dovresti aspettarti: guardando il registro di runtime, dovresti guardare i valori di perdita per iterazione. Noterai che la perdita inizia a crescere in modo significativo da iterazione a iterazione, alla fine la perdita sarà troppo grande per essere rappresentata da una variabile in virgola mobile e lo diventerà nan
.
Cosa puoi fare: Diminuisci base_lr
(nel solver.prototxt) di un ordine di grandezza (almeno). Se hai diversi livelli di perdita, dovresti ispezionare il registro per vedere quale livello è responsabile loss_weight
dell'esplosione del gradiente e diminuire il (in train_val.prototxt) per quel livello specifico, invece del generale base_lr
.
Cattiva politica e parametri del tasso di apprendimento
Motivo: caffe non riesce a calcolare un tasso di apprendimento valido e ottiene 'inf'
o 'nan'
, invece, questo tasso non valido moltiplica tutti gli aggiornamenti e quindi invalida tutti i parametri.
Cosa dovresti aspettarti: guardando il registro di runtime, dovresti vedere che il tasso di apprendimento stesso diventa 'nan'
, ad esempio:
... sgd_solver.cpp:106] Iteration 0, lr = -nan
Cosa puoi fare: correggi tutti i parametri che influenzano la velocità di apprendimento nel tuo 'solver.prototxt'
file.
Ad esempio, se usi lr_policy: "poly"
e dimentichi di definire il max_iter
parametro, ti ritroverai con lr = nan
...
Per ulteriori informazioni sulla velocità di apprendimento in caffe, vedi questo thread .
Funzione di perdita difettosa
Motivo: a volte i calcoli della perdita negli strati di perdita fanno nan
apparire s. Ad esempio, InfogainLoss
livello di alimentazione con valori non normalizzati , utilizzo di livello di perdita personalizzato con bug, ecc.
Cosa dovresti aspettarti: guardando il registro di runtime probabilmente non noterai nulla di insolito: la perdita sta diminuendo gradualmente e all'improvviso nan
appare un .
Cosa puoi fare: verifica se riesci a riprodurre l'errore, aggiungi la stampa al livello di perdita ed esegui il debug dell'errore.
Ad esempio: una volta ho utilizzato una perdita che normalizzava la penalità in base alla frequenza di occorrenza dell'etichetta in un batch. È successo che se una delle etichette di addestramento non appariva affatto nel batch, la perdita calcolata produceva nan
s. In quel caso, lavorare con lotti abbastanza grandi (rispetto al numero di etichette nel set) è stato sufficiente per evitare questo errore.
Ingresso difettoso
Motivo: hai un input con nan
dentro!
Cosa dovresti aspettarti: una volta che il processo di apprendimento "raggiunge" questo errore di input - output diventa nan
. Guardando il registro di runtime probabilmente non noterai nulla di insolito: la perdita diminuisce gradualmente e all'improvviso nan
appare un .
Cosa puoi fare: ricostruire i tuoi set di dati di input (lmdb / leveldn / hdf5 ...) assicurati di non avere file di immagini errati nel tuo set di addestramento / convalida. Per il debug puoi costruire una semplice rete che legge lo strato di input, ha una perdita fittizia sopra di essa e percorre tutti gli input: se uno di loro è difettoso, dovrebbe produrre anche questa falsa rete nan
.
passo più grande della dimensione del kernel nel "Pooling"
livello
Per qualche ragione, la scelta di stride
> kernel_size
per il raggruppamento potrebbe risultare con nan
s. Per esempio:
layer {
name: "faulty_pooling"
type: "Pooling"
bottom: "x"
top: "y"
pooling_param {
pool: AVE
stride: 5
kernel: 3
}
}
risultati con nan
s in y
.
Instabilità in "BatchNorm"
È stato riferito che in alcuni "BatchNorm"
livelli di impostazioni potrebbero essere emessi dei messaggi a nan
causa di instabilità numeriche.
Questo problema è stato sollevato in bvlc / caffe e PR # 5136 sta tentando di risolverlo.
Recentemente, sono venuto a conoscenza del debug_info
flag: l'impostazione debug_info: true
in 'solver.prototxt'
farà stampare caffe per registrare più informazioni di debug (comprese le grandezze del gradiente e i valori di attivazione) durante l'allenamento: queste informazioni possono aiutare a individuare ingrandimenti di gradiente e altri problemi nel processo di allenamento .