Superresolución con DNNs (II)

Saludos lectores

Hoy quiero mostrarles algo en que he estado trabajando estos días.

Entre las muchas cosas que he hecho en estas cuarentenas, está el empezar a aprender algo más en serio sobre redes neuronales

He estado probando varios frameworks, Tensorflow, Pytorch, Yolo, OpenVINO, tinynn, la NN propia de OpenCV, etc. Pero mayormente ha sido Tensorflow, con ayuda de su API de mayor nivel Keras (ayuda mucho simplificando el código).

Hace poco les mostré ejemplos de super-resolución con redes neuronales, y lo vimos aplicado en fotos reales y en imágenes de videojuegos

Superresolución con DNNs.

Pues bien, decidí hacerme una red para ir creando algo de SR, el objetivo lo veremos más adelante.

Toda la experimentación ha sido con un tipo de red llamada Autonencoder Convolucional.

Les explico todo de manera simplificada.

Este tipo de red se encarga de aprender características de un conjunto de datos, abstrayéndolas cada vez más y reduciendo su volumen. Esto es en la primera mitad de la red. La segunda mitad toma estas abstracciones y características comprimidas y trata de “descomprimirlas” para recomponer datos como los de su entrada.

El entrenamiento de redes neuronales es un proceso computacionalmente intensivo, y más si es con muchos datos. Por ello se ha trabajado bastante en la aceleración del proceso en hardware. El backend oficial de GPU para Tensorflow está basado en NVIDIA CUDA por lo que solo se ejecutaría en GPUs compatibles de esta compañía. Sin embargo, se ha trabajado, mayormente por terceros, en algunos backends basados en OpenCL. El mejor soportado y en desarrollo continuo es PlaidML. PlaidML sirve de backend acelerado alternativo para Keras, en lugar del de tensorflow y se ejecuta en GPUs discretos e integrados de AMD, NVIDIA e INTEL. Así que he podido ejecutar Tensorflow acelerando el entrenamiento con mi GPU, una AMD Radeon RX 470. PlaidML fue comprado no hace mucho por Intel, al parecer en interés para el trabajo que viene realizando en futuras GPUs para juegos y sistemas de cómputo. PlaidML es código abierto y software libre con la licencia correspondiente.

Sin más veamos el ejemplo.

Haremos reconstrucción en imagen. En este caso, imágenes de rostros.

Tomando una base de fotografías de personalidades, más de 13 mil imágenes, todas alineadas al nivel de los ojos. Estas las reprocesé, detectando los rostros y recortándolos más ajustados, para evitar los fondos de la imagen original.

Perdí la alineación de los rostros según los ojos, pero para el primer ejemplo, dejémoslo así, ya luego lo haré mejor y les actualizo los resultados.

Como no tengo ni hardware extremo en potencia, ni memoria abundante, ni el tiempo que llevaría entrenar la red con imágenes de alta resolución, las reduje a 64×64 pixeles. Trabajaremos con esto.

La red traté de hacerla lo más pequeñaposible que me diera el mejor resultado, por asunto de cómputo y tiempo de entrenamiento e inferencia. No la hice como la que ven arriba en el esquema simplificado, que es del tipo “compresora” y con el medio completamente conectado, si no que la armé del tipo expansora y puramente convolucional.

Como degradación de la imagen, la reducimos para el primer experimento a 32×32 pixeles, es decir, a la mitad de la resolución, con una selección del vecino-mas-cercano para los pixeles. Luego la llevamos de nuevo a 64×64 de la misma manera. Esto es lo que tenemos. (Es recomendable ver las imagenes a parte para poder ampliarlas más de lo que se ven en la pagina y ver los detalles aspectos que se mencionan)

Ahora, en la entrada de la red se introduce las imágenes degradadas, y como muestra de salida, las originales correspondientes. La red aprenderá las características necesarias y sus combinaciones para poder llevar cada entrada lo más cerca posible de la salida. Para esto se emplea una función de comparación, cuyo resultado debe minimizarse para todo el conjunto, es decir, reducir la diferencia entre las salidas regeneradas y las muestras originales.

Pero la evaluacion real se hace con otras imágenes, unas que la red no haya visto nunca. Por eso el conjunto de entrenamiento se divide en dos, en este caso lo fije en un 80/20. Es decir 80% del total se emplea en entrenar, el restante 20% se emplea en evaluar qué ha “aprendido” la red.

Esto se realiza iterativamente, y la red va aprendiendo algo mejor en cada caso. Creamos un ajuste para que cuando ya no “aprenda”, o al menos sea muy poco, se detenga. Pero antes de detenerse, se hace otro ajuste para que la velocidad de aprendizaje disminuya, así se enfoca el aprendizaje en detalles pequeños. Ya luego si realmente no aprende más, es que se detiene.

Veamos qué tal se ve esto acelerado en el GPU

Sobre esto, el trabajo con la GPU, al final les hago una historia.

Una vez obtenida la red entrenada, se tiene en cuenta la perdida y precisión de los resultados, por si luego mejoramos la estructura de la red, o los datos, podemos comparar cuanto es la mejora con lo anterior.

Le entregamos datos y el resultado los dibujamos. En la siguiente imagen, la primera fila es la imagen origina de 64×64 pixeles, la segunda es la degradad, la tercera fila la imagen degradada reconstruida por la red y la última es la degradada interpolada con un filtro lineal Lanczos de nivel 4 en este caso (buena calidad), algo asi como un poco menos de lo mejor que se haria con Photoshop.

¿Pero qué pasa si reducimos más la resolución? Vemos llevando las imágenes 16×16 pixeles.

¿Y qué tal más bajo aún? ¿Qué tal 8×8?

Algo extremo, no?

¿Qué les ha parecido?

Existe unos tipos de red, llamadas GAN (Generative Adversarial Networks) que preparadas para este contexto, son capaces de generar los rostros (ojo, digo generar, no regenerar), una acción llamada “alucinar”. El nombre le queda muy bien, pues casi si se le da una imagen vacía, saca un rostro. Abajo un ejemplo. LAs columnas son, la imagen degradada, una interpolación lineal, la generada por la red y la original.

Conclusiones

El próximo paso es crear de nuevo las imágenes de los rostros recortados, pero esta vez alineadas todas con los ojos como referencia. Así más características comunes se alinearán por igual y el entrenamiento y resultado será mejor. También probaré con las imágenes de referencia de mayor resolución, al menos al doble (128×128). Esto obliga a hacer la red algo mas profunda, pra capturar mas caracteristicas.

La red como la guarda Keras no es usable en otra aplicación. Debe ser “congelada” y optimizada (quita todo lo entrenable, las variables se fijan, lo redundante se elimina). En esto he tenido problemas, fundamentalmente porque casi todas las funciones y ejemplos que veo para esto son para Tensorflow 1.x y estoy usando 2.x. Si bien he visto como guarda la información en diversos modelos y como actualizar las versiones, aun no me ha resultado.

El objetivo aquí es emplear los resultados de estos y otras ideas que estoy realizando, con OpenCV o con Tensorflow Lite (TFlite) y hacer aplicaciones para PC o móvil. Estoy por reprogramar todo a Tensorflow puro e ir aprendiendo mejor PyTorch (LibTorch es la versión C++ que usaría para aplicaciones). O el pequeñísimo tiny-dnn

El próximo articulo será sobre como pienso usar esto para reconstruir imágenes afectadas por ruido o los problemas de compresión en imagen y video…..
… o prefieren uno sobre “mi propio DLSS” que he estado haciendo? ¿Una muestra? ¿Qué tal esta?

The Witcher 3 DLSS

La historia con la tarjeta.

A la vez que estoy haciendo, evaluando y entrenando las redes, tengo otro código en ejecución, paralelo casi completo, descomponiendo imágenes en bloques diferentes (más de 4 millones de imagencitas, de esto más historia luego). Mantiene el CPU al techo, cuando lo dejo, pues usualmente le “quito” un núcleo al proceso, para que lo coja el control del entrenamiento. Por estar en un momento trasteando la prioridad del proceso en el micro, para que uno del Windows Defender no fastidiara, se me atoró un poco el sistema y el MSI Afterburner se escachó el control automático del ventilador. En este asunto siempre mantengo el MSI Afterb activo y visible (lo vieron en una imagen anterior) como control. Al día siguiente pongo a hacer un entrenamiento, y al poco, como tenía cerrada la ventana de monitoreo del MSIAft, la abro.

Horror!!! ¡La temperatura del GPU había llegado a 90 grados!!

¿¡Se trabó el ventilador!?!!

NO, está al mínimo, 17% de velocidad!!!

Tumbo el entrenamiento, pero algo queda por detrás, la temperatura en 88 grados. No arranca el ventilador…

¡Por qué!!?!?!…….

Arrrgggg!!!

AAAHH!!! Ya se por qué!!!

Cierra y reinicia la PC….!!!!

Arranque normal, temperatura de regreso a menos de 50 grados y bajando hasta 37-40, ventilador OK. Ufff susto. Esta tarjeta de fábrica llega a unos 80 grados y solo lo ha hecho dos veces (una de prueba y otra por tener cerrado el MSI Afterb) pero con el ajuste vía MSI Afterb en juegos a lo más que llega es a 67 (y le cuesta), y con el queme este de entrenar las redes ha llegado a 71. Menos mal que la configuración de entrenamiento no era de muy alta intensidad.

Así que ya saben, no trasteen mucho con las prioridades de los procesos en el sistema….

8 respuestas a «Superresolución con DNNs (II)»

  1. Oye hermanito creo que debieras publicar también en foros relativos a estas lides de momento me viene a la mente github y ya que eres tan apasionado de AMD y empresas didacadas afines a esto, también debes indagar en el como hacerte publicar en sitios que te repliquen y hagan llegar tus resutados a los mismos.

    Este tema está siendo seguido por muchísimas compañias de eso no tengas dudas y asi con cada trabajo que estes llevando.

    Saludos.

    1. gracias, compa, pero no me interesa

      -de foros, Stackoverflow, y hace par de annos que ni comento, ni respondo, ni pregunto
      -github solo para descargar proyectos como guia o base
      -no soy “apasionado” de amd, pongo las cosas tal como son. y por apasionado, lo fuera del mas bajo. porejeplo, si me interesara algo mas que un comino el futbol, no le fuera al RM o al FCB, aunque siguiera sus resultados, le fuera al siguiente en la lista. si lo dices por gpus, por eso me interesa que trae Intel en este campo. pero como poco se sabe, entonces por ahora, al segundo, mejor que al dominante. y si, para trabajos de este tipo quisiera una RTX3090, o una DXG!!! pero cualqueire cosas que sea compatible, funcione mejor que la linea base que tenga y sea barato es valido
      -no me interesa me repliquen, si alguien pasa por aqui y lo ve interesante, que le pique el bichito y se interese por aprender. esto lo publico para los lectores de este blog, para mas nadie
      -conozco que estan haciendo en estos temas varias, pero lo menos que me interesa es que se interesen en lo que yo haga

      si, contracorriente, jajaja

      1. Muy bien amigo la pasión hace la obra y un poco de divulgación no está demás.

        Ejempifiqué con AMD como hubiese hecho con aquella empresa china que ya está fabricando sus GPU y nos pusistes aquel artículo pero oye no olvidar que el reescalado bien se puede implementar en softwares de edición de imagenes como nos ejemplificastes en el primer artículo y por ahí no andan nada pero nada de nada mal GIMP y Krita lo que este último es más para ilustrar y para animación 2D, pero GIMP se las trae sin miedo en edición de imagenes.

        Yo llevo un año haciendo un dragon chino entre otras cosas por que lo mismo quema, ha sido un reto personal puesto que es largo largo y ahora despues de haberlo esculpido y capturado sus texturas les ando dando color es por ello que me sumo a los que se oponen a la explotación de los artitas de videojuegos y cosas como esas, pues se que de lo que hablas si quieres que resulten bien, llevan tiempo pasión y pausa para refrescar.

        Saludos

  2. tu sabes que no he encontrado nada referente a construir una red neuronal en c++ en internet ,todo lo que veo es c# y python…

    1. que tengan interfaz C++, creo que la mayoria, Tensorflow tiene libTensorflow, Torch tiene libTorch que tambien es via C puro,Theano creo que empezo a C++ puro, CNTK tiene, OpenNN tiene, existe tiny-dnn que es superchiquitica

      yo estoy usando ahora Tensorflow y PyTorch con Python (al que considero a uno de los peores lenguajes de programacion de la historia, es insufrible) pero empece probando desde C++. lo que igual, casi todo la ejemplificacion es con Python. pero llevarla a la version C/C++ no es dificil para nada. ademas esta el caso que para la aceleracion que puedo usar, solo habia para Python. por ejemplo, la version C++ de tensorflow trae soporte para CUDA, pero no para opencl

      El sunto es que para ya cuando se van a tener las cosas en ejecucion aplicada, en una aplicacion o sistema, python no sirve, o es muy engorroso. ahi es donde entran como tal las versiones nativas C++. con python puede ser mas “comodo” la parte academico/experimental y durante los entrenamientos y tal

  3. No iba por 5 min leyendo y ya me estaba acordando a lo mismo q hacian en CSI de reescalar la imagen y mostrar el rostro del sujeto XD

    Tremenda pincha tirastes ahi men , buen tiempo te metistes estudiando eso, Like

    1. claro, eso que ves en serie y peliculas es eso mismo, series y peliculas, jajaj

      y esto fue cosa de par de semanas, que hice esto y algunas otras cosas relacionas, en lo que ademas hago otras diferentes, uff

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *