O que devo fazer quando minha rede neural não aprende?

147

Estou treinando uma rede neural, mas a perda de treinamento não diminui. Como posso consertar isso?

Não estou perguntando sobre ajuste excessivo ou regularização. Estou perguntando como resolver o problema em que o desempenho da minha rede não melhora no conjunto de treinamento .


Essa questão é intencionalmente geral, de modo que outras questões sobre como treinar uma rede neural possam ser encerradas como duplicata, com a atitude de que "se você dá um peixe a um homem, você o alimenta por um dia, mas se você ensina um homem a pescar, você pode alimentá-lo pelo resto da vida ". Veja este tópico do Meta para uma discussão: Qual é a melhor maneira de responder perguntas "minha rede neural não funciona, por favor, corrija"?

Se sua rede neural não se generaliza bem, consulte: O que devo fazer quando minha rede neural não se generaliza bem?

Sycorax
fonte
11
Aqui está o caso em que o NN não pôde progredir. youtu.be/iakFfOmanJU?t=144
Joshua
4
O blog de Ivanov " Razões pelas quais sua rede neural não está funcionando ", especialmente as seções II, III e IV, pode ser útil.
user5228

Respostas:

187

O teste de unidade é seu amigo

Há um ditado entre os escritores que "Toda escrita é reescrita" - ou seja, a maior parte da escrita está sendo revisada. Para programadores (ou pelo menos cientistas de dados), a expressão poderia ser reformulada como "Toda a codificação está depurando".

Sempre que você estiver escrevendo um código, é necessário verificar se ele funciona como pretendido. O melhor método que eu já encontrei para verificar a correção é dividir seu código em pequenos segmentos e verificar se cada segmento funciona. Isso pode ser feito comparando a saída do segmento com o que você sabe ser a resposta correta. Isso é chamado de teste de unidade . Escrever bons testes de unidade é uma peça essencial para se tornar um bom estatístico / cientista de dados / especialista em aprendizado de máquina / praticante de redes neurais. Simplesmente não há substituto.

Você precisa verificar se seu código está livre de bugs antes de ajustar o desempenho da rede! Caso contrário, você poderá reorganizar as cadeiras de praia no RMS Titanic .

Existem duas características das redes neurais que tornam a verificação ainda mais importante do que para outros tipos de aprendizado de máquina ou modelos estatísticos.

  1. As redes neurais não são algoritmos "prontos para uso" da mesma forma que a floresta aleatória ou a regressão logística. Mesmo para redes simples e de feed-forward, o ônus é principalmente do usuário tomar várias decisões sobre como a rede é configurada, conectada, inicializada e otimizada. Isso significa escrever código, e escrever código significa depuração.

  2. Mesmo quando um código de rede neural é executado sem gerar uma exceção, a rede ainda pode ter erros! Esses bugs podem até ser do tipo insidioso para o qual a rede treinará, mas ficarem presos em uma solução subótima ou a rede resultante não possui a arquitetura desejada. ( Este é um exemplo da diferença entre um erro sintático e semântico .)

Esta publicação do Medium , " Como código de aprendizado de máquina para teste de unidade ", de Chase Roberts, discute o teste de unidade para modelos de aprendizado de máquina com mais detalhes. Peguei emprestado este exemplo de código de buggy do artigo:

def make_convnet(input_image):
    net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
    net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool2')
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool3')
    net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
    return net

Você vê o erro? Muitas das operações diferentes não são realmente usadas porque os resultados anteriores são substituídos por novas variáveis. O uso desse bloco de código em uma rede ainda treinará e os pesos serão atualizados e a perda poderá até diminuir - mas o código definitivamente não está fazendo o que foi planejado. (O autor também é inconsistente quanto ao uso de aspas simples ou duplas, mas isso é puramente estilístico.)

Os erros de programação mais comuns pertencentes às redes neurais são

  • Variáveis ​​são criadas, mas nunca usadas (geralmente devido a erros de copiar e colar);
  • As expressões para atualizações de gradiente estão incorretas;
  • As atualizações de peso não são aplicadas;
  • As funções de perda não são medidas na escala correta (por exemplo, a perda de entropia cruzada pode ser expressa em termos de probabilidade ou logits)
  • A perda não é apropriada para a tarefa (por exemplo, usando a perda de entropia cruzada categórica para uma tarefa de regressão).

Rastrear antes de andar; Caminhe antes de executar

Redes neurais amplas e profundas, e redes neurais com fiação exótica, são a coisa mais importante no momento em aprendizado de máquina. Mas essas redes não surgiram totalmente formadas; seus designers construíram para eles a partir de unidades menores. Primeiro, construa uma pequena rede com uma única camada oculta e verifique se ela funciona corretamente. Em seguida, adicione incrementalmente a complexidade adicional do modelo e verifique se cada um deles também funciona.

  • Muito poucos neurónios em uma camada pode restringir a representação que a rede aprende, causando sub-montagem. Muitos neurônios podem causar excesso de ajustes, porque a rede "memoriza" os dados do treinamento.

    Mesmo que você possa provar que, matematicamente, apenas um pequeno número de neurônios é necessário para modelar um problema, geralmente ocorre que ter "mais alguns" neurônios facilita o otimizador a encontrar uma configuração "boa". (Mas não creio que alguém entenda completamente por que esse é o caso.) Fornecemos um exemplo disso no contexto do problema XOR aqui: Minhas iterações não são necessárias para treinar NN para XOR com MSE <0,001 muito alto? .

  • Escolher o número de camadas ocultas permite que a rede aprenda uma abstração a partir dos dados brutos. Atualmente, o aprendizado profundo está em alta, e redes com um grande número de camadas têm mostrado resultados impressionantes. Porém, a adição de muitas camadas ocultas pode aumentar o risco de adaptação ou dificultar a otimização da rede.

  • Escolher uma fiação de rede inteligente pode fazer muito trabalho para você. Sua fonte de dados é passível de arquiteturas de rede especializadas? As redes neurais convolucionais podem obter resultados impressionantes em fontes de dados "estruturadas", dados de imagem ou áudio. Redes neurais recorrentes podem se dar bem em tipos de dados seqüenciais, como linguagem natural ou dados de séries temporais. As conexões residuais podem melhorar as redes de alimentação avançada.

O treinamento em rede neural é como uma trava

Para alcançar resultados de última geração, ou mesmo meramente bons, você deve ter configurado todas as peças configuradas para funcionarem bem juntas . Definir uma configuração de rede neural que realmente aprende é como escolher uma trava: todas as peças precisam ser alinhadas da maneira certa. Assim como não é suficiente ter um único copo no lugar certo, também não é suficiente ter apenas a arquitetura ou apenas o otimizador configurados corretamente.

Ajustar as opções de configuração não é tão simples como dizer que um tipo de opção de configuração (por exemplo, taxa de aprendizado) é mais ou menos importante que outro (por exemplo, número de unidades), pois todas essas opções interagem com todas as outras opções, portanto, uma a escolha pode se dar bem em combinação com outra escolha feita em outro lugar .

Esta é uma lista não exaustiva das opções de configuração que também não são opções de regularização ou opções de otimização numérica.

Todos esses tópicos são áreas ativas de pesquisa.

A otimização não convexa é difícil

A função objetivo de uma rede neural é apenas convexa quando não há unidades ocultas, todas as ativações são lineares e a matriz de projeto é de classificação completa - porque essa configuração é identicamente um problema de regressão comum.

Em todos os outros casos, o problema de otimização é não convexo e a otimização não convexa é difícil. Os desafios do treinamento de redes neurais são bem conhecidos (veja: Por que é difícil treinar redes neurais profundas? ). Além disso, as redes neurais têm um número muito grande de parâmetros, o que nos restringe apenas a métodos de primeira ordem (consulte: Por que o método de Newton não é amplamente utilizado no aprendizado de máquina? ). Esta é uma área de pesquisa muito ativa.

  • Definir uma taxa de aprendizado muito alta fará com que a otimização seja divergente, porque você pulará de um lado do "canyon" para o outro. Definir isso muito pequeno impedirá que você faça progressos reais e possivelmente permita que o ruído inerente ao SGD sobrecarregue suas estimativas de gradiente.

  • O recorte de gradiente redimensiona a norma do gradiente se estiver acima de algum limite. Eu costumava pensar que esse era um parâmetro de esquecer e esquecer, normalmente em 1,0, mas descobri que poderia criar um modelo de linguagem LSTM muito melhor definindo-o como 0,25. Não sei por que é isso.

  • O agendamento da taxa de aprendizado pode diminuir a taxa de aprendizado ao longo do treinamento. Na minha experiência, tentar usar o agendamento é muito parecido com o regex : ele substitui um problema ("Como faço para aprender a continuar após uma certa época?") Por dois problemas ("Como faço para aprender a continuar após uma certa época ? "e" Como escolho uma boa programação? "). Outras pessoas insistem que a programação é essencial. Eu vou deixar você decidir.

  • A escolha de um bom tamanho de minibatch pode influenciar indiretamente o processo de aprendizado, pois um minilote maior tenderá a ter uma variação menor ( ) do que um minilote menor. Você deseja que o minilote seja grande o suficiente para ser informativo sobre a direção do gradiente, mas pequeno o suficiente para que o SGD possa regularizar sua rede.

  • Existem várias variantes na descida do gradiente estocástico que usam momento, taxas de aprendizado adaptável, atualizações de Nesterov e assim por diante para melhorar o SGD da baunilha. Projetar um melhor otimizador é uma área de pesquisa ativa. Alguns exemplos:

  • Quando foi lançado, o otimizador de Adam gerou muito interesse. Mas algumas pesquisas recentes descobriram que o SGD com impulso pode superar os métodos de gradiente adaptativo para redes neurais. " O valor marginal dos métodos adaptativos de gradiente no aprendizado de máquina ", de Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro, Benjamin Recht

  • Mas, por outro lado, este artigo muito recente propõe um novo otimizador de taxa de aprendizado adaptativo que supostamente fecha a lacuna entre métodos de taxa adaptativa e SGD com impulso. " Fechando a lacuna de generalização dos métodos de gradiente adaptativo no treinamento de redes neurais profundas " por Jinghui Chen, Quanquan Gu

    Foram observados métodos de gradiente adaptativo, que adotam informações históricas do gradiente para ajustar automaticamente a taxa de aprendizado, generalizando pior que a descida do gradiente estocástico (SGD), com impulso no treinamento de redes neurais profundas. Isso deixa como fechar um problema em aberto na lacuna de generalização dos métodos de gradiente adaptativo. Neste trabalho, mostramos que métodos de gradiente adaptativo, como Adam, Amsgrad, às vezes são "super adaptados". Nós projetamos um novo algoritmo, chamado Método de Estimação de Momento Parcialmente Adaptável (Padam), que unifica Adam / Amsgrad com SGD para obter o melhor dos dois mundos. Experimentos em benchmarks padrão mostram que Padam pode manter uma taxa de convergência rápida como Adam / Amsgrad enquanto generaliza e SGD no treinamento de redes neurais profundas.

Normalização

A escala dos dados pode fazer uma grande diferença no treinamento.

Regularização

A escolha e o ajuste da regularização de rede é uma parte essencial da construção de um modelo que generalize bem (ou seja, um modelo que não seja adequado aos dados de treinamento). No entanto, no momento em que sua rede está lutando para diminuir a perda nos dados de treinamento - quando a rede não está aprendendo - a regularização pode ocultar qual é o problema.

Quando minha rede não aprende, desativo toda a regularização e verifico se a rede não regularizada funciona corretamente. Depois, adiciono cada peça de regularização novamente e verifico se cada uma delas funciona ao longo do caminho.

Essa tática pode identificar onde alguma regularização pode estar mal definida. Alguns exemplos são

Mantenha um diário de experiências

Quando configuro uma rede neural, não codifico nenhuma configuração de parâmetro. Em vez disso, faço isso em um arquivo de configuração (por exemplo, JSON) que é lido e usado para preencher os detalhes de configuração de rede em tempo de execução. Eu mantenho todos esses arquivos de configuração. Se eu fizer alguma modificação de parâmetro, faço um novo arquivo de configuração. Por fim, anexo como comentários todas as perdas por época para treinamento e validação.

O motivo pelo qual sou tão obsessivo com a retenção de resultados antigos é que isso facilita muito voltar e revisar as experiências anteriores. Também protege contra repetir erroneamente o mesmo experimento sem saída. Psicologicamente, também permite que você olhe para trás e observe "Bem, o projeto pode não estar onde eu quero que esteja hoje, mas estou progredindo em comparação com o que estava há semanas atrás".k

Como exemplo, eu queria aprender sobre os modelos de linguagem LSTM, então decidi criar um bot no Twitter que escrevesse novos tweets em resposta a outros usuários do Twitter. Eu trabalhei nisso no meu tempo livre, entre a pós-graduação e meu trabalho. Demorou cerca de um ano, e iteramos mais de 150 modelos diferentes antes de chegar a um modelo que fizesse o que eu queria: gerar novo texto em inglês que (meio que) faça sentido. (Um ponto chave importante, e parte do motivo de tantas tentativas, é que não foi suficiente obter apenas uma baixa perda fora da amostra, pois os primeiros modelos de baixa perda conseguiram memorizar os dados de treinamento, por isso, estava apenas reproduzindo blocos de texto em texto literalmente em resposta às solicitações - foram necessários alguns ajustes para tornar o modelo mais espontâneo e ainda ter baixa perda.)

Sycorax
fonte
11
Muitos bons conselhos lá. É interessante quantos de seus comentários são semelhantes aos que eu fiz (ou vi outros fazerem) em relação à estimativa de depuração de parâmetros ou previsões para modelos complexos com esquemas de amostragem do MCMC. (Por exemplo, o código pode parecer para trabalhar quando não está implementado corretamente.)
Glen_b
11
@Glen_b Eu não acho que as melhores práticas de codificação recebam ênfase suficiente na maioria dos currículos de estatísticas / aprendizado de máquina, e foi por isso que enfatizei tanto esse ponto. Eu vi um número de postos de NN onde OP deixou um comentário como “oh Eu encontrei um bug agora ele funciona.”
Sycorax
7
Ensino uma programação para o curso de ciência de dados em python e, na verdade, realizamos funções e testes de unidade no primeiro dia, como conceitos principais. Lutando contra a boa luta.
Matthew Drury
8
+1 em "Toda a codificação está depurando". Surpreende-me quantos pôsteres no SO parecem pensar que a codificação é um exercício simples que requer pouco esforço; que esperam que seu código funcione corretamente na primeira vez em que o executam; e que parecem incapazes de prosseguir quando não o fazem. O engraçado é que eles estão meio certos: a codificação é fácil - mas a programação é difícil.
Bob Jarvis
41

As respostas postadas são ótimas e eu gostaria de adicionar algumas "verificações de sanidade" que me ajudaram bastante no passado.

1) Treine seu modelo em um único ponto de dados. Se isso funcionar, treine-o em duas entradas com saídas diferentes.

Isso verifica algumas coisas. Primeiro, ele mostra rapidamente que seu modelo é capaz de aprender, verificando se ele pode superestimar seus dados. No meu caso, eu constantemente cometo erros tolos de fazer Dense(1,activation='softmax')vs Dense(1,activation='sigmoid')para previsões binárias, e o primeiro fornece resultados de lixo.

Se o seu modelo não conseguir ajustar demais alguns pontos de dados, é muito pequeno (o que é improvável na era atual) ou algo está errado em sua estrutura ou no algoritmo de aprendizado.

2) Preste atenção à sua perda inicial.

eu=-0,3em(0,5)-0,7em(0,5)0,7

-0,3em(0,99)-0,7em(0,01)=3.2.

Você pode estudar isso ainda mais, fazendo seu modelo prever alguns milhares de exemplos e, depois, histografando as saídas. Isso é especialmente útil para verificar se seus dados estão normalizados corretamente. Como exemplo, se você espera que sua saída seja fortemente inclinada para 0, pode ser uma boa ideia transformar suas saídas esperadas (seus dados de treinamento), tomando as raízes quadradas da saída esperada. Isso evitará problemas de gradiente para sigmóides saturados na saída.

3) Generalize as saídas do seu modelo para depurar

Como exemplo, imagine que você esteja usando um LSTM para fazer previsões a partir de dados de séries temporais. Talvez no seu exemplo, você se preocupe apenas com a previsão mais recente; portanto, seu LSTM gera um único valor e não uma sequência. Alterne o LSTM para retornar previsões em cada etapa (em keras, é isso return_sequences=True). Depois, você pode examinar suas saídas de estado oculto após cada etapa e verificar se elas são realmente diferentes. Uma aplicação disso é garantir que, quando você estiver mascarando suas seqüências (por exemplo, preenchendo-as com dados para torná-las iguais), o LSTM esteja ignorando corretamente seus dados mascarados. Sem generalizar seu modelo, você nunca encontrará esse problema .

4) Olhe para camadas individuais

O Tensorboard fornece uma maneira útil de visualizar as saídas da sua camada . Isso pode ajudar a garantir que as entradas / saídas sejam normalizadas adequadamente em cada camada. Também pode pegar ativações de buggy. Você também pode consultar as saídas da camada no keras em um lote de previsões e, em seguida, procurar por camadas que tenham ativadas distorcidas suspeitas (todas as 0 ou todas diferentes de zero).

5) Crie um modelo mais simples primeiro

Você decidiu que a melhor abordagem para resolver seu problema é usar uma CNN combinada com um detector de caixa delimitadora, que processa ainda mais as colheitas de imagens e depois usa um LSTM para combinar tudo. Leva apenas 10 minutos para sua GPU inicializar seu modelo.

Em vez disso, crie um lote de dados falsos (mesma forma) e divida seu modelo em componentes. Em seguida, faça modelos fictícios no lugar de cada componente (sua "CNN" pode ser apenas uma convolução 2x2 de 20 passos, o LSTM com apenas 2 unidades ocultas). Isso ajudará a garantir que a estrutura do modelo esteja correta e que não haja problemas estranhos. Eu lutei por um tempo com esse modelo e, quando tentei uma versão mais simples, descobri que uma das camadas não estava sendo mascarada corretamente devido a um erro de keras. Você pode facilmente (e rapidamente ) consultar as camadas internas do modelo e ver se configurou seu gráfico corretamente.

6) Padronize suas versões de pré-processamento e pacote

As redes neurais, em particular, são extremamente sensíveis a pequenas alterações nos seus dados. Como exemplo, dois pacotes populares de carregamento de imagens são cv2e PIL. Apenas em virtude da abertura de um JPEG, esses dois pacotes produzirão imagens ligeiramente diferentes . As diferenças são geralmente muito pequenas, mas você ocasionalmente verá quedas no desempenho do modelo devido a esse tipo de coisa. Também torna a depuração um pesadelo: você obteve uma pontuação de validação durante o treinamento e, posteriormente, usa um carregador diferente e obtém uma precisão diferente no mesmo conjunto de dados danado.

Portanto, se você estiver baixando o modelo de alguém no github, preste muita atenção ao pré-processamento. Quais carregadores de imagem eles usam? Quais rotinas de pré-processamento de imagem eles usam? Ao redimensionar uma imagem, que interpolação eles usam? Eles primeiro redimensionam e depois normalizam a imagem? Ou o contrário? Qual é o pedido do canal para imagens RGB?

A maneira mais segura de padronizar pacotes é usar um requirements.txtarquivo que descreve todos os seus pacotes, como na configuração do sistema de treinamento, até os keras==2.1.5números de versão. Em teoria, o uso do Docker junto com a mesma GPU do seu sistema de treinamento deve produzir os mesmos resultados.

Alex R.
fonte
7
(+1) Verificar a perda inicial é uma ótima sugestão. Lamento ter deixado de fora da minha resposta.
21318 Sycorax
7
Certificar-se de que seu modelo possa se ajustar demais é uma excelente idéia. Estou tão acostumado a pensar em sobreajustar como uma fraqueza que nunca pensei explicitamente (até que você o mencionou) que a capacidade de sobreaquecer é realmente uma força.
John Coleman
15

Não treine uma rede neural para começar!

Todas as respostas são ótimas, mas há um ponto que deve ser mencionado: há algo a aprender com seus dados? (que pode ser considerado como algum tipo de teste).

Se o rótulo que você está tentando prever é independente de seus recursos, é provável que a perda de treinamento seja difícil de reduzir.

Em vez disso, comece a calibrar uma regressão linear, uma floresta aleatória (ou qualquer método que você queira cujo número de hiperparâmetros seja baixo e cujo comportamento você possa entender).

Então, se você conseguir um desempenho decente nesses modelos (melhor do que a adivinhação aleatória), poderá começar a ajustar uma rede neural (e a resposta do @Sycorax resolverá a maioria dos problemas).

RUser4512
fonte
5
xk
11

Em sua essência, o fluxo de trabalho básico para o treinamento de um modelo NN / DNN é mais ou menos sempre o mesmo:

  1. define a arquitetura NN (quantas camadas, que tipo de camada, as conexões entre as camadas, as funções de ativação etc.)

  2. leia dados de alguma fonte (a Internet, um banco de dados, um conjunto de arquivos locais etc.), veja algumas amostras (para garantir que a importação tenha corrido bem) e faça a limpeza dos dados, se / quando necessário. Este passo não é tão trivial quanto as pessoas normalmente supõem. A razão é que, para DNNs, geralmente lidamos com conjuntos de dados gigantescos, várias ordens de magnitude maiores do que estamos acostumados, quando ajustamos modelos estatísticos paramétricos não-lineares mais lineares (os NNs pertencem a essa família, em teoria).

  3. normalizar ou padronizar os dados de alguma forma. Como os NNs são modelos não lineares, a normalização dos dados pode afetar não apenas a estabilidade numérica, mas também o tempo de treinamento e as saídas NN (uma função linear como normalização não é comutada por uma função hierárquica não linear).

  4. divida os dados no conjunto de treinamento / validação / teste ou em várias dobras se estiver usando validação cruzada.

  5. treinar a rede neural, enquanto ao mesmo tempo controla a perda no conjunto de validação. Aqui você pode desfrutar dos prazeres da otimização não convexa, onde você não sabe se existe alguma solução, se existem várias soluções, qual é a melhor solução em termos de erro de generalização e quão perto você está de chegar isto. A comparação entre a perda treinamento e curva de perda de validação orienta você, é claro, mas não subestime a die hard atitude de NNs (e especialmente DNNs): muitas vezes eles mostram uma (talvez devagar) diminuição de treinamento de perda / validação, mesmo quando você tem erros incapacitantes no seu código.

  6. Verifique a precisão do conjunto de teste e faça alguns gráficos / tabelas de diagnóstico.

  7. Volte ao ponto 1 porque os resultados não são bons. Reiterar ad nauseam .

É claro que os detalhes mudarão com base no caso de uso específico, mas com essa tela aproximada em mente, podemos pensar no que é mais provável que dê errado.

Verificações básicas de arquitetura

Isso pode ser uma fonte de problemas. Normalmente, faço essas verificações preliminares:

  • procure uma arquitetura simples que funcione bem no seu problema (por exemplo, MobileNetV2 no caso de classificação de imagem) e aplique uma inicialização adequada (nesse nível, o aleatório geralmente funciona). Se isso funcionar corretamente nos seus dados, pelo menos você saberá que não há problemas evidentes no conjunto de dados. Se você não conseguir encontrar uma arquitetura simples e testada que funcione no seu caso, pense em uma linha de base simples . Por exemplo, um classificador Naive Bayes para classificação (ou mesmo apenas classificando sempre a classe mais comum) ou um modelo ARIMA para previsão de séries temporais

  • Crie testes de unidade. Deixar de fazer isso (e o uso do sangrento Jupyter Notebook) geralmente são as causas principais dos problemas no código NN que sou solicitado a revisar, especialmente quando o modelo deve ser implantado na produção. Como a resposta mais votada já cobriu testes de unidade, acrescentarei que existe uma biblioteca que suporta o desenvolvimento de testes de unidade para NN (apenas no Tensorflow, infelizmente).

Conjunto de treinamento

Verifique seus dados de entrada. Veja se você inverteu o conjunto de treinamento e os rótulos do conjunto de testes, por exemplo (aconteceu comigo uma vez -___-) ou se importou o arquivo errado. Veja algumas amostras de entrada e os rótulos associados e verifique se eles fazem sentido. Verifique se os dados normalizados estão realmente normalizados (dê uma olhada no intervalo). Além disso, os conjuntos de dados do mundo real são sujos: para classificação, pode haver um alto nível de ruído no rótulo (amostras com o rótulo de classe errado) ou para previsões multivariadas de séries temporais, alguns componentes da série temporal podem ter muitos dados ausentes ( Já vi números tão altos quanto 94% em algumas das entradas).

A ordem na qual o conjunto de treinamento é alimentado na rede durante o treinamento pode ter efeito. Tente uma aleatória reprodução aleatória do conjunto de treinamento ( sem interromper a associação entre entradas e saídas ) e veja se a perda de treinamento diminui.

Finalmente, a melhor maneira de verificar se você tem problemas no conjunto de treinamento é usar outro conjunto de treinamento. Se você estiver classificando imagens, em vez das imagens coletadas, use um conjunto de dados padrão como CIFAR10 ou CIFAR100 (ou ImageNet, se você puder se dar ao luxo de treinar). Esses conjuntos de dados são bem testados: se sua perda de treinamento diminuir aqui, mas não no seu conjunto de dados original, você poderá ter problemas no conjunto de dados.

Faça os testes de ouro

Existem dois testes que chamo de Golden Tests, que são muito úteis para encontrar problemas em um NN que não treina:

  • reduza o conjunto de treinamento para 1 ou 2 amostras e treine-o. O NN deve superajustar imediatamente o conjunto de treinamento, atingindo uma precisão de 100% no conjunto de treinamento muito rapidamente, enquanto a precisão no conjunto de validação / teste será de 0%. Se isso não acontecer, há um erro no seu código.

  • o teste oposto: você mantém o conjunto completo de treinamento, mas embaralha os rótulos. A única maneira que o NN pode aprender agora é memorizando o conjunto de treinamento, o que significa que a perda de treinamento diminuirá muito lentamente, enquanto a perda de teste aumentará muito rapidamente. Em particular, você deve atingir a perda de chance aleatória no conjunto de testes . Isso significa que se você tiver 1000 aulas, deverá atingir uma precisão de 0,1%. Se você não vê nenhuma diferença entre a perda de treinamento antes e depois de embaralhar as etiquetas, isso significa que seu código está com erros (lembre-se de que já verificamos as etiquetas do conjunto de treinamento na etapa anterior).

Verifique se sua métrica de treinamento faz sentido

A precisão (perda de 0-1) é uma métrica de baixa qualidade se você tiver um forte desequilíbrio de classe. Tente algo mais significativo, como perda de entropia cruzada: você não apenas deseja classificar corretamente, mas gostaria de classificá-lo com alta precisão.

Traga as grandes armas

Se nada ajudou, agora é a hora de começar a mexer nos hiperparâmetros. Essa é facilmente a pior parte do treinamento de NN, mas esses são modelos gigantescos e não identificáveis, cujos parâmetros são adequados para resolver uma otimização não convexa, portanto, essas iterações geralmente não podem ser evitadas.

  • tente otimizadores diferentes: o SGD treina mais devagar, mas isso leva a um erro de generalização mais baixo, enquanto Adam treina mais rápido, mas a perda de teste para um valor mais alto
  • tente diminuir o tamanho do lote
  • aumente a taxa de aprendizado inicialmente e decaia-o ou use uma taxa de aprendizado cíclica
  • adicionar camadas
  • adicionar unidades ocultas
  • remova a regularização gradualmente (talvez mude a norma do lote para algumas camadas). A perda de treinamento agora deve diminuir, mas a perda de teste pode aumentar.
  • visualize a distribuição de pesos e desvios para cada camada. Eu nunca precisei chegar aqui, mas se você estiver usando o BatchNorm, esperaria distribuições normais aproximadamente padrão. Veja se a norma dos pesos está aumentando anormalmente com as épocas.
  • se você estiver recebendo algum erro no momento do treinamento, pesquise no Google esse erro . Desperdicei uma manhã enquanto tentava consertar uma arquitetura que funcionava perfeitamente, apenas para descobrir que a versão do Keras que eu havia instalado tinha suporte para buggy multi-GPU e tive que atualizá-la. Às vezes, eu tinha que fazer o oposto (fazer o downgrade de uma versão do pacote).
  • atualize seu currículo e comece a procurar um emprego diferente :-)
DeltaIV
fonte
+1, mas "maldito caderno Jupyter"? Gostaria de comentar sobre isso? :)
ameba
2
Eis por que eu odeio os Notebooks Jupyter . TL; DR: estado oculto, diffing é um problema, problemas de segurança e incentiva práticas de programação ruins, como não usar testes de unidade / regressão / integração. Treinar NNs já é bastante difícil, sem que as pessoas se esqueçam dos fundamentos da programação.
DeltaIV 28/06
2
Possivelmente estou sendo muito negativo, mas, francamente, já me cansei de pessoas clonando Jupyter Notebooks do GitHub, pensando que seria questão de minutos para adaptar o código ao caso de uso deles e depois me reclamar que nada funciona. Por uma questão de pesar, obtenha um IDE real, como PyCharm ou VisualStudio Code, e crie um código bem estruturado, em vez de criar um Notebook! Especialmente se você planeja enviar o modelo para a produção, isso facilitará muito as coisas.
DeltaIV 28/06
2
Ri muito. 'Jupyter notebook' e 'unit testing' são anti-correlacionados.
Sycorax
2
(+1) Esta é uma boa redação. As sugestões para testes de randomização são realmente ótimas maneiras de acessar redes com erros.
Sycorax
6

Se o modelo não estiver aprendendo, há uma chance decente de que sua retropropagação não esteja funcionando. Mas há tantas coisas que podem dar errado com um modelo de caixa preta como a Rede Neural; há muitas coisas que você precisa verificar. Acho que Sycorax e Alex fornecem respostas abrangentes muito boas. Só quero adicionar uma técnica ainda não foi discutida.

ϵ

Anthony Lei
fonte