En la serie documental inglesa Faking it de Channel 4, el pintor y decorador Paul O’Hare, de Liverpool, se enfrenta al reto de, en solo cuatro semanas, hacerse pasar por un artista reconocido frente a los críticos de una galería de arte de Londres. Aquí vamos a mostrarte cómo hacerlo en menos de media hora con la ayuda de Docker, AWS y Deep Learning, incluido el tiempo que tardas en leer este post. Y por menos de 10 euros.
“Los grandes artistas copian, los genios roban” — Pablo Picasso
Un toque de genialidad
Para acelerar tu transformación, vamos a utilizar un sistema de inteligencia artificial. Este sistema se basa en una red neuronal profunda que crea imágenes artísticas indistinguibles (en nuestra opinión) a las obras originales. ¿Cómo lo hace? Combinando el contenido de una fotografía (un retrato o paisaje) con el estilo de otra imagen (normalmente, la obra de un artista reconocido). Usamos un algoritmo llamado neural-style, basado en una potente red profunda de procesamiento de imágenes.
Pero es mucho más fácil entender lo que hace echando un vistazo a las imágenes resultantes. Estas imágenes bien valen mil horas de investigación o líneas de código 😉
El misterioso funcionamiento de este algoritmo parte de la reutilización de la red neuronal profundaVGG19, desarrollada por investigadores de Oxford y ganadora de la competición de procesamiento de imágenes ImageNetChallenge 2014. Esta red emplea múltiples capas de redes neuronales convolucionales para afinar una imagen partiendo de los píxeles y alcanzando un nivel superior (una representación más conceptual de la imagen). De hecho, un nivel tan superior que el estilo se representa de manera fiel con las correlaciones que surgen en los niveles más profundos de la red. Es así, mediante esta descomposición de estilo versus píxeles, como la red puede explotarse para crear imágenes nuevas, redibujando los píxeles de una foto con el estilo de una imagen diferente.
Hasta ahora, implementar y desplegar este algoritmo no era tarea fácil por una serie de razones. En este post vamos a explicar cómo hacerlo con solo tres comandos. Pero antes vamos a exponer algunos detalles. Ahora que ya hemos resuelto cómo dar las pinceladas (VGG19), necesitaremos:
- Una paleta de pintor: librerías torch para Deep Learning, que permiten implementar nuestro pintor neuronal (usando los algoritmos desarrollados por Justin Johnson)
- y una forma de acelerar nuestra producción de obras de arte, ya que no queremos pasarnos horas, días, semanas o meses esperando a obtener los resultados. Usaremos unidades de procesamiento de gráficos (GPU) y una CPU tradicional para acelerar nuestro algoritmo de Deep Learning (nuestras pinceladas) y reducir el tiempo de espera a unos pocos minutos.
Problemas de la pintura moderna
Casi hemos llegado. Pero antes tenemos que solucionar un último desafío. La innovación, las dependencias y los cambios en las herramientas y librerías de aprendizaje automático pueden dar al traste a menudo con nuestro entorno de trabajo. Solamente la cantidad de librerías y requisitos necesarios para poner en funcionamiento este algoritmo ya supone un problema:
- controladores de nvidia, para usar las GPU
- kit de desarrollo CUDA, para poder realizar cálculos en las GPU
- librerías cudnn, para acelerar las operaciones de redes profundas en la GPU
- torch7, un ecosistema para el desarrollo de redes profundas, y sus dependencias (protobuf)
- el módulo loadcaffe lua para cargar redes preconstruidas, mediante el cual aplicaremos la red VGG19.
Necesitamos todo este software para automatizar el funcionamiento del algoritmo con diferentes imágenes, estilos y parámetros con el fin de conseguir resultados más impactantes. Todo esto da lugar a un entorno frágil que puede dejar de funcionar si una actualización inesperada entra en los controladores de GPU o en la versión de torch. Esto no solo significa que la configuración del primer entorno es muy trabajosa, sino que además tendremos que hacer este esfuerzo una y otra vez para que todo se mantenga en buena forma. Esto se aleja mucho de nuestro ideal: el artista debe tener el lienzo a mano por si le viene la inspiración, y las herramientas listas para poder canalizar su creatividad, que nunca debería estar supeditada a la molesta dependencia de un entorno en constante cambio.
Docker parece ser la mejor solución a nuestro problema. Pero hay una pega: Docker aísla nuestro proceso de su entorno, y eso incluye los recursos de hardware específicos de la máquina “host” en la que se aloja. Desgraciadamente, nuestro algoritmo de redes profundas requiere acceso directo a una GPU. Docker es la solución, pero necesitamos algo más.
La respuesta a nuestras dudas es nvidia-docker: un wrapper para Docker que nos permite utilizar contenedores que aprovechen las GPU de nvidia. Con este comando, Docker montará automáticamente los controladores de las GPU del host en cualquier otro contenedor a través de un volumen, creando así un canal a través del cual cualquier proceso Docker puede ejecutar código en las GPU. Esto funcionará independientemente de las GPU que estén disponibles en el host o del código en funcionamiento en el contenedor.
En el caso concreto de nuestro proyecto artístico, los requisitos del host se reducen drásticamente: de toda la lista de arriba, solo necesitaremos instalar Docker, nvidia-docker y los controladores de GPU adecuados. El resto de dependencias estarán incluidas dentro de una imagen de Docker, construida de manera reproducible mediante un archivo Dockerfile y garantizando que todas las piezas y engranajes puedan congelarse en versiones interoperables y funcionales.
Herramientas de pintura y suministros
Ahora solo nos falta un sitio donde poner nuestro sistema a funcionar. Vamos a recurrir a la nube pública, en concreto a AWS y sus GPU —máquinas virtuales optimizadas para cálculo. AWS ofrece dos familias de instancias GPU, pero vamos a usar las nuevas instancias P2de Amazon EC2. Estas instancias están diseñadas para lidiar con duras cargas de trabajo de Deep Learning, como la que tenemos en nuestras manos. Vamos a probarlo:
$ docker-machine create — driver amazonec2 \
— amazonec2-instance-type p2.xlarge \
— amazonec2-access-key *** \
— amazonec2-secret-key *** nvidia-docker
Antes de ejecutar este comando, necesitarás:
- Instalar Docker en Mac o en Windows, o docker-machine en tu portátil u ordenador si aún no lo has hecho.
- Tener una cuenta en AWS. Desgraciadamente, las instancias P2 o G2 no están disponibles para la capa gratuita de AWS… pero podemos hacer mucho arte por menos de 10 euros. Si tu portátil o tu ordenador tiene un chip NVIDIA, ¡puedes ejecutar tus scripts en local!
- Crear un par de claves de acceso/secretas, y
- Como no puedes usar las instancias P2 o G2 por defecto en AWS, abrir un ticket al soporte de AWS para aumentar el límite de las instancias P2 o G2 que puedes utilizar. Solo lleva unas pocas horas conseguirlo.
Instalar los controladores NVIDIA y nvidia-docker es el segundo paso en nuestro viaje de conversión en artistas (de mentira). Hemos desarrollado un script simple que nos hace todo el trabajo:
$ docker-machine ssh nvidia-docker
$ git clone https://github.com/albarji/neural-style-docker
$ cd neural-style-docker
$ ./scripts/install-nvidia.sh
Si todo va según lo planeado, obtendrás el siguiente resultado:
Con este último comando solo estamos instalando el paquete de software nvidia y mandando una consulta a la tarjeta de GPU para asegurarnos de que está todo bien.
Para dibujar, hay que cerrar los ojos y cantar…
Dijo una vez Picasso. Pero antes de cerrar los ojos, aquí está el último paso: desplegar el algoritmo de aprendizaje automático que va a hacer la magia:
$ ./scripts/fake-it.sh goldengate.jpg vangogh.jpg
Ahora solo tienes que descargar las imágenes resultantes y publicarlas en un foro de arte como Deviantart o llevarlas a la galería de arte más cercana ;). Desde tu portátil/ordenador, lanza esto:
$ docker-machine scp -r nvidia-docker:/home/ubuntu/neural-style-docker/output .
Y obtendrás los resultados en el directorio actual (en el ejemplo, goldengate_by_vangogh.jpg).
Aquí te dejamos unos pocos ejemplos más de lo que puedes hacer:
Dame un museo…
…y lo llenaré, dijo una vez más Pablo Picasso. ¡Nosotros también podemos hacerlo! Y sin invertir toda una vida en ello. Hemos probado algunos estilos y algo de contenido para comenzar, así que solo tenéis que recostaros, relajaros, cerrar los ojos y cantar. Al aplicar diferentes estilos a una misma imagen, nos hacemos una idea de cómo diferentes pintores habrían representado una misma escena o un mismo retrato.
Como tributo al Docker y por las horas, días y semanas que nos ha ahorrado, hemos decidido abrir nuestro propio museo Docker:
Ahora te toca a ti. Escoge tu artista o cuadro favorito y algunas imágenes y conviértelas en una obra de arte. ¡Comparte tu trabajo con nosotros! Y síguenos en Twitter (@albarjip y @lherrerabenitez).
PD: No olvides borrar tus instancias P2 cuando termines.
$ docker-machine rm nvidia-docker
Nuestras galerías
Visita “nuestras” obras de arte en:
- http://lherrerabenitez.deviantart.com/gallery/
- http://albarji.deviantart.com/gallery/60433505/neuralstyle
Referencias de aprendizaje automático, Deep Learning y Docker
¿Eres nuevo en aprendizaje automático, Deep Learning o Docker y quieres saber más? Prueba con estos enlaces…
- https://arxiv.org/abs/1508.06576 — A neural algorithm of artistic style
- http://www.robots.ox.ac.uk/~vgg/publications/2015/Simonyan15/ — Very Deep Convolutional Networks for Large-Scale Image Recognition (red VGG19)
- https://github.com/jcjohnson/neural-style—Una implementación torch del trabajo A Neural Algorithm of Artistic Style, de Leon A. Gatys, Alexander S. Ecker y Matthias Bethge.
- http://image-net.org/challenges/LSVRC/2014/ — ImageNet 2014 Challenge
- https://www.coursera.org/learn/machine-learning—Curso de Aprendizaje automático de Andrew Ng
- https://github.com/soumith/cvpr2015/blob/master/Deep%20Learning%20with%20Torch.ipynb — Deep Learning with Torch
- https://github.com/docker/labs—Tutoriales de Docker
- https://github.com/NVIDIA/nvidia-docker — NVIDIA Docker
Construir y optimizar la imagen docker
Nos gustaría mejorar y reducir el tamaño de nuestra imagen docker. ¿Nos ayudas?
- Clona el proyecto
$ git clone https://github.com/albarji/neural-style-docker
- Modifica alguno de los archivos del proyecto
- Construye una nueva imagen:
$ sudo nvidia-docker build -t neural-style:2.0 .
- Comprueba que funciona correctamente con el ejemplo en el documento:
$ sudo nvidia-docker run – rm -v $(pwd):/images – entrypoint python neural-style /neural-style/variants.py – contents img/docker.png – styles img/starryNight.jpg – outfolder
Escrito en colaboración con Luis Herrera Benítez, capitán de Docker y Embajador de AWS.