A través de la aplicación Guía Escolar en las unidades previas 2 y 3 hemos abordado los bloques de Percepción, Actuación, Representación y Razonamiento Lógico. Bloques que hasta el momento no parecen haber incorporado "inteligencia" a nuestro sistema. Lo que abordamos en esta unidad 4 es el Aprendizaje; la clave de un sistema de inteligencia artificial. El bloque de Aprendizaje nos permitirá llevar a cabo acciones dependientes de la experiencia de nuestro sistema, de esta manera tenemos respuestas a situaciones que no han sido previamente programadas o contempladas.
La forma en la que funciona el bloque de Aprendizaje es mediante algoritmos que introducimos en el sistema, capaces de crear modelos matemáticos a partir de los datos. Estos algoritmos conforman lo que se conoce con el nombre de Machine Learning, campo en el que distinguimos algoritmos de aprendizaje supervisado, no supervisado y reforzado. La diferencia radica principalmente en la guía del diseñador frente al aprendizaje.
Dado que los algoritmos que crean el modelo se crean a partir de los datos, éstos deben estar adecuadamente preparados; tiene que ser una gran cantidad de datos, de calidad y representativos del modelo que queramos crear. De ahí que una parte importante del Machine Learning abarque técnicas de preparación de datos.
Pero es que además debemos contar con datos de reserva para testear y validar el modelo obtenido. Estos datos se aplican una vez hemos finalizado el entrenamiento y verificamos que éste responde a los nuevos datos tal y como pretendemos que lo haga.
Concretamente vamos a implementar una App que permita la detección y clasificación de objetos entrenados por nuestro modelo. Para ello haremos uso de una aplicación también del MIT llamada Personal Image Classifier (PIC en adelante).
Así que comencemos dividiendo el estudio de esta unidad que no deja de ser la obtención de un modelo de Machine Learning aplicando los pasos siguientes:
NECESIDADES:
Necesitamos que en los dispositivos móviles tengamos instalados estas dos aplicaciones:
RECURSOS:
Carpeta Drive con Imágenes y Proyecto
ENLACES:
Nos vamos a https://classifier.appinventor.mit.edu/ y comenzamos el aprendizaje de nuestro modelo. Para ello he tenido que hacer uso de Chrome pues Firefox me daba problemas a la hora de obtener el modelo, concretamente no me dejaba pasar de las fotos a la obtención de dicho entrenamiento. Los pasos a seguir son los siguientes:
Para el diseño de la App en lo que a componentes se refiere os dejo por aquí un vídeo con una introducción a aquellos que he añadido en esta primera fase. Os recomiendo importar el proyecto que he dejado en la carpeta Drive anterior y de ese modo podáis ver con detenimiento cómo quedan las propiedades de cada componente.
Igualmente, insisto en que es más que recomendable empezar desde cero el proyecto pues de ese modo nos enfrentamos a los problemas que tendrás nuestros estudiantes.
Comencemos con la programación y concretamente con la Screen 1. En este caso, la programación es más que sencilla, pues la Screen1 cuenta con dos botones, el primero de ellos nos lleva a la Screen2 mientras que el segundo cierra la App.
Comenzamos creando las variables que vamos a utilizar. En este caso:
Las dos primeras las usaremos para mostrar la cuenta atrás o funcionar en modo cronómetro. Son variables que usaremos cada segundo cuando se dispare el reloj. Luego tenemos la lista de objetos, el nombre del objeto encontrado y la puntuación.
Vamos a crear a continuación un par de procedimientos que iremos necesitando y que parten el proceso de la App en 3 pasos; la cuenta atrás, la búsqueda del objeto y la posible detección o no. Tener en cuenta que el procedimiento Paso1 debe tener una variable de entrada llamada Tiempo. Usar el botón de configuración (engranaje) del bloque.
Pues vamos con su programación:
Este procedimiento simplemente resetea las etiquetas del cronómetro a 0.
En el primer paso de la Screen2 mostramos la primera disposición vertical que como ya vimos muestra la etiqueta con la cuenta atrás. Por ello ponemos a cierto la variable correspondiente y cargamos el tiempo que hayamos puesto en la llamada a este procedimiento (lo veremos en el evento que se ejecuta al cargar la Screen2).
En el segundo paso de la Screen2 mostramos la segunda disposición vertical y marcamos la variable cronómetro a cierto para que empiece el contador.
En el tercer paso mostramos la tercera disposición vertical y anulamos temporalmente el cronómetro para que no siga contando mientras estamos testeando el resultado.
Una vez definidos esos procedimientos vamos a ver qué ocurre cuando cargamos la Screen2.
Es decir, una vez cargada la Screen2 se resetea el cronómetro, aunque de momento no lo usamos, y llamamos al Paso 1, pasando como parámetro Tiempo = 3. Paso 1 mostrará la etiqueta que nos muestra la cuenta atrás en cada segundo del proceso que veremos a continuación del reloj. Como última instrucción, tomamos el primer objeto de la lista Objetos, es decir, la naranja.
Veamos ahora como el procedimiento del reloj hace la cuenta atrás:
Como vemos en este procedimiento podemos distinguir dos partes bien diferenciadas. La parte superior se ejecuta cuando la variable Var_CuentaAtrás es cierta, y esto ocurre durante el Paso 1. Expliquemos un poco el procedimiento: Cuando cargamos la Screen 2, ésta llama al Paso 1, que muestra la etiqueta que hará la cuenta atrás. También se marca la variable Var_CuentaAtrás como cierta, hecho que utiliza este procedimiento del reloj (que se ejecuta cada segundo) para ejecutar el código de la parte superior. En dicho código vemos cómo se decrementa el valor de la etiqueta que muestra la cuenta atrás y en el caso de que llegue a 1 entonces se llama al siguiente paso; el Paso 2, se cambian las variables Var_CuentaAtrás y Var_Cronómetro para que a partir de ahora la App comience el siguiente paso; la búsqueda del primer objeto.
En dicho paso, el procedimiento del reloj ya ejecutará cada segundo la parte inferior de su programación. En dicha parte se incrementa el cronómetro y se ajustan los minutos y horas en caso de que superemos los 60 segundos y los 60 minutos correspondientemente.
A continuación vamos con el funcionamiento de la librería PIC y la forma en la que trabaja la App para la identificación de objetos. Comenzamos con el bloque que lanza la identificación de objetos, esto es, la librería PIC. Como veis no tiene ninguna dificultad.
Una vez lanzada la extensión PIC, ésta obtiene un resultado. Hay que decir que el resultado es una lista doble del tipo ((objeto, probabilidad), (objeto, probabilidad), (objeto, probabilidad)). De forma ordenada nos pondrá el primer elemento el objeto y la probabilidad de que sea ese. De modo que para obtener únicamente el nombre de la predicción tenemos que sacar el primer elemento de la lista; (objeto, probabilidad) y a continuación de nuevo el primer elemento; objeto. De ahí que recurramos a un procedimiento llamado ObtenerObjeto que hace exactamente lo comentado, obtener el nombre (primer elemento) del objeto seleccionado. Veamos un ejemplo:
((ratón, 0.4), (naranja, 0.3), (taza, 0.2)) -> (ratón, 0.4) -> ratón
Para ello hacemos uso de una variable local llamada Local_Seleccionado. Finalmente almacenamos en la variable global Nombre_Obtenido el resultado de la comprobación.
Una vez obtenido el nombre del objeto preguntamos si éste es el objeto que había que detectar, para lo cual usamos la lista Objetos mediante el índice marcado por la variable Puntuación, que va incrementándose a medida que detectamos uno u otro objeto. Si la detección es correcta llamamos al proceso Objeto_Encontrado, sino llamamos al proceso Objeto_No_Encontrado. Pero si la detección es correcta y hemos llegado a 3 (el total de objetos), entonces llamamos al proceso Conseguido porque hemos acabado, inicializando también Puntuación a 1 por si queremos volver a empezar.
Veamos los procesos Objeto_Encontrado y Objeto_No_Encontrado:
Como podemos ver no son nada complicados. En el primer caso le damos la enhorabuena, aumentamos la Puntuación y seleccionamos el siguiente objeto. En el segundo paso le decimos que siga intentándolo.
Ambos procesos llaman al paso 3 para mostrar esa información.
Seguimos con el bloque Conseguido cuando hemos finalizado la detección de los 3 objetos. Este proceso llama además al proceso MostrarTiempo que le dará el tiempo en el que ha conseguido el objetivo.
Por último os paso el código de los botones que quedaban por programar; Btn_Atrás y Btn_Aceptar. El primero hace volver a la App a la pantalla inicial, mientras que el segundo se sitúa en el Paso 3 y permite continuar con la búsqueda llamando al Paso 2.