Percebi que uma ocorrência frequente durante o treinamento está NAN
sendo introduzida.
Freqüentemente, parece ser introduzido por pesos em camadas de produto interno / totalmente conectadas ou de convolução explodindo.
Isso está ocorrendo porque o cálculo do gradiente está explodindo? Ou é por causa da inicialização do peso (em caso afirmativo, por que a inicialização do peso tem esse efeito)? Ou provavelmente é causado pela natureza dos dados de entrada?
A questão abrangente aqui é simplesmente: Qual é o motivo mais comum para os NANs ocorrerem durante o treinamento? E em segundo lugar, quais são alguns métodos para combater isso (e por que funcionam)?
caffe
relacionada.Respostas:
Boa pergunta.
Eu me deparei com esse fenômeno várias vezes. Aqui estão minhas observações:
Gradiente explodir
Motivo: grandes gradientes desviam o processo de aprendizagem do caminho.
O que você deve esperar: Olhando o log de tempo de execução, você deve olhar os valores de perda por iteração. Você notará que a perda começa a crescer significativamente de iteração para iteração, eventualmente a perda será muito grande para ser representada por uma variável de ponto flutuante e se tornará
nan
.O que você pode fazer: Diminua o
base_lr
(no solver.prototxt) em uma ordem de magnitude (pelo menos). Se você tiver várias camadas de perda, deve inspecionar o log para ver qual camada é responsável pela explosão do gradiente e diminuirloss_weight
(em train_val.prototxt) para essa camada específica, em vez da geralbase_lr
.Política de taxa de aprendizagem e parâmetros ruins
Motivo: o caffe falha ao calcular uma taxa de aprendizado válida e obtém
'inf'
ou'nan'
, em vez disso, essa taxa inválida multiplica todas as atualizações e, portanto, invalidando todos os parâmetros.O que você deve esperar: olhando para o log do tempo de execução, você deve ver que a própria taxa de aprendizagem se torna
'nan'
, por exemplo:O que você pode fazer: corrigir todos os parâmetros que afetam a taxa de aprendizagem em seu
'solver.prototxt'
arquivo.Por exemplo, se você usar
lr_policy: "poly"
e esquecer de definir omax_iter
parâmetro, você acabará comlr = nan
...Para obter mais informações sobre a taxa de aprendizado no caffe, consulte este tópico .
Função de perda defeituosa
Motivo: às vezes, os cálculos da perda nas camadas de perda fazem com que
nan
s apareça. Por exemplo,InfogainLoss
camada de alimentação com valores não normalizados , usando camada de perda personalizada com bugs, etc.O que você deve esperar: ao examinar o log de tempo de execução, você provavelmente não notará nada de incomum: a perda está diminuindo gradualmente e, de repente, um a
nan
aparece.O que você pode fazer: veja se consegue reproduzir o erro, adicione impressão à camada de perda e depure o erro.
Por exemplo: Uma vez eu usei uma perda que normalizou a penalidade pela frequência de ocorrência do rótulo em um lote. Acontece que, se um dos rótulos de treinamento não aparecesse no lote - a perda calculada produzia
nan
s. Nesse caso, trabalhar com lotes grandes o suficiente (no que diz respeito ao número de etiquetas do conjunto) foi o suficiente para evitar esse erro.Entrada defeituosa
Motivo: você tem uma contribuição
nan
nisso!O que você deve esperar: assim que o processo de aprendizagem "atinge" essa entrada - a saída falha
nan
. Olhando para o log de tempo de execução, você provavelmente não notará nada incomum: a perda está diminuindo gradualmente e, de repente, um anan
aparece.O que você pode fazer: reconstruir seus conjuntos de dados de entrada (lmdb / leveldn / hdf5 ...) certifique-se de não ter arquivos de imagem ruins em seu conjunto de treinamento / validação. Para depuração, você pode construir uma rede simples que lê a camada de entrada, tem uma perda simulada em cima dela e percorre todas as entradas: se uma delas estiver com defeito, essa rede falsa também deve produzir
nan
.passo maior que o tamanho do kernel na
"Pooling"
camadaPor alguma razão, escolher
stride
>kernel_size
para agrupar pode resultar emnan
s. Por exemplo:resultados com
nan
s emy
.Instabilidades em
"BatchNorm"
Foi relatado que, em algumas configurações, a
"BatchNorm"
camada pode gerarnan
s devido a instabilidades numéricas.Este problema foi levantado em bvlc / caffe e PR # 5136 está tentando corrigi-lo.
Recentemente, tornou-se ciente de
debug_info
bandeira: Ajustedebug_info: true
em'solver.prototxt'
vai fazer print caffe para registrar mais informações de depuração (incluindo magnitudes de gradiente e valores de ativação) durante o treino: Esta informação pode ajudar na identificação blowups gradiente e outros problemas no processo de formação .fonte
No meu caso, a causa não foi definir o viés nas camadas de convolução / deconvolução.
Solução: adicione o seguinte aos parâmetros da camada de convolução.
bias_filler {tipo: valor "constante": 0}
fonte
Esta resposta não é sobre uma causa para
nan
s, mas sim propõe uma maneira de ajudar a depurá-lo. Você pode ter esta camada python: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))
Adicionar esta camada em
train_val.prototxt
certos pontos que você suspeita pode causar problemas:fonte
learning_rate é alto e deve ser diminuído A precisão no código RNN era nan, com selecione o valor baixo para a taxa de aprendizado que corrige
fonte
Eu estava tentando construir um autoencoder esparso e tinha várias camadas nele para induzir a esparsidade. Enquanto corria minha rede, encontrei os NaNs. Ao remover algumas das camadas (no meu caso, eu realmente tive que remover 1), descobri que os NaNs desapareceram. Então, eu acho que muita dispersão pode levar a NaNs também (alguns cálculos 0/0 podem ter sido invocados !?)
fonte
nan
a configuração fixa? que tipo de camadas? quais parâmetros?