Sobreajuste de redes neuronales convolucionales. La deserción no ayuda

16

Estoy jugando un poco con convnets. Específicamente, estoy usando el conjunto de datos kaggle cats-vs-dogs que consta de 25000 imágenes etiquetadas como gato o perro (12500 cada una).

Me las arreglé para lograr una precisión de clasificación de alrededor del 85% en mi conjunto de pruebas, sin embargo, establecí el objetivo de lograr una precisión del 90%.

Mi principal problema es el sobreajuste. De alguna manera, siempre termina sucediendo (normalmente después de la época 8-10). La arquitectura de mi red está ligeramente inspirada en VGG-16, más específicamente, mis imágenes cambian de tamaño a 128X128X3 , y luego ejecuto:

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 las capas, excepto la última, tienen relus como funciones de activación.

Tenga en cuenta que he probado diferentes combinaciones de convoluciones (comencé con convoluciones más simples).

Además, he aumentado el conjunto de datos al reflejar las imágenes, de modo que en total tengo 50000 imágenes.

Además, estoy normalizando las imágenes usando la normalización mínima máxima, donde X es la imagen

X=X-0 0/ /255-0 0

El código está escrito en tensorflow y los tamaños de lote son 128.

Los mini lotes de datos de entrenamiento terminan sobreajustados y tienen una precisión del 100%, mientras que los datos de validación parecen dejar de aprender en torno al 84-85%.

También he tratado de aumentar / disminuir la tasa de abandono escolar.

El optimizador utilizado es AdamOptimizer con una tasa de aprendizaje de 0.0001

En este momento he estado jugando con este problema durante las últimas 3 semanas y el 85% parece haber establecido una barrera frente a mí.

Para el registro, sé que podría usar el aprendizaje de transferencia para lograr resultados mucho más altos, pero estoy interesado en construir esta red como una experiencia de autoaprendizaje.

Actualizar:

Estoy ejecutando la MISMA red con un tamaño de lote diferente, en este caso estoy usando un tamaño de lote mucho más pequeño (16 en lugar de 128) hasta ahora estoy logrando una precisión del 87.5% (en lugar del 85%). Dicho esto, la red termina sobreajustando de todos modos. Aún así, no entiendo cómo un abandono del 50% de las unidades no está ayudando ... obviamente estoy haciendo algo mal aquí. ¿Algunas ideas?

Actualización 2:

Parece que el problema tenía que ver con el tamaño del lote, ya que con un tamaño más pequeño (16 en lugar de 128) ahora estoy logrando una precisión del 92.8% en mi conjunto de prueba, con el tamaño de lote más pequeño que la red aún se adapta (los mini lotes terminan sin embargo, con una precisión del 100%), la pérdida (error) sigue disminuyendo y, en general, es más estable. Las desventajas son un tiempo de ejecución MUCHO más lento, pero vale la pena la espera.

Juan Antonio Gómez Moriano
fuente
2
¿Podría dar más detalles sobre su evaluación de sobreajuste? Por ejemplo, ¿la precisión de la validación disminuye en algún momento, junto con la divergencia de los resultados de capacitación y validación? ¿Qué hay de la función de pérdida?
Neil Slater
Buena pregunta, por lo que al sobreajustar me refiero al hecho de que los mini lotes en el tren alcanzan una precisión del 100% y pérdidas de 0.08, mientras que la validación no parece nunca ser inferior a 0.35 y su precisión se mantiene ahora en el 88%. De acuerdo con la validación, no parece caer (al menos no demasiado), parece ser plana, sin embargo, ¿cómo es posible que el mini lote logre una pérdida tan baja mientras la validación aún está muy lejos?
Juan Antonio Gomez Moriano
No sé una respuesta para usted, sin embargo, este comportamiento (gran divergencia entre el tren y la validación, pero aún así la validación estancada OK-ish) es algo que he visto antes varias veces. Casi dudo en llamarlo sobreajuste porque a veces los resultados de la prueba son aceptables.
Neil Slater
"Aún no entiendo cómo una deserción del 50% de las unidades no está ayudando". He visto personas que utilizan con éxito valores mucho más altos de deserción.
Ricardo Cruz

Respuestas:

14

Bien, después de mucha experimentación, he logrado obtener algunos resultados / ideas.

En primer lugar, si todo es igual, los lotes más pequeños en el conjunto de entrenamiento ayudan mucho para aumentar el rendimiento general de la red, como un aspecto negativo, el proceso de entrenamiento es muuuuuch más lento.

Segundo punto, los datos son importantes, nada nuevo aquí, pero como aprendí mientras luchaba contra este problema, más datos siempre parecen ayudar un poco.

Tercer punto, el abandono es útil en redes grandes con muchos datos y muchas iteraciones, en mi red apliqué el abandono solo en las capas finales completamente conectadas, las capas de convolución no se aplicaron.

Cuarto punto (y esto es algo que estoy aprendiendo una y otra vez): las redes neuronales toman MUCHO para entrenar, incluso en buenas GPU (entrené esta red en floydhub, que usa tarjetas NVIDIA bastante caras), por lo que la PACIENCIA es clave .

Conclusión final: los tamaños de lote son más importantes de lo que uno podría pensar, aparentemente es más fácil alcanzar un mínimo local cuando los lotes son más grandes.

El código que escribí está disponible como un cuaderno de Python, creo que está decentemente documentado

https://github.com/moriano/loco-learning/blob/master/cats-vs-dogs/cats-vs-dogs.ipynb

Juan Antonio Gómez Moriano
fuente
Gracias por publicar tus hallazgos. Una pregunta rápida: estoy frente a un problema similar y vi esto en el bloc de notas que envió: NOTE USE EITHER mean centering or min-max, NOT BOTH. Actualmente estoy dividiendo mis imágenes de entrada por 255 dentro de mi input_fn(Tensorflow Estimator API). Luego, dentro del modelo, estoy ejecutando esa entrada a través de la norma de lote. ¿Debo seguir haciendo solo una de esas normalizaciones? Ver github.com/formigone/tf-imagenet/blob/master/models/…
rodrigo-silveira
Entiendo que dividir por 255 se realiza solo una vez para cada imagen, y la razón es mantener todos los valores entre 0 y 1, ya que eso proporcionará estabilidad numérica.
Juan Antonio Gómez Moriano
Claro, lo entiendo. ¿Pero cree que tiene sentido también normalizar por lotes esos valores en el rango [0, 1]?
rodrigo-silveira
Eso, no sé, ha pasado un tiempo desde que usé la normalización por lotes :)
Juan Antonio Gómez Moriano
3

Le sugiero que analice las parcelas de aprendizaje de su precisión de validación como lo sugirió Neil Slater. Luego, si la precisión de la validación disminuye, intente reducir el tamaño de su red (parece demasiado profundo), agregue el abandono a las capas CONV y BatchNormalization después de cada capa. Puede ayudar a deshacerse del sobreajuste y aumentar la precisión de la prueba.

HatemB
fuente
Gracias por el consejo, lo intentaré, sin embargo, tenía la impresión de que las capas CONV no requieren deserción, en la mayoría de los documentos que he leído, la deserción parece aplicarse siempre a las capas finales completamente conectadas, no a las convolutinas.
Juan Antonio Gomez Moriano
3

Hay varias soluciones posibles para su problema.

  1. Utilice Dropout en las capas anteriores (capas convolucionales) también.

  2. Su red parece de alguna manera bastante grande para una tarea tan "fácil"; Intenta reducirlo. Las grandes arquitecturas también están capacitadas en conjuntos de datos mucho más grandes.

Si desea mantener su arquitectura "grande", pruebe:

  1. Aumento de imagen para aumentar virtualmente sus datos de entrenamiento

  2. Prueba el entrenamiento contradictorio. A veces ayuda.

Andreas Look
fuente
"Su red parece de alguna manera bastante grande para una tarea tan" fácil "; intente reducirla. Las grandes arquitecturas también están capacitadas en conjuntos de datos mucho más grandes". No estoy de acuerdo, ya que agregué más convoluciones, la precisión aumentó (inicialmente estaba alcanzando el 68% con solo dos convoluciones). Además, ya estoy aumentando mi conjunto de datos, opero con 50000 imágenes.
Juan Antonio Gomez Moriano
2

Una cosa que aún no se ha mencionado y que puede considerar para el futuro: aún puede aumentar su abandono en las capas completamente conectadas.

Una vez leí un periódico que usaba una tasa de abandono del 90%. Aunque tenía muchos nodos (2048 si recuerdo correctamente), lo he intentado yo mismo en capas con menos nodos y fue muy útil en algunos casos.

Solo miré qué papel era. No recuerdo qué papel acabo de recordar, pero encontré estos que también tuvieron cierto éxito con tasas de abandono del 90%.

Karpathy, A., Toderici, G., Shetty, S., Leung, T., Sukthankar, R. y Fei-Fei, L. (2014). Clasificación de video a gran escala con redes neuronales convolucionales. En Actas de la conferencia de IEEE sobre Visión por Computadora y Reconocimiento de Patrones (pp. 1725-1732).

Simonyan, K. y Zisserman, A. (2014). Redes convolucionales de dos canales para el reconocimiento de acciones en videos. En Avances en sistemas de procesamiento de información neuronal (pp. 568-576).

Varol, G., Laptev, I. y Schmid, C. (2017). Convoluciones temporales a largo plazo para el reconocimiento de la acción. Transacciones IEEE sobre análisis de patrones e inteligencia artificial.

kefbach
fuente
0

También tuve este problema. Después de cenar con él durante horas, por casualidad decidí mezclar los datos antes de introducirlos en el sistema y listo, comenzó a funcionar. ¡Me tomó un tiempo darme cuenta de que fue el arrastrar los pies lo que hizo el truco! ¡Espero que esto salve a alguien de la frustración!

usuario79129
fuente