Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.
Problema Inicial.
Generar imágenes ficticias de dos tipos de fósiles diferentes para aumentar el dataset con el que entrenar una red clasificadora de imágenes.
Cuestiones Involucradas.
- Deep Learning
- GAN
- SRGAN
Solución.
Creación de dos GANs (una por cada tipo de imágen) agrandando los resultados mediante otra SRGAN para obtener los datos necesarios.
Desarrollo del proyecto Paper: GAN para mejorar el rendimiento de un clasificador de Fósiles
Problema Inicial
Manuel me contactó comentando que tenía un problema con el entrenamiento de una red neuronal clasificadora de fósiles: mientras que con unos tipos de fósiles la red funcionaba muy bien, con otros tipos, únicamente clasificaba correctamente el 30% de las imágenes. Esto era debido a que la red se estaba entrenando con muy pocas imágnes. Por tanto, hacía falta conseguir más imágenes con las que entrenar a esta red, cosa que se podría conseguir mediante una GAN.
Sin embargo, las imágenes que incluían tenian ciertas pecularidades:
- El tamaño de las imágenes debía ser suficientemente grande. Las GANs, en general, suelen devolver imágenes de baja resolución, ya que mayor resolución implica más datos y, por tanto, necesitas tiempos de entrenamiento más largos o más GPUs (cosa de la que no disponía).
- Hay pocas imágenes para entrenar a la GAN, sobre todo para uno de los tipos de imágenes. Esto es muy importante, ya que puede hacer que las GAN «memorice» en vez de aprender, de tal forma que genere una cantidad de imágenes muy limitadas.
Planteamiento inicial del proyecto
Tras ver las imágenes, mi primer impulso fue buscar papers en los que se abordara específicamente este problema: una GAN que genere imágenes en alta resolución y con pocos datos de entrada. Para mi sorpresa, vi que recienemtente se había publicado este paper, donde se presentaba un modelo de GAN, llamado F2GAN, que funcionaba bien bajo esas circunstancias.
Además, los creadores habían publicado el código en este repositorio en Github, donde se mostraban los resultados y el código para la implementación. Así pues, probé a correr el código por mi cuenta, sin éxito. El problema: el algoritmo requería demasiada capacidad computacional de la cual requería: los autores recomendaban el uso de múltiples GPUs, mientras que yo únicamente contaba con la GPU gratuita ofrecida por Colab, que es potente, pero no tanto.
Así pues, seguí indagando y cambié el enfoque: en vez de una GAN que resolviera ese problema, buscaría una GAN específica para data augmentation. En esa búsqueda encontré este paper donde se presenta una arquitectura llamada DAGAN (Data Augmentation GAN) que permite, precisamente, eso, generar nuevas imágenes. Tras una búsqueda en paperswith code, encontré que ese paper también había sido subido a Github (enlace), por lo que podría probar el código.
Sin embargo, una vez más, el resultado no fue el que me gustaría: no contaba con suficiente potencia de cómputo como para que el algoritmo funcionara.
En este momento, tuve que plantearme cómo debería afrontar el problema.
Divde y vencerás: generando imágenes en alta resolución con GANs
En esa reflexión, me di cuenta de una cuestión importante: la dificultad de entrenamiento del modelo viene derivada del tamaño de las imágenes resultantes. Si la GAN generara imágenes en menor resolución, no habría problema de cómputo. Ahora, solo haría falta una manera de convertir esas imágenes de baja resolución en imágenes de alta resolución que mantengan la proporción. Esto es algo que ya se puede conseguir mediante las SRGANs (Super Resolution GAN).
Además, pensé que resolver el problema de las pocas imágenes de entrenamiento quizás es algo que pudiera arreglarse con la propia estructura del modelo, incluyendo capas de droput con altas probabilidades. De hecho, algo similar es lo que se hizo en este paper, donde se propone una estructura llamada Dropout-GAN (muy interesante).
Así pues, entrené una GAN siguiendo la implementación realizada por Goodfellow (enlace) y que es similar a la que expliqué en este tutorial. Además, tuve que realizar ciertas modificaciones al algoritmo para asegurarme de que no memorizaba las imágenes con las que se entrenaba la red (que eran pocas). Para ello, tras varias pruebas ví como fijar una capa de Dropout con un rate elevado del 0.5 tras cada una de las capas de LeakyReLU es lo que mejores resultados conseguía:
Una vez creada la GAN, la entrené por 7.000 epochs, consiguiendo reducir signigitcativamente el coste y, sobre todo, generando imágenes con un alto nivel de fidelidad:
Ahora que tenía la GAN, tuve que crear 500 imágenes para cada uno de los tipos de imágenes (trampling y marcas de dientes). Aunque eran imágenes con un alto nivel de fidelidad, eran imágenes muy muy pequeñas (64×64) que no podían ser usadas para entrenar el clasificador de imágenes. Así pues, había que agrandar estos resultados, manteniendo la calidad de la imagen.
Para ello, utilicé una implementación de las Super-Resolution GANs, propuesta por Christian Ledig en su paper (enlace). El algoritmo, al no requerir de ninguna modificación, se implementó tal cual, lo cual se puede encontrar en diferentes respositorios tanto en Torch (enlace) como para Keras (enlace).
De esta forma, pasamos de tener imágenes de 64×64 a imágenes de 256×256 y, en última instancia, imágenes de 1024×1024, todas ellas mantieniendo al máximo la calidad, como se puede ver en la imagen a continuación:
Finalmente, se optó por utilizar las imágenes de tamaño 256×256, puesto que eran un tamaño lo suficientemente grande como para poder ser utilizadas por la red e incluir la misma imagen con mayor tamaño no generaba impacto alguno en el modelo.
Resultado del proyecto
Tras haber aplicado la SRGAN contamos con 1.000 nuevas imágenes con las que entrenar a nuestro modelo.
Ese incremento vino de la mano de una mejor clasificación de los grupos infrarepresentados, lo que supuso un incremento del F1-Score de entorno a 10 puntos, variando delo modelo y los parámetros.
En definitiva, gracias a estos algoritmos se ha podido entrenar uno de los primeros algoritmos especializados en la identificación de marcas de fósiles.
Además, creo que resulta interesante las opciones a nivel computacional y de flexibilidad que ofrece la estrategia de divide y vencerás frente a la creación de un modelo único que resuelva el problema.
Para más información puedes consultar el paper en este enlace.