Estou brincando um pouco com convnets. Especificamente, estou usando o conjunto de dados kaggle gatos contra cães, que consiste em 25000 imagens rotuladas como gato ou cachorro (12500 cada).
Consegui atingir cerca de 85% de precisão de classificação no meu conjunto de testes, no entanto, estabeleci uma meta de atingir 90% de precisão.
Meu principal problema é o excesso de ajustes. De alguma forma, sempre acaba acontecendo (normalmente após a época 8-10). A arquitetura da minha rede é pouco inspirada no VGG-16, mais especificamente, minhas imagens são redimensionadas para e, em seguida, corro:
Convolution 1 128x128x32 (kernel size is 3, strides is 1)
Convolution 2 128x128x32 (kernel size is 3, strides is 1)
Max pool 1 64x64x32 (kernel size is 2, strides is 2)
Convolution 3 64x64x64 (kernel size is 3, strides is 1)
Convolution 4 64x64x64 (kernel size is 3, strides is 1)
Max pool 2 32x32x64 (kernel size is 2, strides is 2)
Convolution 5 16x16x128 (kernel size is 3, strides is 1)
Convolution 6 16x16x128 (kernel size is 3, strides is 1)
Max pool 3 8x8x128 (kernel size is 2, strides is 2)
Convolution 7 8x8x256 (kernel size is 3, strides is 1)
Max pool 4 4x4x256 (kernel size is 2, strides is 2)
Convolution 8 4x4x512 (kernel size is 3, strides is 1)
Fully connected layer 1024 (dropout 0.5)
Fully connected layer 1024 (dropout 0.5)
Todas as camadas, exceto a última, têm relus como funções de ativação.
Observe que eu tentei combinações diferentes de convoluções (comecei com convoluções mais simples).
Além disso, aumentei o conjunto de dados espelhando as imagens, para que, no total, eu tivesse 50000 imagens.
Além disso, estou normalizando as imagens usando a normalização min max, onde X é a imagem
O código é escrito em tensorflow e os tamanhos de lote são 128.
Os mini-lotes de dados de treinamento acabam se ajustando demais e com precisão de 100%, enquanto os dados de validação parecem parar de aprender em torno de 84 a 85%.
Eu também tentei aumentar / diminuir a taxa de desistência.
O otimizador usado é o AdamOptimizer com uma taxa de aprendizado de 0,0001
No momento, estou jogando com esse problema nas últimas 3 semanas e 85% parecem ter colocado uma barreira na minha frente.
Para que conste, sei que poderia usar o aprendizado por transferência para obter resultados muito mais altos, mas sou interessante em construir essa rede como uma experiência de auto-aprendizado.
Atualizar:
Estou executando a mesma rede com um tamanho de lote diferente; nesse caso, estou usando um tamanho de lote muito menor (16 em vez de 128) até agora, estou atingindo uma precisão de 87,5% (em vez de 85%). Dito isto, a rede acaba se ajustando de qualquer maneira. Ainda não entendo como um abandono de 50% das unidades não está ajudando ... obviamente estou fazendo algo errado aqui. Alguma ideia?
Atualização 2:
Parece que o problema tinha a ver com o tamanho do lote, como com um tamanho menor (16 em vez de 128), agora estou alcançando uma precisão de 92,8% no meu conjunto de testes, com o tamanho menor do lote em que a rede ainda se adapta (os mini lotes acabam com uma precisão de 100%), no entanto, a perda (erro) continua diminuindo e, em geral, é mais estável. Os contras são um tempo de execução MUITO mais lento, mas vale totalmente a pena a espera.
fonte
Respostas:
Ok, depois de muita experimentação eu consegui obter alguns resultados / idéias.
Em primeiro lugar, tudo sendo igual, lotes menores no conjunto de treinamento ajudam muito para aumentar o desempenho geral da rede, como um lado negativo, o processo de treinamento é muuuuuch mais lento.
Segundo ponto, os dados são importantes, nada de novo aqui, mas como aprendi ao combater esse problema, mais dados sempre parecem ajudar um pouco.
Terceiro ponto, o abandono é útil em grandes redes com muitos dados e muitas iterações. Na minha rede, apliquei o abandono apenas nas camadas finais totalmente conectadas, as camadas de convolução não foram aplicadas.
Quarto ponto (e isso é algo que estou aprendendo várias vezes): as redes neurais exigem MUITO para treinar, mesmo em boas GPUs (eu treinei essa rede no floydhub, que usa placas NVIDIA bastante caras), então PATIENCE é a chave .
Conclusão final: os tamanhos dos lotes são mais importantes do que se pensa, aparentemente é mais fácil atingir um mínimo local quando os lotes são maiores.
O código que escrevi está disponível como um notebook python, acho que está decentemente documentado
https://github.com/moriano/loco-learning/blob/master/cats-vs-dogs/cats-vs-dogs.ipynb
fonte
NOTE USE EITHER mean centering or min-max, NOT BOTH
. Atualmente, estou dividindo minhas imagens de entrada por 255 na minhainput_fn
(API do Tensorflow Estimator). Então, dentro do modelo, estou executando essa entrada através da norma de lote. Ainda devo fazer apenas uma dessas normalizações? Veja github.com/formigone/tf-imagenet/blob/master/models/…Sugiro que você analise os gráficos de aprendizado de sua precisão de validação, como sugeriu Neil Slater. Em seguida, se a queda na precisão da validação tentar reduzir o tamanho da sua rede (parece muito profunda), adicione a interrupção às camadas CONV e BatchNormalization após cada camada. Pode ajudar a se livrar do excesso de ajustes e aumentar a precisão do teste.
fonte
Existem várias soluções possíveis para o seu problema.
Use o Dropout nas camadas anteriores (camadas convolucionais) também.
Sua rede parece bastante grande para uma tarefa "fácil"; tente reduzi-lo. As grandes arquiteturas também são treinadas em conjuntos de dados muito maiores.
Se você deseja manter sua arquitetura "grande", tente:
Ampliação da imagem para aumentar virtualmente seus dados de treinamento
Tente treinamento adversário. Às vezes ajuda.
fonte
Uma coisa que ainda não foi mencionada e que você pode considerar para o futuro: você ainda pode aumentar sua desistência nas camadas totalmente conectadas.
Li um jornal uma vez que usava 90% de desistência. Embora tivesse muitos nós (2048, se bem me lembro), tentei isso sozinho em camadas com menos nós e foi muito útil em alguns casos.
Eu apenas procurei qual era o papel. Não me lembro de qual papel acabei de lembrar, mas encontrei aqueles que também tiveram algum sucesso com taxas de abandono de 90%.
fonte
Eu tive esse problema também. Depois de mexer com ele por horas, por acaso decidi embaralhar os dados antes de inseri-los no sistema e pronto, ele começou a funcionar. Demorei um pouco para descobrir que foi o embaralhamento que fez o truque! Espero que isso salve alguém da frustração!
fonte