Entrenar modelos con CoreML3 en iOS

0
306

Índice de contenidos

  • 1. Introducción
  • 2. Entorno
  • 3. Probando nuestro modelo
  • 4. Entrenando nuestro modelo
  • 5. Conclusiones

 

1. Introducción

Machine Learning es una tecnología cada vez más demandada en el mundo del desarrollo, desde que salió iOS11 en 2017 tenemos la posibilidad de incorporar a nuestras aplicaciones iOS modelos entrenados de Machine learning, esto se podía hacer a través del framework de Apple CoreML. La limitación que teníamos en ese punto es que no podíamos entrenar a nuestros modelos en el propio dispositivo, únicamente podíamos evolucionar nuestro modelo «fuera» y actualizar la aplicación con el nuevo modelo. Puedes ver un ejemplo de implantación en este tutorial.

En 2018 Apple se alió con IBM para poder entrenar los modelos mediante la interacción de CoreML con Watson Services, básicamente CoreML enviaba el feedback a Watson para que éste se entrenase y Watson enviaba el modelo nuevo a CoreML. Los inconvenientes de esta forma de entrenamiento eran que dependíamos de conexión a internet para entrenar los modelos y por supuesto la privacidad, ya que el modelo no está únicamente en nuestro dispositivo.

Con la llegada de iOS13 , coreML3 y el avance de los procesadores que llevan los dispositivos, ya por fin tenemos la capacidad de entrenar a nuestro modelos en el dispositivo. Si lo pensamos, con FaceId ya se estaba haciendo esta función, ya que el dispositivo va aprendiendo a reconocer nuestra cara y con el tiempo va siendo más exacto sin tener que enviar el modelo fuera. CoreML 3 ya nos ofrece una API para entrenar los modelos, vamos a ver cómo hacerlo con una aplicación que reconozca tipos de animales.

 

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2,3 Ghz Intel Core i9 de 8 núcleos, 32GB DDR4).
  • Sistema Operativo: Mac OS Catalina 10.15.4
  • Entorno de desarrollo: XCode 11.4.1

 

3. Conociendo el contexto

Para hacer uso de CoreML necesitas primero un modelo previamente entrenado que luego podrás refinar tú mediante el entrenamiento. El formato específico de Apple es mlmodel. Existen muchos modelos ya creados por la comunidad para su descarga, nosotros vamos a usar un modelo creado con la herramienta Create ML que la tenemos disponibles en las herramientas de Xcode:

En esta herramienta podemos crear distintos tipos de modelo, os invito a investigarla ya que podremos hacer nuestros propios modelos de forma rápida y fácil, no obstante, no podremos crear modelos actualizables, para ello tendremos que crearla con alguna herramienta externa (TensorFlow, Keras…) y exportarla como CoreMLModel vía coreMLTools.

Vamos a descargar el proyecto inicial desde donde partir nuestro tutorial aquí.

Como hemos comentado antes, vamos a crear una app que se encargue  de reconocer perros y gatos. Una vez descargado vamos a ver que tenemos un proyecto con dos pestañas en el tabbar:

Test: el controlador FirstViewController es el que corresponde a esta pantalla. En él se muestran imágenes de perros y gatos, si pulsamos en next(), cargará una nueva imagen, que de forma aleatoria será de perros o gatos. Aquí vamos a ver cómo funciona nuestro modelo de forma genérica.

Train: El controlador SecondViewController es la clase que corresponde a esta pantalla, aquí vamos a mostrar de nuevo un carrousel de imágenes aleatorias de perros y gatos y es donde vamos a entrenar a nuestro modelo indicándole a qué tipo de animal pertenece.

 

4. Probando nuestro modelo

Ahora vamos a ver como funciona el modelo, en primer lugar vamos a crear un nuevo fichero en Swift llamado MLManager y vamos a escribir lo siguiente:

Lo que hemos hecho aquí es crear un manager como capa de abstracción de CoreML, contiene una referencia a nuestro modelo de datos y una función predict() que nos va devolver una predicción de la imagen que le pasemos. También hemos creado una extensión de nuestro modelo que nos devuelva la información necesaria para la predicción, y las constrains de la imagen, que tratamos en el modelo, veamos las clases involucradas:

MLFeatureValue es la clase que se encarga de empaquetar los datos que entran y salen del modelo. Los valores que obtenemos como predicción y los que enviamos para entrenarlo han de ser de este tipo.

MLImageConstraints es la clase que se encarga de informar del tamaño de las imágenes que se tratan en el modelo de datos.

Para continuar nos vamos a nuestro FirstViewController y creamos una variable de nuestro MLManager

Y en la función next() escribimos lo siguiente:

 

Únicamente hemos asignado a nuestro Label el valor de la predicción, si compilamos y ejecutamos vamos a empezar a obtener predicciones:

Como podemos ver, no siempre acierta, pero vamos a intentar arreglar eso 😉

 

5. Entrenando nuestro modelo

Vamos a empezar a entrenar a entrenar a nuestro modelo, para ello nos vamos a ir a nuestra clase MLManager y vamos a añadir la siguiente función:

Veamos paso a paso lo que va hacer esta función:

En primer lugar creamos un array vacío de tipo MLDictionaryFeatureProvider, que es donde vamos a almacenar los valores de entrada y salida de nuestro modelo:

Después creamos las variables necesarias para identificar los inputs y los outputs de nuestro modelo así como las opciones de la imagen que vamos a tratar:

Ahora crearemos los valores de entrada y salida:

Un vez creamos estos valores vamos a envolverlos en un MLDictionaryFeatureProvider de la siguiente forma:

Por último, vamos a devolver una instancia MLArrayBatchProvider que es una hija de MLBatchProvider, ésta clase simplemente representa una colección de MLFeatureProviders que como hemos comentado antes es lo que necesita el modelo para su entrenamiento.

Ahora vamos a crear la función con la tarea de entrenamiento, añadimos lo siguiente:

Aquí hemos creado una tarea de actualización mediante el constructor de la clase MLUpdateTask en el que le pasamos la URL de nuestro modelo, los datos de entrenamiento (que van a ser lo que hemos creado en la anterior función), y le pasamos un closure en el que vamos a recibir el contexto de la actualización, en ésta vamos a poder ver si la actualización del modelo ha sido válida.

La última función que vamos a crear en nuestro manager es la de guardado como tal:

Aquí hemos obtenido nuestros datos de entrenamiento llamando a la función trainingData() que hemos escrito anteriormente y a continuación llamamos de forma asíncrona la función de actualización del modelo updateModel(), cuando ésta ejecute el closure obtendremos el contexto que hemos mencionado antes.

Si ahora nos vamos a nuestra clase SecondViewController en la función tag() escribimos lo siguiente:

No nos olvidemos de añadir nuestra referencia al MLManager:

Si compilamos y ejecutamos ya podremos ir a la pantalla Train, y empezar a entrenar nuestro modelo. Cuando identifiquemos alguna podremos ver en las trazas que nuestro modelo ha sido actualizado:

 

6. Conclusiones

Existen muchas posibles aplicaciones de la tecnología Machine Learning, por desgracia, en las aplicaciones móviles, no hay muchos desarrolladores que hagan uso de ellas, pero como posibles ejemplos, podríamos predecir comportamientos de navegación entre pantallas de nuestra app, mejorar algoritmos de predicción de sueño, predecir que artículos prefiere leer el usuario, saber que items suele comprar…etc.

Lo que se puede comprobar en este tutorial es que con una implementación muy sencilla podremos hacer uso de esta maravillosa tecnología.

Puedes descargar el proyecto finalizado aquí.

Dejar respuesta

Please enter your comment!
Please enter your name here