General | Aprende Machine Learning https://www.aprendemachinelearning.com en Español Tue, 17 Oct 2023 07:26:38 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 https://www.aprendemachinelearning.com/wp-content/uploads/2017/11/cropped-icon_red_neuronal-1-32x32.png General | Aprende Machine Learning https://www.aprendemachinelearning.com 32 32 134671790 LLM: ¿Qué son los Grandes Modelos de Lenguaje? https://www.aprendemachinelearning.com/llm-que-son-los-grandes-modelos-de-lenguaje/ https://www.aprendemachinelearning.com/llm-que-son-los-grandes-modelos-de-lenguaje/#respond Fri, 15 Sep 2023 11:15:26 +0000 https://www.aprendemachinelearning.com/?p=8493 Introducción a los LLM, en Inglés Large Language Model, que revolucionaron el campo del Procesamiento del Lenguaje Natural (NLP) crearon tendencia gracias a ChatGPT e incluso pusieron en cuestión la posibilidad de alcanzar el AGI, el punto de quiebre en el que la Inteligencia Artificial se vuelve autónoma y más poderosa que la inteligencia humana.

The post LLM: ¿Qué son los Grandes Modelos de Lenguaje? first appeared on Aprende Machine Learning.

]]>

Introducción a los LLM, en Inglés Large Language Model, que revolucionaron el campo del Procesamiento del Lenguaje Natural (NLP) crearon tendencia gracias a ChatGPT e incluso pusieron en cuestión la posibilidad de alcanzar el AGI, el punto de quiebre en el que la Inteligencia Artificial se vuelve autónoma y más poderosa que la inteligencia humana.

En este artículo vamos a comentar cómo surgen las LLMs, el cambio de paradigma, sus modelos actuales y cómo disrumpe en prácticamente todas las áreas laborales.

Definición de LLM

Los Grandes Modelos de Lenguaje son modelos de propósito general de Inteligencia Artificial desarrollados dentro del campo del Procesamiento del Lenguaje Natural que puede entender y generar texto al estilo humano.

Un LLM es un modelo estadístico que determina la probabilidad de ocurrencia de una secuencia de palabras en una oración.

Los modelos más famosos actuales “GPT” tienen una arquitectura basada en Transformers (2017) y usan redes neuronales que son entrenadas con inmensas cantidades de texto obtenidos y “curados” de internet, incluyendo libros, periódicos, foros, recetas, legales, paper científicos, patentes, enciclopedias.

Para darnos una idea de la inmensa cantidad de información que utiliza GPT-3, es el equivalente a que una persona leyera 120 palabras por minuto las 24 horas del día sin parar durante 9 mil años.

Cambio de paradigma

Desde hace más de 50 años se vienen creando diversas arquitecturas de redes neuronales que van siendo refinadas y especializadas en tareas como las redes convolucionales para clasificación de imágenes, Redes Recurrentes para NLP, Redes para audio, redes profundas para ventas. Dentro del propio campo de NLP se entrenaban modelos de lenguaje para distintas tareas con datasets específicos, por ejemplo para “análisis de sentimiento” ó traducción de textos de inglés a español, resumen de noticias.

Cuando surge la arquitectura de Transformers en 2017, confluye una serie de buenas prácticas que facilitan el poder entrenar grandes cantidades de texto de manera no supervisada (next-word) utilizando el poder de procesamiento de las GPUS (en paralelo) con una buena relación de precio, tiempo y calidad en los resultados obtenidos.

Entonces, surge algo por sorpresa: un modelo del lenguaje que sólo era entrenado para traducir texto de inglés a francés era capaz de responder a preguntas como “¿cuál es la capital de Francia?” ó de realizar tareas como la de análisis de sentimiento o resumen de conceptos: todo ello en un mismo modelo!

A esas capacidades inesperadas que adquiere el modelo se le conocen como “zero-shot“. Además una vez que el modelo queda entrenado, se lo puede utilizar en diversidad de tareas y se puede seguir reutilizando haciendo un “fine-tuning” con pocos datos adicionales y seguir expandiendo sus capacidades.

¿Ser o no ser con Código?

Una curiosidad: Al crear los inmensos datasets para entrenar los LLMs se excluía deliberadamente los bloques de código (Python, java, javascript) como una manera de limpiar los datos. Sin embargo más tarde descubrieron que al incluir código, los modelos eran capaces de programar, pero también se volvían “más inteligentes” para realizar razonamientos lógicos.

¿Una SuperInteligencia?

Cuando OpenAI tuvo entrenado al modelo GPT-2 en 2019 lo vio tan potente que creyó que no era buena idea liberarlo por miedo al posible mal uso que se pudiera hacer de él.

Con GPT3 el modelo LLM ya era capaz de crear cuentos, poemas y noticias falsas que eran indistinguibles -apenas-de la escritura humana.

El modelo Bard(Lamda) de Google logró confundir a un ingeniero que trabajaba en su desarrollo para hacerle creer que tenia conciencia propia, que la IA era un “ser sintiente”. El test de Turing estaba definitivamente resulto.

A finales de 2022 OpenAI lanza ChatGPT que se viraliza en redes sociales haciendo que un producto de este tipo alcance la cantidad de un millón de usuarios en menos de una semana, algo comparable al crecimiento de adquisición de usuarios que logran las redes sociales más populares.

Entonces surgen montones de dudas: ¿Es realmente inteligente ChatGPT? Puede contestar preguntas de lo que sea? Puede saber más que un médico? Va a reemplazar mi trabajo? Puede convertirse en una tecnología peligrosa?

De hecho a principios de 2023 con la salida de GPT-4 dentro de ChatGPT un grupo de 1000 científicos de todo el mundo firmaron una petición para detener el desarrollo de este tipo de modelos de lenguaje durante 6 meses para estudiar si es responsable y beneficioso su uso libre o si por el contrario, estamos a tiempo de frenar esta tecnología que nos puede llevar al fin del mundo…

Si bien mantener una charla con este tipo de bots es sorprendente, los científicos reputados como Andrew Ng (deeplearning.ai) y Yann LeCun (Meta) mantienen la calma (y el escepticismo) dando un mensaje de que una IA que “sólo aprendió a predecir la próxima palabra” aún está lejos de convertirse en AGI y que de hecho, sufre de alucinaciones, no puede realizar cálculos matemáticos sencillos ni deducciones lógicas, está lejos de ser una herramienta peligrosa.

Modelos que siguen Instrucciones

Dentro del desarrollo de LLMs hay dos grandes tipos en los que los podemos subdividir; los modelos “base” (ó crudos) y los “Instruction Tuned LLM“. Los modelos Base son los modelos “generales” que están entrenados en predecir la siguiente palabra. Los modelos tuneados para seguir instrucciones son entrenados para seguir instrucciones a partir de un grupo de ejemplos; estos son los que permiten que tengamos diálogo mediante chats, como el propio ChatGPT.

Una analogía entre estos dos modelos, podría ser la de un médico clínico (conocimiento general) y un médico especialista. Si preguntamos al médico “base” sobre unos síntomas nos dará una respuesta general que puede ser buena, pero si la pregunta es específica para un área (ej. en cardiología) obtendremos mejor respuesta del médico especialista.

Los modelos de instrucciones son los que nos permiten hacer que el LLM pueda generar listas con resultados, o crear canciones, contestar preguntas con mayor precisión pero también prevenir dar malas respuestas ó inapropiadas (también llamadas tóxicas) que puede contener el modelo base (sin filtros). El modelo base podría contener información sobre cómo fabricar un químico peligroso, pero dentro del finetuning del modelo basado en instrucciones podríamos evitar que esa información aparezca en sus respuestas.

Los Instruction-models están entrenados para ser “Helpful-Honest-Harmless“, es decir que brinden ayuda, sean honestos e inocuos. Pero ¿cómo evaluamos al modelo de instrucciones? ¿cómo sabemos que podemos liberarlos al público sin peligro? Mediante el mecanismo de RLHF

EL RLHF, “un tipo en el Loop”

El Reinforcement Learning with Human Feedback es un paso adicional para mejorar al modelo. Para ello pasamos preguntas y las respuestas generadas por el LLM a un grupo de personas que evaluarán si la respuesta es de calidad ó si por el contrario incumple las normas. Esto retroaliementará mediante “premios ó castigos” al modelo, permitiendo reajustar sus parámetros gracias al Aprendizaje por refuerzo.

Es como si intentáramos dotar de una personalidad al modelo para que se “comporte” de una forma esperada y respetuosa.

Este paso adicional en donde necesitamos un grupo de personas es un coste adicional que sólo pueden permitirse grandes empresas. Lo interesante como Ingenieros o Científico de Datos es poder contar con un modelo que siga instrucciones que sea libre y poder ajustarlo a nuestro antojo.

Panorama LLMs 2023 y la llama que llama

Desde 2018 que empezaron a aparecer LLMs entrenadas por las grandes compañías IT, recordemos algunas de ellas, su aporte y los modelos recientes, a Septiembre de 2023.

LLM destacadas

Fecha, nombre, compañía, parámetros en “Billions”*, aporte

*NOTA, recuerda que el uso de “Billions” en inglés es distinto al valor Billón del español.

  • 2018 Octubre – BERT – Google – ? – Utiliza la Arquitectura Transformer sólo su rama encoder.
  • 2019 Julio – Roberta – Meta – 0.35B – versión multilenguaje optimizada de BERT.
  • 2019 Noviembre – GPT2 – OpenAI – 1.5B – Entrenado para predecir la Siguiente Palabra. Utiliza sólo decoder de la arquitectura de Transformers.
  • 2020 Mayo – GPT3– OpenAI – 175B – Alcanza un nivel de conversación al nivel humano. Puede generar textos, noticias o literatura fantástica sin problemas.
  • 2022 Enero – Lamda – Google – 137B – Modelo de lenguaje tuneado para chat y diálogos, priorizando ser agradable a los humanos.
  • 2022 Marzo – Chinchilla – DeepMind – 70B – Demostró que con un “presupuesto limitado” la mejor performance no se consigue con modelos enromes si no con modelos más pequeños entrenados con más datos.
  • 2022 Marzo – InstrucGPT – OpenAI – 175B – Entrenado con RLHF para seguir instrucciones
  • 2022 Abril – PALM – Google – 540B – Supera al hombre en muchas tareas del “bigbench” definidas como punto de referencia.
  • 2022 Octubre – FLANT5 – Google – 11B – Modelo basado en PALM para seguir instrucciones libre bajo licencia Apache 2.
  • 2022 Noviembre – BLOOMBigScience – Entrenado en 59 idiomas para uso libre.
  • 2023 Febrero – Llama – Meta – 13B/65B – “supera a GPT3 siendo 10 veces más pequeño”. Es libre pero no para uso comercial.
  • 2023 Marzo – GPT4 – OpenAI – ? – Se desconoce su tamaño, pero es el modelo más poderoso en la actualidad.
  • 2023 Mayo – Palm2 -Google – ? – “Tiene capacidades multi-lenguaje y de razonamiento más eficientes con menor cómputo”.
  • 2023 Mayo – FalconTII – 40B – “40 billones de parámetros entrenados en un trillón de tokens”.
  • 2023 Julio – LLAMA2 – META – 180B – Permite ser utilizado comercialmente!
  • 2023 Septiembre – Falcon – TII – 180B – Opensource! Supera a LLAMA2

Conclusión

Los Grandes Modelos de Lenguaje están apoderándose de toda la popularidad de la Inteligencia Artificial y lo tienen justificado; son realmente grandiosas en sus tareas y han logrado traer a la agenda de los organismos internacionales la importancia de regular este tipo de tecnologías, su importancia, riesgos e impacto que tendrá en nuestra sociedad (global), incluyendo el plano económico y laboral.

Las LLMS han pateado el tablero a las grandes compañías, creando una nueva carrera en IA, el propio Google vio amenazado su negocio como motor de búsqueda, Microsoft trazo alianzas estratégicas con OpenAI y reflotó a Bing agregando funciones de Chat con IA y dando acceso a LLMs desde su servicio en la nube Azure.

Las personas que están trabajando con esta tecnología creen que las LLMs se han convertido en compañeros indispensables para casi cualquier tareas, potenciando nuestras tareas, no para reemplazarnos si no para aumentarnos (en marketing, programación, toma de decisiones, investigación, escritura…)

En próximos artículos hablaré sobre el prompt engineering, las librerías python que nos ayudan a implementar LLMs en local y en la nube y en cómo construir nuestros propios sistemas privados al estilo de ChatGPT.

Espero que hayas disfrutado del artículo!

The post LLM: ¿Qué son los Grandes Modelos de Lenguaje? first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/llm-que-son-los-grandes-modelos-de-lenguaje/feed/ 0 8493
Seguimiento de Objetos con Yolo v8 y BYTETrack – Object Tracking https://www.aprendemachinelearning.com/seguimiento-de-objetos-con-yolo-v8-y-bytetrack-object-tracking/ https://www.aprendemachinelearning.com/seguimiento-de-objetos-con-yolo-v8-y-bytetrack-object-tracking/#comments Fri, 08 Sep 2023 11:15:20 +0000 https://www.aprendemachinelearning.com/?p=8271 Realiza un proyecto python de 100 líneas para detectar y seguir personas en video. Usaremos Yolo v8 y Bytetrack.

The post Seguimiento de Objetos con Yolo v8 y BYTETrack – Object Tracking first appeared on Aprende Machine Learning.

]]>

En artículos anteriores, hablamos sobre la clasificación de imágenes y sobre cómo hacer detección de objetos en tiempo real gracias a Yolo. Esta vez hablaremos sobre “Seguimiento de objetos” (Object Tracking en inglés) en donde sumamos una nueva “capa” de inteligencia dentro del campo de Visión Artificial.

La Problemática del rastreo de objetos

Imaginemos que tenemos un cámara de seguridad en donde aplicamos un modelo de Machine Learning como Yolo que detecta coches en tiempo real. Agregamos un “rectángulo rojo” (ó caja) sobre cada automóvil que se mueve. Bien. Queremos contabilizar cuántos de esos vehículos aparecen en pantalla durante una hora; ¿cómo hacemos?. Hasta ahora, sabemos los coches que hay en cada frame del video. En el primer fotograma hemos detectado 3 coches. En el segundo cuadro tenemos 3 coches. ¿Son los mismos ó son coches distintos? ¿Qué ocurre cuando en el siguiente fotograma aparece un cuarto coche? ¿Cuántos coches sumamos? 3 + 3 + 4 ? Tendremos un mal recuento en el transcurso de una hora, si no aplicamos un algoritmo adecuado para el rastreo de vehículos.

Espero que con ese ejemplo empieces a comprender la problemática que se nos plantea al querer hacer object tracking. Pero no es sólo eso, además de poder identificar cada objeto en un cuadro y mantener su identidad a lo largo del tiempo, aparecen otros problemas “clásicos”: la oclusión del objeto la superposición y la transformación.

  • Oclusión: cuando un objeto que estamos rastreando queda oculto momentáneamente o parcialmente por quedar detrás de una columna, farola ú otro objeto.
  • Superposición de objetos: ocurre cuando tenemos a dos jugadores de fútbol con camiseta blanca y uno pasa por detrás de otro, entonces el algoritmo podría ser incapaz de entender cuál es cada uno.
  • Transformación del objeto: tenemos identificada a una persona que camina de frente con una camiseta roja y luego cambia de rumbo y su camiseta por detrás es azul. Es la misma persona pero que en el transcurso de su recorrido va cambiando sus “features”.
  • Efectos visuales: ocurre cuando al cristal de un coche le da el sol y genera un destello, lo cual dificulta su identificación. O podría ser que pase de una zona soleada a una con sombra generando una variación en sus colores.

Algoritmos de Seguimiento:

Para poder realizar el object tracking y resolver los problemas antes mencionados se desarrollaron diversos algoritmos, siendo los más conocidos sort, deepsort, bytetrack y actualmente siguen apareciendo nuevos.

Lo básico que queremos de un algoritmo de detección es que primero identifique al objeto y que pasado el tiempo mantenga su “etiqueta”. Pero… que lo haga muy rápido, porque si estamos analizando un video en vivo no podemos congelar la imagen durante más de un segundo, ó resultará en una experiencia poco agradable.

Listemos los algoritmo de Tracking y algunas de sus características, más adelante comentaremos con un poco más de detalle el algoritmo de Byte Track, que es el que utilizaremos en el ejercicio.

  • Sort (Simple Online Realtime Tracking): utiliza la posición y el tamaño de la caja que contiene al objeto. Se predice la posición/trayectoria por su velocidad constante.
  • DeepSort: Mejora a Sort al agregar información sobre la apariencia del objeto mediante un vector creado a partir de las capas ocultas de una red neuronal profunda que debe ser entrenada.
  • StrongSort: Modifica las funciones de costo y métricas de DeepSort para mejorar sus resultados.
  • FairMOT: integra la identificación del objeto dentro de la propia red de detección encoder-decoder.
  • ByteTrack: utiliza las cajas de detección de alta y baja confianza para mantener trayectorias que puedan estar poco visibles durante el video.

En un principio de los tiempos, se intentaba poder identificar a una clase de objeto y mantener su localización. Actualmente y gracias al mayor poder de cómputo, el tipo de tarea/problema se conoce como “Multiple object tracking with Re-Identification“; en donde podemos detectar diversas clases y mantener su identificación con el paso del tiempo.

Casos de Uso

Estos son algunas de las aplicaciones que puedes realizar con Object Tracking

Seguimiento de personas / objeto de interés

Fuente de la imágen: artículo

Contabilizar vehículos (u objetos)

Entrada en una zona determinada

Trazado de rutas

¿Cómo funciona ByteTrack para seguimiento de Objetos?

ByteTrack utiliza IoU en su algoritmo. La mayoría de métodos obtienen las identidades asociando cajas de detección si los scores son mayores a un umbral (por ej. mayor a 80%). Los objetos con menor score de detección -por ej. objetos que estén parcialmente ocultos tras “una farola”- son eliminados causando trayectorias de identificación erróneas. Para resolver este problema, ByteTrack utiliza los scores de confianza altos y bajos.

IoU: nos da un porcentaje de acierto del área de predicción frente a la bounding-box real que queríamos detectar.

Comprendamos el algoritmo paso a paso:

Inicialización: Tenemos las entradas como una secuencia de Video “V”, el detector de objetos (Yolo) “Det”; el límite de confianza de score “L”. La salida será “T” siendo las rutas que sigue en el video. Comenzamos con T vacíos.

Para cada cuadro de video, predecimos las cajas de detección y scores usando Yolo. Separamos todas las cajas en dos partes: “D_high” y “D_low” según su puntaje alto o bajo del umbral “L”.

Luego de separar las cajas con los puntajes Altos y Bajos, usamos el Kalman Filter para predecir las nuevas ubicaciones en el frame actual de cada Trayectoria T.

La primer asociación se realiza entre las cajas de Score alto D_high y todos los tracks T (incluyendo los tracks perdidos “T_lost”).

Mantenemos las detecciones que quedaron sin asociarse en “D_remain” y los trayectos sin pareja en “T_remain”.

La segunda asociación intentará emparejar las cajas de bajo puntaje D_low y las restantes rutas “T_remain” de la primer asociación.

Seguiremos manteniendo las trayectorias huérfanas en “T_re-remain” y borrar todas las cajas sin emparejar de bajo puntaje.

Para los tracks sin pareja de esta segunda iteración, las pondremos en T_lost. Para cada track en T_lost si se mantiene sin relación por “30 frames”, lo eliminamos de “T”.

Finalmente inicializamos nuevos trayectos desde las cajas de alto score sin emparejar que teníamos en D_remain de la primer asociación.

NOTA: para realizar las asociaciones podemos usar métodos de “location” o “feature”. La principal innovación del algoritmo de ByteTrack es el uso de los scores de alta y baja confianza de las cajas detectadas.

Puedes revisar la implementación oficial en Python de ByteTrack en este enlace.

Comentario sobre Kalman Filter

No sólo la apariencia del objeto (features) es importante si no también la información sobre su movimiento y trayectoria. El Kalman filter predice donde estará un objeto que estaba en el frame t-1 en el próximo frame t. La distancia entre la predicción y la posición real detectada será el costo de la función. El Kalman filter es un filtro Lineal y asume el mismo ruido para todos los objetos.

¿Estado del arte?

En la siguiente gráfica vemos que ByteTrack tiene un buen equilibrio entre velocidad de detección y predicción de trayectorias, siendo el mejor de su momento (oct-2021), hasta principios de 2022. En 2022 fue superado por BoT-SORT y a finales de ese mismo año por SMILETrack.

Ejercicio: seguimiento de Skaters

Vamos a crear un script de 100 líneas en donde utilizaremos un modelo Yolo v8 preentrenado para la detección de 80 clases de objetos diferentes, incluyendo personas y skates. Iteraremos por los frames de un video en donde realizaremos la detección y alimentaremos con sus features al algoritmo de rastreo ByteTrack que se encargará de identificar al objeto.

Si tenemos éxito, veremos cómo el “objeto” se mantiene con el mismo identificador durante el video.

Si el algoritmo falla en su detección, asignará un nuevo ID, pues creerá que se trata de un objeto nuevo.

Crear el Environment

Puedes clonar el repositorio GitHub del ejercicio antes de empezar, para contar con los archivos necesarios.

Crea un nuevo ambiente Python utilizando Anaconda ejecutando:

conda create -n tracking python=3.9 numpy

Activa el ambiente

conda activate tracking

Instala ahora los paquetes con las versiones necesarias mediante pip

pip install -r requirements.txt
Las 80 clases que podemos detectar con el modelo standard de YOLO.

Código python

Primero importamos los paquetes que utilizaremos

import cv2
import numpy as np
import torch
from ultralytics.nn.autobackend import AutoBackend
from ultralytics.yolo.data.dataloaders.stream_loaders import LoadImages
from ultralytics.yolo.utils.ops import non_max_suppression, scale_boxes
from ultralytics.yolo.utils.plotting import Annotator, colors

from bytetrack.byte_tracker import BYTETracker

Inicialización de variables, aqui elegimos el video mp4 al que le aplicaremos la detección, en mi ejemplo el archivo se llama skateboard_01.mp4.

save_vid = False
video_file = 'skateboard_01.mp4'
vid_writer = None
save_path = video_file[:-4] + '_output.mp4'

conf_thres = 0.25
iou_thres = 0.45
classes = [0, 36]  # person, skateboard
agnostic_nms = False
max_det = 100
line_thickness = 2
imgsz = (640, 640)
vid_stride = 1

Cargamos el modelo preentrenado “nano” de Yolo (el más pequeño), la primera vez, el modelo se descargará.

detection_model = AutoBackend("yolov8n.pt")
detection_model.warmup()
stride, names, pt = detection_model.stride, detection_model.names, detection_model.pt

Instanciamos el algoritmo de Detección:

bytetracker = BYTETracker(
    track_thresh=0.6, match_thresh=0.8, track_buffer=120, frame_rate=30
)
tracker = bytetracker

Creamos un “loader” de las imágenes del video que vamos a procesar e inicializamos el Archivo de video mp4 de Salida:

dataset = LoadImages(
    video_file,
    imgsz=imgsz,
    stride=stride,
    auto=pt,
    transforms=None,
    vid_stride=vid_stride,
)
path, im, im0s, vid_cap, s = next(iter(dataset))

fps = vid_cap.get(cv2.CAP_PROP_FPS)
w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
vid_writer = cv2.VideoWriter(
    save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)
)

Entramos al Loop principal; aqui, realizaremos la detección de los objetos y luego aplicaremos el algoritmo de seguimiento para “re-identificar” objetos. Luego “imprimimos” en pantalla (frame) una caja y su ID.

for frame_idx, batch in enumerate(dataset):
    path, im, im0s, vid_cap, s = batch
    detections = np.empty((0, 5))
    im = torch.from_numpy(im).to("cpu").float()  # uint8 to fp16/32
    im = torch.unsqueeze(im/255.0, 0)

    result = detection_model(im)

    p = non_max_suppression(
        result, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det
    )

    for i, det in enumerate(p):
        p, im0, _ = path, im0s.copy(), getattr(dataset, "frame", 0)

        if det is not None and len(det):
            det[:, :4] = scale_boxes(
                im.shape[2:], det[:, :4], im0.shape
            ).round()  # rescale boxes to im0 size

        track_result = tracker.update(det.cpu(), im0)

        annotator = Annotator(im0, line_width=line_thickness, example=str(names))

        # dibujar los contornos de los objetos detectados
        if len(track_result) > 0:
            for j, (output) in enumerate(track_result):
                bbox = output[0:4]
                id = int(output[4])  # integer id
                cls = int(output[5]) # integer class
                conf = output[6]
                label = f"{id} {names[cls]} {conf:.2f}"
                annotator.box_label(bbox, label, color=colors(cls, True))

    im0 = annotator.result()
    cv2.imshow(str(p), im0)  # mostrar en pantalla
    cv2.waitKey(1)

    vid_writer.write(im0)  # guardar frame en video

vid_writer.release()
cv2.destroyAllWindows()

En menos de 100 líneas de código podemos procesar videos y detectar objetos mediante Yolov8 y ByteTrack.

Video de salida ejemplo

Conclusión

En este artículo aprendimos los problemas y puntos clave a resolver para llevar a cabo el seguimiento de objetos en el campo de la Visión Artificial. Cada año aparecen nuevos algoritmos que complementan la detección de múltiples objetos (siendo la mejor en mi opinión Yolo) permitiendo el rastreo en tiempo real y preciso de objetos. Gracias a ello, podemos realizar trazado de rutas ó comprender cuando un objeto entra en una zona determinada para “disparar las alarmas/acciones” necesarias…

Recuerda que tienes el ejercicio completo en mi repositorio de Github. Tienes la opción de ejecutar en una Jupyter Notebook o mediante un script de Python al que puedes pasar como parámetro el video mp4 que quieras probar.

Nos vemos en la próxima!

Recursos / Enlaces

Otros artículos de interés (en inglés)

The post Seguimiento de Objetos con Yolo v8 y BYTETrack – Object Tracking first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/seguimiento-de-objetos-con-yolo-v8-y-bytetrack-object-tracking/feed/ 3 8271
¿Cómo funcionan los Transformers? en Español https://www.aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/ https://www.aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/#comments Tue, 08 Nov 2022 08:54:00 +0000 https://www.aprendemachinelearning.com/?p=7771 El Machine Learning cambió para siempre con la llegada en 2017 de un paper llamado Attention is all you need en donde se presentaba una nueva arquitectura para NLP: Los Transformers

The post ¿Cómo funcionan los Transformers? en Español first appeared on Aprende Machine Learning.

]]>
Imagen creada por el Autor utilizando el modelo de text-to-img StableDiffusion

Los Transformers aparecieron como una novedosa arquitectura de Deep Learning para NLP en un paper de 2017 “Attention is all you need” que presentaba unos ingeniosos métodos para poder realizar traducción de un idioma a otro superando a las redes seq-2-seq LSTM de aquel entonces. Pero lo que no sabíamos es que este “nuevo modelo” podría ser utilizado en más campos como el de Visión Artificial, Redes Generativas, Aprendizaje por Refuerzo, Time Series y en todos ellos batir todos los records! Su impacto es tan grande que se han transformado en la nueva piedra angular del Machine Learning.

En este artículo repasaremos las piezas fundamentales que componen al Transformer y cómo una a una colaboran para conseguir tan buenos resultados. Los Transformers y su mecanismo de atención posibilitaron la aparición de los grandes modelos generadores de texto GPT2, GPT3 y BERT que ahora podían ser entrenados aprovechando el paralelismo que se alcanza mediante el uso de GPUs.

Agenda

  • ¿Qué son los transformers?
  • Arquitectura
    • General
    • Embeddings
    • Positional Encoding
    • Encoder
      • Mecanismo de Atención
      • Add & Normalisation Layer
      • Feedforward Network
    • Decoder
    • Salida del Modelo
  • Aplicaciones de los Transformers
    • BERT
    • GPT-2
    • GPT-3
  • Resumen

¿Qué son los transformers en Machine Learning?

En el paper original de 2017 “Attention is all you need” aparece el diagrama con la novedosa arquitectura del Transformer, que todos deberíamos tatuarnos en un brazo. Esta arquitectura surge como una solución a problemas de aprendizaje supervisado en Procesamiento del Lenguaje Natural, obteniendo grandes ventajas frente a los modelos utilizados en ese entonces. El transformer permitía realizar la traducción de un idioma a otro con la gran ventaja de poder entrenar al modelo en paralelo; lo que aumentaba drásticamente la velocidad y reducción del coste; y utilizando como potenciador el mecanismo de atención, que hasta ese momento no había sido explotado del todo. Veremos que en su arquitectura utiliza diversas piezas ya existentes pero que no estaban combinadas de esta manera. Además el nombre de “Todo lo que necesitas es Atención” es a la vez un tributo a los Beatles y una “bofetada” a los modelos NLP centrados en Redes Recurrentes que en ese entonces estaban intentando combinarlos con atención. De esta sutil forma les estaban diciendo… “tiren esas redes recurrentes a la basura”, porque el mecanismo de atención NO es un complemento… es EL protagonista!

All you need is Love Attention

The Beatles

Con el tiempo, esta arquitectura resultó ser flexible y se pudo utilizar para tareas más allá del NLP, además de para la generación de texto, clasificación, resumen de contenidos también pudo traspasar esa frontera y ser aplicado en Visión Artificial, Generación de Audio, Predicción de Series Temporales y Aprendizaje por Refuerzo.

La Arquitectura Encoder-Decoder del Transformer

Veamos primero la gran foto de los Transformers.

Visión General

Estás viendo el dibujo que deberías de llevar en tu próxima camiseta:

La Arquitectura de los Transformers

La primera impresión puede ser algo intimidante, pero vayamos poco a poco. Si pensamos en el modelo como una caja negra, sería simplemente:

Entrada -> Transformer -> Salida

Vemos que con una entrada de texto “Hola” obtenemos la salida “Hello”.

Si hacemos un poco de zoom en esa caja, veremos dos componentes principales: Encoders y Decoders.

La entrada pasará por una serie de Encoders que se encadenan uno tras otro y luego envían su salida a otra serie de Decoders hasta emitir la Salida final. En el paper original, se utilizan 6 encoders y 6 decoders. Notaremos un recuadro llamado “Target” donde estamos pasando el Output Deseado al modelo para entrenar; pero obviamente que no lo pasaremos al momento de la inferencia; al menos no completo (más adelante en el artículo).

Observamos ahora con mayor detalle cómo está compuesto un Encoder y un Decoder y veremos que son bastante parecidos por dentro.

En su interior tanto Encoder como decoder cuentan con un componente de Atención (o dos) y una red neuronal “normal” como salidas.

Para comenzar a evaluar con mayor detalle las partes del Transformer, primero deberemos generar un Embedding de la entrada y luego entrar al Encoder. Así que veamos eso primero.

Embeddings

El uso de embeddings existía en NLP desde antes de los Transformers, puede que estés familiarizado con modelos como el word-2-vec y puede que ya hayas visto las proyecciones creadas con miles de palabras donde los embeddings logran agrupar palabras de manera automática en un espacio multidimensional. Entonces conceptos como “hombre y mujer”, distanciado de “perro y gato” veremos nombres de países juntos y profesiones ó deportes también agrupados en ese espacio. Primero convertimos las palabras a tokens, es decir a un valor numérico asociado, porque recordemos que las redes neuronales únicamente pueden procesar números y no cadenas de texto.

Ejemplo de Word Embeddings y una proyección en 3D.

Entonces convertimos una palabra a un número, ese número a un vector de embeddings de 512 dimensiones (podría ser de otro valor, pero el propuesto en el paper fue este).

Entonces:

  1. Palabra -> Token(*)
  2. Token -> Vector n-dimensional

(*) NOTA: una palabra podría convertirse en más de un token

La parte novedosa que introduce el paper de los transformers, es el “Positional Encoding” a esos embeddings…

Positional Encoding

Una vez que tenemos los embeddings, estaremos todos de acuerdo que el orden en que pasemos las palabras al modelo, será importante. De hecho podríamos alterar totalmente el significado de una oración si mezclamos el orden de sus palabras o hasta podría carecer totalmente de significado.

La casa es verde != verde casa la es

Entonces necesitamos pasar al modelo los tokens pudiendo especificar de alguna manera su posición.

Aquí, de paso comentaremos dos novedades de los Transformers: la solución a este posicionamiento pero también esto permite el poder enviar en simultáneo TODOS los tokens al modelo, algo que anteriormente no se podía hacer, por lo que se pasaba “palabra por palabra” una después de la otra, resultando en una menor velocidad.

Para resolver el posicionamiento, se agrega una valor secuencial al embedding que se asume que la red podrá interpretar. Si aparece el token “perro” como segunda palabra ó como décima, mantendrá en esencia el mismo vector (calculado anteriormente en el embedding) pero con un ligero valor adicional que lo distinguirá y que será el que le de la pista a la red neuronal de interpretar su posición en la oración.

En el paper se propone una función sinusoidal sobre el vector de 512 dimensiones del embedding. Entonces ese vector de embeddings del token “perro” será distinto si la palabra aparece primera, segunda, tercera.

Y ahora sí, podemos dar entrada al Encoder de los Transformers.

Encoder

El Encoder está compuesto por la capa de “Self attention” y esta conectada a una red feed forward. Entre las entradas y salidas se aplica la Skip Connection (ó ResNet) y un Norm Layer.

El mecanismo de Atención, es una de las implementaciones novedosas que propone el paper. Veremos que logra procesar en paralelo, manteniendo la ventaja de entreno mediante GPU.

El Encoder tiene como objetivo procesar la secuencia de los tokens de entrada y ser a su vez la entrada del mecanismo de atención del Decoder. No olvides que realmente se encadenan varios Encoders con varios Decoders (no se utilizan sólo uno en la práctica).

El -dichoso- mecanismo de Atención

Primero que nada, ¿Para qué queremos un mecanismo de Atención? El mecanismo de atención nos ayuda a crear y dar fuerza a las relaciones entre palabras en una oración. Si tenemos el siguiente enunciado:

El perro estaba en el salón, durmiendo tranquilo.

Nosotros comprendemos fácilmente que la palabra “tranquilo” se refiere al perro y no al “salón”. Pero a la red neuronal que comienza “en blanco”, sin saber nada de las estructuras del lenguaje (español, pero podría ser cualquier idioma), y que además ve la misma frase como valores numéricos:

5 186 233 7 5 1433 567 721

NOTA: no olvides que cada token, por ej. el nº5 corresponde a un embedding de n-dimensiones de 512 valores. Por simplificar usamos el 5 como reemplazo de “El”, por no escribir sus 512 componentes.

¿Cómo podrá entender que ese último token “721” está afectando a la segunda palabra “186”?
Por eso surgen los mecanismos de atención; para lograr dar más -o menos- importancia a una palabra en relación a las otras de la oración.

La solución que presentan los Transformers en cuanto a la atención, es la construcción de un “Diccionario Blando” (Soft Dictionary). ¿Qué es esto de un diccionario blando?
En programación, es probable que conozcas el uso de diccionarios de tipo “clave-valor” un típico “hashmap” en donde ante una entrada, obtengo un valor dict[“perro”]=0.78.
Para el “diccionario de atenciones” podría ser que si pedimos la atención de “tranquilo vs perro” de la oración, nos devuelva un 1 indicando mucha atención, pero si le pedimos “tranquilo vs salón” nos devuelva un -1.

Pero… eso no es todo. Nuestro Diccionario es “Suave/Blando”, esto quiere decir que no se va a saber “de memoria” el resultado de una clave. Si alteramos un poco la oración, el diccionario tradicional fallaría:

El perro estaba durmiendo en un salón tranquilo.

Ahora la clave de atención para “tranquilo vs salón” deberá pasar de -1 a ser cercana a 1.

Para poder calcular la atención, se utilizan 3 matrices llamadas “Query-Key-Value” que van a operar siguiendo una fórmula que nos devuelve un “score” o puntaje de atención.

  • En la matriz Q de Query tendremos los tokens (su embedding) que estamos evaluando.
  • En la matriz K de Key tendremos los tokens nuevamente, como claves del diccionario.
  • En la matriz V de Value tendremos todos los tokens (su embedding) “de salida”.

El resultado de la atención será aplicar la siguiente fórmula:

Si nos olvidamos del Softmax y el “multihead” (se definirá a continuación), podemos simplificar la fórmula diciendo que:
La atención será multiplicación matricial Q por la transpuesta de K; a eso le llamamos “factor”; y ese factor multiplicado por V.

¿Y eso qué significa? ¿Por qué estamos operando de esa manera? Si recuerdas, tanto Q como K son los valores de los Embeddings, es decir, cada token es un vector n-dimensional. Al hacer el producto vectorial obtenemos matemáticamente la “Similitud” entre los vectores. Entonces si el embedding estuviera funcionando bien, la similitud entre “nieve” y “blanco” deberían estar más cercanas que “nieve” y “negro”. Entonces cuando dos palabras sean similares, tendremos un valor positivo y mayor que si son opuestos, donde obtendríamos un valor negativo (dirección contraria). Este factor se multiplica por la matriz de Valor conformando el Score final de atención para cada relación entre pares de <<palabras>> que estamos evaluando.

Como estamos trabajando con matrices, seguimos aprovechando la capacidad de calcular todo a la vez y poder hacerlo acelerado por GPU.

Más de una atención: Multi-Head Attention

…hay más en el paper, porque el tipo de atención que vamos a calcular se llama “Multi-head Attention“. ¿Qué son esas “Multi-cabezas”??? Lo que se hace es que en vez de calcular la atención de todos los tokens de la oración una vez con las 512 dimensiones (provenientes del embedding), subdividiremos esos valores en grupos y de cada uno, calcular su atención. En el paper proponen “8 heads” con lo que entonces calcularemos “8 atenciones de a 64 valores del embeddings” por cada token! Esto a mi modo de entender es algo bastante arbitrario pero por arte de “magia matemática” funciona… Luego de calcular esas 8 cabezas, (esas 8 atenciones) haremos un promedio de los valores de cada atención entre tokens.

Si volvemos al ejemplo para la clave de “tranquilo vs perro” calcularemos 8 atenciones y al promediarlas deberíamos obtener un valor cercano a 1 (para la 1er oración).

Cuando terminemos de entrenar el modelo Transformer completo, podríamos intentar analizar y entender esas matrices de atención creadas y tratar de comprenderlas. Algunos estudios muestran que la “multi-atención” logra representar relaciones como la de “artículo-sustantivo” ó “adjetivo-sustantivo”, “verbo sustantivo” lo cual me sigue pareciendo algo increíble.

3 tipos de atención: Propia, Cruzada y Enmascarada

Prometo que esto ya es lo último que nos queda comprender sobre los mecanismos de atención… A todo lo anterior, hay que sumar que tenemos 3 tipos distintos de atención

  1. Self Attention
  2. Cross Attention
  3. Masked Attention

Su comportamiento es igual que al descripto anteriormente pero con alguna particularidad:

Self Attention se refiere que crearemos los valores y las matrices de Q-K-V a partir de las propias entradas de los tokens de entrada.

En la Atención Cruzada, vemos cómo utilizamos como entradas en el Decoder los valores obtenidos en el Encoder. Esto es lo que hará que con sólo el valor (Value) del Output pueda modelar la salida de atención buscada, esto es importante porque al final es lo que condicionará mayormente la “traducción” que está haciendo internamente el Decoder!

Y la llamada “Masked attention” se refiere a que enmascaramos parte triangular superior de la matriz de atención al calcularla para no caer en “data-leakage”, es decir, para no “adelantar información futura” que el Output no podría tener en su momento. Esto puede resultar confuso, intentaré aclararlo un poco más. En el Encoder, cuando tenemos los valores de entrada y hacemos “self-attention” dijimos que calculamos la atención de “todos contra todos” porque todos los tokens de entrada son conocidos desde el principio. Si recordamos la frase anterior:

El perro estaba en el salón, durmiendo tranquilo.

Aquí podemos calcular tanto la atención para la clave “perro-tranquilo” y también la de “tranquilo-perro”

Sin embargo -si suponemos que estamos traduciendo al inglés- en el output tendremos

“The dog was in the living room, sleeping peacefully”

PERO hay un detalle; para poder generar el output al momento de la inferencia, generaremos de a una palabra por vez, entonces iremos produciendo el siguiente output:

T1 – The
T2 – The dog
T3 – The dog was
T4 – The dog was in …

Esto quiere decir que vamos generando los tokens de a uno a la vez por lo que al principio no podríamos conocer la relación entre “dog-peacefully” pues esta relación aún no existe!

Entonces diferenciemos esto:

-> Al momento de entrenar el modelo pasamos el output deseado COMPLETO a las matrices de QKV de “Masked Attention” para entrenar en paralelo; al estar enmascarado, es como si estuviésemos simulando la secuencia “The, The dog, The dog was…”

-> Al momento de inferencia REALMENTE tendremos uno a uno los tokens como una secuencia temporal, realmente, iremos agregando de a una palabra del output a la cadena de salida a la vez.

Al enmascarar la matriz Q*K en su diagonal superior, prevenimos obtener valores “futuros” en la relación de atención entre sus tokens.

Short residual skip Connections y Layer Normalization

Al utilizar Skip Connections permitimos mantener el valor de origen del input a través de las deep neural networks evitando que sus pesos se desvanezcan con el paso del tiempo. Esta técnica fue utilizada en las famosas ResNets para clasificación de imágenes y se convirtieron en bloques de construcción para redes profundas. También es sumamente importante la Normalización en RRNN. Previene que el rango de valores entre capas cambie “demasiado bruscamente” logrando hacer que el modelo entrene más rápido y con mayor capacidad de generalización.

Feed Forward Network

La salida final del Encoder la dará una Red Neuronal “normal”, también llamada MLP ó capa densa. Se agregarán dos capas con Dropout y una función de activación no lineal.

Decoder

Ahora que conocemos los componentes del Encoder, podemos ver que con esos mismos bloques podemos crear el Decoder.

Al momento de entrenar, estaremos pasando el Input “hola amigos” y Output “hello friends” (su traducción) al mismo tiempo al modelo.

Tradicionalmente, usamos la salida únicamente para “validar” el modelo y ajustar los pesos de la red neuronal (durante el backpropagation). Sin embargo en el Transformer estamos usando la salida “hello friends” como parte del aprendizaje que realiza el modelo.

Entonces, el output “hello friends” es también la “entrada” del decoder hacia embeddings, posicionamiento y finalmente ingreso a la Masked Self Attention que comentamos antes (para los valores de Q,K,V).

De aquí, y pasando por la Skip Connection y Normalización (en la gráfica “Add & Norm) entramos al segundo mecanismo de Atención Cruzada que contiene para las matrices Query y Key” la salida del Encoder y como Value la salida de la Masked Attention.

Nuevamente Suma y Normalización, entrada a la Feed Forward del Decoder.

RECORDAR: “N encoder y N decoders”

No olvidemos que si bien estamos viendo en mayor detalle “un encoder” y “un decoder”, la arquitectura completa del Transformer implica la creación de (en el paper original) 6 encoders encadenados que enlazan con otros 6 decoders.

Salida final del Modelo

La salida final del modelo pasa por una última capa Lineal y aplicar Softmax. El Softmax, por si no lo recuerdas nos dará un valor de entre 0 y 1 para cada una de las posibles palabras (tokens) de salida. Entonces si nuestro “lenguaje” total es de 50.000 posibles tokens (incluyendo signos de puntuación, admiración, interrogación), encontraremos a uno de ellos con valor más alto, que será la predicción.

Si yo te dijera “en casa de herrero cuchillo de …” y vos tuvieras que predecir la próxima palabra, de entre todas las posibles en el castellano seguramente elegirías “palo” con probabilidad 0,999. Ahí acabas de aplicar Softmax intuitivamente en tu cabeza, y descartaste al resto de 49.999 palabras restantes.

Repaso de la arquitectura

Repasemos los puntos fuertes de la arquitectura de los Transformers:

  • La arquitectura de Transformers utiliza Encoders y Decoders
  • El Transformer permite entrenar en paralelo y aprovechar el GPU
  • Utiliza un mecanismo de atención que cruza en memoria “todos contra todos los tokens” y obtiene un score. Los modelos anteriores como LSTM no podían memorizar textos largos ni correr en paralelo.
  • El mecanismo de atención puede ser de Self Attention en el Encoder, Cross Attention ó Masked Attention en el Decoder. Su funcionamiento es igual en todos los casos, pero cambian los vectores que utilizamos como entradas para Q,K,V.
  • Se utiliza El Input pero también la Salida (el Output del dataset) para entrenar al modelo.

Aplicaciones de los Transformers

Los Transformers se convirtieron en el modelo “de facto” para todo tipo de tareas de NLP, incluyendo Traducción de idiomas (como vimos), clasificación de texto, resumen de textos y Question-Answering. Sólo basta con modificar los datasets que utilizamos para entrenar al modelo y la “salida final del modelo”, manteniendo al resto de arquitectura.

A raíz de poder entrenar mediante GPU, reducción de tiempo y dinero, surgieron varios modelos para NLP que fueron entrenados con datasets cada vez más grandes, con la creencia de que cuantas más palabras, más acertado sería el modelo, llevándolos al límite. Ahora, parece que hemos alcanzado un tope de acuracy, en el cual no vale la pena seguir extendiendo el vocabulario.

Vemos 3 de estos grandes modelos de NLP y sus características

BERT – 2018

BERT (Bidirectional Encoder Representations from Transformers) aparece en 2018, desarrollado por Google y utiliza sólo la parte del Encoder de los Transformers. Este modelo fue entrenado con todos los artículos de la Wikipedia en Inglés que contiene más de 2500 millones de palabras. Esto permitió generar un modelo “pro-entrenado” en inglés muy poderoso que podía ser utilizado para múltiples tareas de NLP. Además, al ser Open Source, permitió la colaboración y extensión por parte de la comunidad científica. El poder utilizar un modelo pre-entrenado tan grande, preciso y potente, permite justamente “reutilizar” ese conocimiento sin necesidad de tener que entrenar nuevamente un modelo de NLP, con el coste y tiempo (e impacto medioambiental) que puede conllevar.

Además BERT contenía algunas novedades, por ejemplo, en vez de utilizar un “Embeddings único y estático”, implementó un mecanismo en donde la misma palabra (token) podría devolver un vector distinto (de “embeddings”) de acuerdo al contexto de la oración de esa palabra.

Cuando salió BERT, batió muchos de los records existentes en datasets como SQuAD, GLUE y MultiNLI.

GPT-2 – 2019

GPT es un modelo de generación de texto creado por Open AI en 2019 y que contiene 1500 millones de parámetros en la configuración de su red neuronal profunda.

Al ser entrenado para generar “siguiente palabra”, pasa a convertirse en un problema de tipo “no supervisado”. Su re-entreno fue realizado usando BooksCorpus, un dataset que contiene más de 7,000 libros de ficción no publicados de diversos géneros.

Este modelo generó polémica en su momento debido a que empezaba a crear textos similares a lo que podía escribir una persona, con lo cual antes de ser lanzado, se temió por su mal uso para generar contenido falso en internet. Había sido anunciado en febrero y recién fue accesible al público, de manera parcial en Agosto. Los modelos de tipo GPT utilizan únicamente la parte de “Decoder” del Transformer.

Ejercicio Práctico: Crea tu propio chatbot con GPT-2 en Español!

GPT-3 – 2020

Lanzado en 2020, la red de GPT-3 tiene 175.000 millones de parámetros. Entrenado con textos de internet que contienen más de 500.000 millones de tokens.

En GPT-3, la generación de textos por la IA puede alcanzar un nivel literario que pasa inadvertido por los humanos, el modelo es capaz de mantener la coherencia en textos largos y debido a su gran conocimiento del mundo, crear un contexto y párrafos muy reales.

Otra de las novedades que trajo GPT3 es que lograba realizar tareas “inesperadas” de manera correcta, sin haber sido entrenado para ello. Por ejemplo, puede realizar Question-Answer, crear diálogos ó hasta escribir código en Python, Java o traducir idiomas. A este tipo de aprendizaje “no buscado” le llamamos “One Shot Learning”.

El Codigo de GPT-3 aún no ha sido liberado, hasta la fecha.

Más allá del NLP

Al comportarse tan bien para tareas de NLP, se comenzó a utilizar esta arquitectura adaptada para Clasificación de imágenes en Computer Vision y también logró superar en muchos casos a las Redes Convolucionales! A este nuevo modelo se le conoce como Vision Transformer o “Vit”.

También podemos utilizar Transformers para pronóstico de Series Temporales (Time Series). Este caso de uso tiene mucha lógica si lo pensamos, porque al final es muy parecido a “predecir la próxima palabra”, pero en su lugar “predecir la próxima venta”, ó stock…

Los Transformers están siendo utilizados en modelos generativos de música o como parte de los modelos de difusión text-to-image como Dall-E2 y Stable Diffusion.

Por último, los Transformers también están siendo utilizados en Aprendizaje por Refuerzo, donde también tienen sentido, pues la fórmula principal de este tipo de problemas también contiene una variable temporal/secuencial.

Y en todos estos campos, recién está empezando la revolución! No digo que será el Transformer quien reemplace al resto de Arquitecturas y modelos de Machine Learning existentes, pero está siendo un buen motivo para cuestionarlos, replantearlos y mejorar!

Resumen

Los Transformers aparecieron en un paper de 2017 implementando un eficiente mecanismo de atención como punto clave para resolver problemas de traducción en el campo del Procesamiento del Lenguaje Natural. Como bien sabemos, el lenguaje escrito conlleva implícitamente un orden temporal, secuencial que hasta aquel entonces era una de las barreras para no poder crear modelos extensos, pues impedía el aprovechamiento de GPU. La nueva arquitectura rompía esa barrera utilizando unos sencillos trucos: utilizar todos los token al mismo tiempo (en vez de uno en uno) y enmascarar la multiplicación matricial para impedir el data leakage en el caso del decoder.

Además, resolvió el Posicionamiento de los token y aprovechó técnicas ya existentes como el uso de Skip Connections y Normalization Layers.

Todo ello posibilitó la creación de los grandes modelos actuales, BERT, GPT y la aparición de muchísimos modelos disponibles “pre-entrenados” que pueden ser descargados y reutilizados para fine-tuning por cualquier persona.

Como si esto fuera poco, los Transformers tienen la flexibilidad suficiente para traspasar el área de NLP y contribuir al resto de áreas del Machine Learning obteniendo resultados impresionantes.

Habrá que agradecer a Ashish VaswaniNoam ShazeerNiki ParmarJakob UszkoreitLlion JonesAidan N. GomezLukasz KaiserIllia Polosukhin por su obra maestra.

Material Extra

Enlaces a más info sobre Transformers!

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

El libro del Blog

Si te gustan los contenidos del blog y quieres darme tu apoyo, puedes comprar el libro en papel, ó en digital (también lo puede descargar gratis!).

The post ¿Cómo funcionan los Transformers? en Español first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/feed/ 1 7771
Crea imágenes increíbles con Inteligencia Artificial en tu ordenador https://www.aprendemachinelearning.com/crea-imagenes-stable-diffusion-con-inteligencia-artificial-en-tu-ordenador/ https://www.aprendemachinelearning.com/crea-imagenes-stable-diffusion-con-inteligencia-artificial-en-tu-ordenador/#respond Thu, 06 Oct 2022 08:00:00 +0000 https://www.aprendemachinelearning.com/?p=7681 El modelo de Machine Learning llamado Stable Diffusion es Open Source y permite generar cualquier imagen a partir de un texto, por más loca que sea, desde el sofá de tu casa! Estamos viviendo unos días realmente emocionantes en el campo de la inteligencia artificial,...

The post Crea imágenes increíbles con Inteligencia Artificial en tu ordenador first appeared on Aprende Machine Learning.

]]>
El modelo de Machine Learning llamado Stable Diffusion es Open Source y permite generar cualquier imagen a partir de un texto, por más loca que sea, desde el sofá de tu casa!

Estamos viviendo unos días realmente emocionantes en el campo de la inteligencia artificial, en apenas meses, hemos pasado de tener modelos enormes y de pago en manos de unas pocas corporaciones a poder desplegar un modelo en tu propio ordenador y lograr los mismos -increíbles- resultados de manera gratuita. Es decir, ahora mismo, está al alcance de prácticamente cualquier persona la capacidad de utilizar esta potentísima herramienta y crear imágenes en segundos (ó minutos) y a coste cero.

En este artículo les comentaré qué es Stable Diffusion y por qué es un hito en la historia de la Inteligencia Artificial, veremos cómo funciona y tienes la oportunidad de probarlo en la nube o de instalarlo en tu propio ordenador sea Windows, Linux ó Mac, con o sin placa GPU.

Reseña de los acontecimientos

  • 2015: Paper que propone los Diffusion Models.
  • 2018 -2019 Text to Image Synthesis – usando GANS se generan imágenes de 64×64 pixels, utiliza muchos recursos y baja calidad de resultados.
  • Enero 2021: Open AI anuncia Dall-E, genera imágenes interesantes, pequeñas, baja resolución, lentas.
  • Febrero 2021: CLIP de Open AI (Contrastive Language-Image Pretraining), un codificador dual de lenguaje-imagen muy potente.
  • Julio 2021: Image Text Contrastive Learning Mejora sobre las Gans “image-text-label” space.
  • Marzo 2022: GLIDE: esta red es una mejora sobre Dall-E, tambien de openAI pero usando DIFFUSION model.
  • Abril 2022: Dall-E 2 de Open AI, un modelo muy bueno de generación de imágenes. Código cerrado, acceso por pedido y de pago.
  • Mayo 2022: Imagen de Google.
  • Agosto de 2022: Lanzamiento de Stable Diffusion 1.4 de Stability AI al público. Open Source, de bajos recursos, para poder ejecutar en cualquier ordenador.

¿Qué es Stable Diffusion?

Stable Diffusion es el nombre de un nuevo modelo de Machine Learning de Texto-a-Imagen creado por Stability Ai, Comp Vis y LAION. Entrenado con +5 mil millones de imágenes del dataset Laion-5B en tamaño 512 por 512 pixeles. Su código fue liberado al público el 22 de Agosto de 2022 y en un archivo de 4GB con los pesos entrenados de una red neuronal que podemos descargar desde HuggingFace, tienes el poder de crear imágenes muy diversas a partir de una entrada de texto.

Stable Diffusion es también una gran revolución en nuestra sociedad porque trae consigo diversas polémicas; al ofrecer esta herramienta a un amplio público, permite generar imágenes de fantasía de paisajes, personas, productos… ¿cómo afecta esto a los derechos de autor? Qué pasa con las imágenes inadecuadas u ofensivas? Qué pasa con el sesgo de género? Puede suplantar a un diseñador gráfico? Hay un abanico enorme de incógnitas sobre cómo será utilizada esta herramienta y la disrupción que supone. A mí personalmente me impresiona por el progreso tecnológico, por lo potente que es, los magnificos resultados que puede alcanzar y todo lo positivo que puede acarrear.

¿Por qué tanto revuelo? ¿Es como una gran Base de datos de imágenes? – ¡No!

Es cierto que fue entrenada con más de 5 mil millones de imágenes. Entonces podemos pensar: “Si el modelo vio 100.000 imágenes de caballos, aprenderá a dibujar caballos. Si vio 100.000 imágenes de la luna, sabrá pintar la luna. Y si aprendió de miles de imágenes de astronautas, sabrá pintar astronautas“. Pero si le pedimos que pinte “un astronauta a caballo en la luna” ¿qué pasa? La respuesta es que el modelo que jamás había visto una imagen así, es capaz de generar cientos de variantes de imágenes que cumplen con lo solicitado… esto ya empieza a ser increíble. Podemos pensar: “Bueno, estará haciendo un collage, usando un caballo que ya vio, un astronauta (que ya vió) y la luna y hacer una composición“. Y no; no es eso lo que hace, ahí se vuelve interesante: el modelo de ML parte de un “lienzo en blanco” (en realidad es una imagen llena de ruido) y a partir de ellos empieza a generar la imagen, iterando y refinando su objetivo, pero trabajando a nivel de pixel (por lo cual no está haciendo copy-paste). Si creyéramos que es una gran base de datos, les aseguro que no caben las 5.500.000.000 de imágenes en 4 Gygabytes -que son los pesos del modelo de la red- pues estaría almacenando cada imagen (de 512x512px) en menos de 1 Byte, algo imposible.

¿Cómo funciona Stable Diffusion?

Veamos cómo funciona Stable Diffusion!

Stable Diffusion está basado en otro modelo llamado “Latent Diffusion” que proviene de modelos de difusión de ML que están entrenados para “eliminar el ruido de “imágenes sucias” paso a paso”. Esto quiere decir que al modelo le entrenamos con fotos donde ensuciamos ciertos pixeles, con manchas, desenfoque (blur) o distorsiones que agregamos a propósito y le pedimos como salida la imagen correcta (la imagen original sin ruido). Entonces, la red neuronal del modelo aprende a “quitar el ruido”, es decir, transformar esas manchas (ruido) en la imagen original.

Los modelos de difusión lograron resultados muy buenos como generadores de imágenes aunque su contra es que como trabajan a nivel de pixel requieren de mucha memoria RAM y toman tiempo para crear imágenes de alta definición.

La mejora introducida por los modelos “Latent Diffusion” es que el modelo es entrenado para generar “representaciones de imágenes latentes” (comprimidas). Sus tres componente principales son:

  1. Autoencoder (VAE)
  2. U-Net
  3. Text-Encoder

1-Autoencoder (VAE)

El modelo VAE tiene dos partes, un codificador y un decodificador. En codificador es usado para convertir la imagen en una representación latente de baja dimensión, que servirá como entrada a la “U-Net”. El decodificador por el contrario, transforma la representación latente nuevamente en una imagen.

Durante el entrenamiento de difusión latente, se usa el codificador para obtener las representaciones latentes de las imágenes para el proceso de difusión directa, se aplica más y más ruido en cada paso. Durante la inferencia, se realiza el proceso inverso de difusión donde “expande los latentes” para convertirlos nuevamente en imágenes con el decodificador VAE. Para la inferencia sólo necesitamos el decodificador.

Ejemplo de arquitectura de una red Autoencoder VAE del artículo “VAE

2-U-Net

La U-Net tiene una mitad de camino “de contracción” y otra mitad de “expansión“, ambos compuestos por bloques ResNet (para soportar redes profundas sin desvanecer el aprendizaje). La primera mitad de la U-Net reduce la imagen a una representación de baja resolución (similar a un encoder) y la segunda parte intentará generar la imagen original en alta resolución (similar a un decoder). La salida de la U-Net predice el “ruido residual” que puede ser usado para calcular la representación “sin ruido” de la imagen.

Para prevenir que la U-Net pierda información importante durante el downsampling, se agregan conexiones de “atajo corto” (skip connections) entre los dos caminos: encoder y decoder. Además la U-Net de stable diffusion puede condicionar su salida respecto de los text-embeddings de las capas de cross-attention. Las capas de “Atención Cruzada” se agregan tanto en las partes de codificación y decodificación de la U-Net, entre los bloques ResNet. A eso se le llama Difusión guiada ó Difusión condicionada.

Ejemplo de Arquitectura de una U-Net, se llama así por su forma de “U”.

3-Text-Encoder

El Text-Encoder es el responsable de transformar el mensaje de entrada por ejemplo “Ilustración de Taylor Swift con un pingüino bailando en la ciudad” en un espacio de embeddings que puede ser comprendido por la U-Net. Se utiliza un encoder de tipo Transformers que mapea la secuencia de palabras de entrada en una secuencia latente del embedding de textos.

Stable Diffusion no entrena al Text-Encoder durante la etapa de entrenamiento del modelo si no que utiliza un encoder ya entrenado de CLIP.

Ejemplo de arquitectura de Clip, un modelo text-encoder
Ilustración de Taylor Swift con un Pingüino bailando en la ciudad, creada por el Autor.

Resumen de la arquitectura de Stable Difussion

El modelo al completo, como lo muestra la web oficial de Stable Diffusion es así:

Gráfica de arquitectura de Stable Diffusion. Fuente: web oficial de Stable Diffusion

Al momento de entrenar, la red tiene como entrada una imagen y un texto asociado. La red convertirá la imagen “en ruido” por completo y luego la intentará reconstruir. No olvidemos que es un problema de Aprendizaje supervisado, por lo cual, contamos con el dataset completo, con F(x)=Y desde el inicio.

  1. A la izquierda, en rojo “Pixel Space” tenemos la “x” inicial que entrará en el Encoder de la VAE.
  2. En verde, Espacio Latente, Arriba el Proceso de Difusión, lleva “z” a “zT” agregando ruido a la imagen
  3. En verde, Espacio Latente, Abajo, de derecha a izquierda, entra “zT” a la U-Net e intentará reconvertirla en “z”.
  4. Conditioning, a la derecha, utiliza el modelo CLIP con el texto asociado a la imagen y dirige la salida de la U-Net.
  5. Por último, luego de iterar varias veces la U-Net y obtener una “z buena” (que es la imagen en estado latente), la decodificamos a pixeles utilizando el Decoder de la VAE (en el Pixel Space) y obtendremos una imagen similar a la “x” inicial.

Esta es la arquitectura para entrenar al modelo. Si vas a utilizar la red una vez entrenada, realmente realizaremos el “camino de inferencia“, veamos:

Al hacer la Inferencia, creamos una imagen:

Al momento de hacer la inferencia crearemos una imágen desde ruido! Por eso, el primer paso, es crear una imagen de 512×512 completamente de pixeles aleatorios!

Veamos la gráfica de inferencia que nos propone Stability.ai

Flujo de Inferencia explicada en HuggingFace sobre Stable Diffusion

Entonces, generamos la imagen de ruido y a partir de ella, la pasaremos a la U-Net que junto con el texto de entrada irá condicionando la salida, una y otra vez, intentará “quitar el ruido” para volver a una imagen original inexistente…

¿Te das cuenta? estamos engañando a la red neuronal, para que genere un gráfico que nunca antes existió…

La pobre Red Neuronal, es como si fuera un escultor con un cincel al que le damos un bloque de piedra enorme y le decimos “Quiero a Taylor Swift con un pingüino, hazlo!“.

Entonces, en cada iteración, creará desde el ruido, una imagen

Partimos de una imagen aleatoria completamente con ruido y tras 25 iteraciones la red de Stable Diffusion será capaz de generar una bonita ilustración.

Pero… ¿Qué imágenes puedes crear con Stable Diffusion?

Veamos algunos ejemplos de imágenes creadas por Stable Diffusion para ver si te convenzo de que esto es realmente algo grande… y luego ya puedes decidir si quieres probarlo y hasta instalarlo en tu propio equipo.

Aquí algunas imágenes encontradas en diversos canales:

En Lexica, que por cierto, te recomiendo visitar su web, pues tiene imágenes junto a los prompts para generarlas.

En Instagram

Imágenes encontradas en Reddit

Imágenes encontradas en Twitter

¡Quiero usar Stable Diffusion! ¿Cómo hago?

Puedes pagar por el servicio, ejecutar en la nube ó instalarlo en tu propia computadora.

1-Probarlo gratis, lo primero! (pagar luego…)

Desde la web de los creadores puedes dar tus primeros pasos. Tienes que registrarte y obtienes unos créditos gratuitos, luego que se acaben, tendrás que pagar. Debes entrar en https://beta.dreamstudio.ai/dream

Página de Bienvenida al Dream Studio de Stable Diffusion

Veremos en la parte de abajo, centro la caja de texto donde podemos ingresar el “prompt” con lo que queremos dibujar. Sobre la derecha los parámetros de configuración, que comentaremos luego, pero lo básico es que puedes elegir el tamaño de imagen y cantidad de imágenes a generar.

Ten en cuenta que tienes unos créditos (gratuitos) limitados para utilizar, por lo que debes estar atento a lo que vas consumiendo.

2-Instalar StableDiffusion en tu Computadora

Podemos instalar Stable Difussion en Windows y en Linux con “Instaladores automáticos” siguiendo las instrucciones del repositorio de Automatic1111. Para Windows hay otro instalador aqui .

Puedes instalar en ordenadores Mac (y aprovechar las GPUS de los chips M1 y M2) desde el repositorio de InvokeAI siguiendo las instrucciones para Macintosh.

Si te atreves a instalarlo de manera un poco más “manual”, puedes aventurarte a seguir las instrucciones del Repositorio Oficial de Stable Diffusion. No es difícil, básicamente, si tienes instalado Anaconda en tu ordenador, es clonar el repo y crear el environment de python siguiendo los pasos.

Un paso Clave: descargar el modelo de la red de HuggingFace

Casi todos los modos de instalar que vimos anteriormente, necesitan de un paso manual que es el de obtener y descargar el modelo desde la web de HuggingFace que ocupa 4.27 Gygabytes. Para ello, debes registrarte en HuggingFace e ir a la página del modelo. Deberás aceptar las condiciones de uso, y luego podrás descargar el último modelo, al momento de escribir este artículo es el archivo sd-v1-4.ckpt. Una vez descargado, lo deberás copiar en la carpeta models/ldm/stable-diffusion-1/ y renombrar el archivo como model.ckpt.

Eso es todo! Voilá, crea todas las imágenes que quieras! Tienes el mundo en tus manos!

Tiempos de “Rendering”

Si tienes una tarjeta gráfica con GPU, en mi caso la Nvidia RTX3080 tarda 5 segundos en crear una imágen de 512x512px. Si no tienes tarjeta puedes crear imágenes usando CPU pero tardarán unos 6 minutos (en un ordenador del año 2015 Core i5 y 8GB de memoria). En ordenadores Macbook con chip M2 tarda aproximadamente 1 minuto por imagen.

3-Usar StableDiffusion gratis y con GPU desde la nube de Google Colab

Otra opción para utilizar este genial modelo de forma gratuita es utilizar las notebooks de Google Colab y activar la opción de GPU. Existen varias notebooks compartidas que puedes utilizar como template con la instalación, aquí te recomiendo esta notebook y un hilo en Twitter en español, que te ayuda a seguir los pasos.

¿Cómo Funcionan los Transformers?

Entendiendo los parámetros de entrada de Stable Diffusion

Tanto en la versión web, la de instaladores, manual ó en la nube; contaremos con los mismos parámetros para configurar la red neuronal. Estos son:

  • Alto y Ancho de imagen: deben ser múltiplos de 64, tamaño mínimo de 256 y máximo de 1024px. Sin embargo la recomendación es utilizar 512×512 pues es el tamaño con el que se entrenó la red.
  • Steps: es la cantidad de iteraciones que realizará la U-Net durante la inferencia. Cuanto más iteramos, mayor “ruido” quitaremos de la imagen, es decir, quedará mejor definida. Pero también tardará más tiempo. Teniendo en cuenta el sampler que utilicemos, un valor de entre 25 y 50 estará bien.
  • CFG Scale: este es un valor curioso, pues determina el “grado de libertad” que damos a la propia red para ser creativa. El valor por defecto es 7.5. Si disminuimos el valor, se centrará más en nuestro Prompt. Si aumentamos el valor (más de 10) empezará a improvisar y a hacer dibujos más delirantes y más a su antojo.
  • Número de Imágenes: la cantidad de diversas imágenes que se crearán durante la inferencia. Cuantas más creamos más memoria RAM necesitaremos, tener en cuenta.
  • Sampler: será la función con la que se creará el “denoising” en la U-Net y tiene implicancias en la imagen que se generará. El Sampler más avanzado (de momento) es el DPM2 y necesita más steps para lograr buenos resultados, llevando más tiempo. Curiosamente, el sampler llamado Euler Ancestral es el más básico y logra muy buenas imágenes en unas 20 iteraciones (menor tiempo).
  • Seed ó Semilla: La semilla está relacionada con la imagen con ruido que generamos inicialmente desde donde la red empezará a dibujar. Con una misma semilla podremos replicar una imagen todas la veces que queramos para un mismo prompt. Si no asignamos un valor de semilla, se generará aleatoriamente, obteniendo siempre imágenes distintas para el mismo prompt.

El Prompt Engineering

Se le llama Prompt Engineering al arte de introducir textos que generen buenas imágenes. Lo cierto es que no es tan fácil como parece la creación de imágenes, es decir, la red siempre creará imágenes, pero para que destaquen realmente, hay que agregar las keywords adecuadas. Por suerte ya hay personas que descubrieron muchos de esos tweaks

Los truquillos en el Prompt

Varios exploradores recomiendan seguir una fórmula de tipo:

Tipo imagen – objeto – lugar – tiempo – estilo ó autor

Por ejemplo:

Pintura de un gato con gafas en un teatro, 1960, por Velazquez

Y esto mismo… pero en inglés, obtenemos:

Oil paint of a cat wearing glasses in a theatre, 1960, by Velazquez

Hay algunas palabras que se agregan al final, que son muy útiles, poner “trending on ArtStation”, “highly detailed”, “unreal engine 5”.

Aqui te dejo un enlace a un artículo maravilloso que muestra con ejemplo de muchas de las combinaciones.

imágenes generadas con Imágenes: “img2Img”

Además del txt2Img (que a partir de un texto, generemos una imagen), tenemos otra opción llamada img2img.

Con esta opción ingresamos una imagen creada por nosotros con el “paintbrush” u otra herramienta similar y la utilizaremos como imagen de inicio para generar una nueva imagen. Esto tiene mucha lógica si lo piensas, en vez de empezar con una imagen llena de ruido, le damos unas “guías” a la red neuronal para que pueda crear la imagen. Y los resultados son increíbles!

Imagen de partida para img2img
Imagen obtenida con Img2Img

Por si fuera poco, Inpainting y Outpainting

El Inpainting permite crear una máscara dentro de una imagen y que el modelo dibuje dentro, manteniendo el estilo pictórico y la coherencia.

También existe el llamado OutPainting, que nos permite “extender” una imagen, logrando obras increíbles, será mejor que lo veas!

Resumen y Conclusiones

A estas alturas, espero que estes tan emocionado como yo con esta nueva tecnología y esto es sólo el comienzo! Los modelos de Machine Learning de texto-a-imagen acaban de aterrizar y se perfeccionarán; uno de los puntos fuertes y gran acierto de Stable Diffusion es que al lanzarse a todo el público, logró captar a una gran comunidad de desarrolladores, artistas y curiosos que colaboran y que potencian sus capacidades aún más! Al momento de escribir el artículo, han pasado menos de 2 meses y aparecieron muchísimos proyectos relacionados. Además se comenta que está por aparecer la nueva versión del modelo de pesos entrenado 1.5 dentro de poco. Algunos usuarios hasta crearon videos mediante Stable Diffusion y otros empiezan a mezclar la red con las 3 dimensiones para crear objetos.

En próximos artículos veremos en mayor profundidad y en código Python el uso de redes VAE, U-Net y Transformers.

Hasta pronto!

Material Adicional:

Aquí comparto dos videos muy buenos sobre Arte con IA y otro sobre Stable Diffusion

Otros artículos relacionados de interés:

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

El libro del Blog

Si te gustan los contenidos del blog y quieres darme una mano, puedes comprar el libro en papel, ó en digital.

The post Crea imágenes increíbles con Inteligencia Artificial en tu ordenador first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/crea-imagenes-stable-diffusion-con-inteligencia-artificial-en-tu-ordenador/feed/ 0 7681
Aprendizaje por Refuerzo https://www.aprendemachinelearning.com/aprendizaje-por-refuerzo/ https://www.aprendemachinelearning.com/aprendizaje-por-refuerzo/#comments Thu, 24 Dec 2020 08:00:00 +0000 https://www.aprendemachinelearning.com/?p=5911 En este artículo aprenderemos qué es el aprendizaje por refuerzo, lo más novedoso y ambicioso a día de hoy en Inteligencia artificial, veremos cómo funciona, sus casos de uso y haremos un ejercicio práctico completo en Python: una máquina que aprenderá a jugar al pong...

The post Aprendizaje por Refuerzo first appeared on Aprende Machine Learning.

]]>

En este artículo aprenderemos qué es el aprendizaje por refuerzo, lo más novedoso y ambicioso a día de hoy en Inteligencia artificial, veremos cómo funciona, sus casos de uso y haremos un ejercicio práctico completo en Python: una máquina que aprenderá a jugar al pong sóla, sin conocer las reglas ni al entorno.

Nuestra Agenda

Los temas que veremos incluyen:

  • ¿Qué es el Reinforcement Learning?
    • Diferencias con los clásicos
    • Componentes
  • Casos de Uso
    • Y los videojuegos?
  • Cómo funciona el RL?
    • premios y castigos
    • fuerza bruta
  • Q-Learning
    • Ecuación de Bellman
    • Explorar vs Explotar
  • El juego del Pong en Python
    • Clase Agente
    • Clase Environment
    • El juego
    • La tabla de Políticas
  • Conclusiones
    • Recursos Adicionales

Comencemos!!

¿Qué es el Aprendizaje por Refuerzo?

Seguramente ya conocerás las 2 grandes áreas de aprendizaje tradicional del Machine Learning, el aprendizaje supervisado y el aprendizaje no supervisado. Parece difícil que aquí hubiera espacio para otras opciones; sin embargo sí la hay y es el Aprendizaje por refuerzo. En aprendizaje por refuerzo (ó Reinforcement Learning en inglés) no tenemos una “etiqueta de salida”, por lo que no es de tipo supervisado y si bien estos algoritmos aprenden por sí mismos, tampoco son de tipo no supervisado, en donde se intenta clasificar grupos teniendo en cuenta alguna distancia entre muestras.

Si nos ponemos a pensar, los problemas de ML supervisados y no supervisados son específicos de un caso de negocio en particular, sea de clasificación ó predicción, están muy delimitados, por ejemplo, clasificar “perros ó gatos“, ó agrupar “k=5” clusters. En contraste, en el mundo real contamos con múltiples variables que por lo general se interrelacionan y que dependen de otros casos de negocio y dan lugar a escenarios más grandes en donde tomar decisiones. Para conducir un coche no basta una inteligencia que pueda detectar un semáforo en rojo, verde ó amarillo; tendremos muchísimos factores -todos a la vez- a los que prestar atención: a qué velocidad vamos, estamos ante una curva?, hay peatones?, es de noche y debemos encender las luces?.

Una solución sería tener múltiples máquinas de ML supervisadas y que interactúan entre si -y esto no estaría mal- ó podemos cambiar el enfoque… Y ahí aparece el Reinforcement Learning (RL) como una alternativa, tal vez de las más ambiciosas en las que se intenta integrar el Machine Learning en el mundo real, sobre todo aplicado a robots y maquinaria industrial.

El Reinforcement Learning entonces, intentará hacer aprender a la máquina basándose en un esquema de “premios y castigos” -cómo con el perro de Pablov- en un entorno en donde hay que tomar acciones y que está afectado por múltiples variables que cambian con el tiempo.

Diferencias con “los clásicos”

En los modelos de Aprendizaje Supervisado (o no supervisado) como redes neuronales, árboles, knn, etc, se intenta “minimizar la función coste”, reducir el error.

En cambio en el RL se intenta “maximizar la recompensa“. Y esto puede ser, a pesar de a veces cometer errores ó de no ser óptimos.

Componentes del RL

El Reinforcement Learning propone un nuevo enfoque para hacer que nuestra máquina aprenda, para ello, postula los siguientes 2 componentes:

  • el Agente: será nuestro modelo que queremos entrenar y que aprenda a tomar decisiones.
  • Ambiente: será el entorno en donde interactúa y “se mueve” el agente. El ambiente contiene las limitaciones y reglas posibles a cada momento.

Entre ellos hay una relación que se retroalimenta y cuenta con los siguientes nexos:

  • Acción: las posibles acciones que puede tomar en un momento determinado el Agente.
  • Estado (del ambiente): son los indicadores del ambiente de cómo están los diversos elementos que lo componen en ese momento.
  • Recompensas (ó castigos!): a raíz de cada acción tomada por el Agente, podremos obtener un premio ó una penalización que orientarán al Agente en si lo está haciendo bien ó mal.

Entonces, la “foto final” nos queda así:

En un primer momento, el agente recibe un estado inicial y toma una acción con lo cual influye é interviene en el ambiente. Esto está muy bien, pues es muy cierto que cuando tomamos decisiones en el mundo real lo estamos modificando, ¿no?. Y esa decisión tendrá sus consecuencias: en la siguiente iteración el ambiente devolverá al agente el nuevo estado y la recompensa obtenida. Si la recompensa es positiva estaremos reforzando ese comportamiento para el futuro. En cambio si la recompensa es negativa lo estaremos penalizando, para que ante la misma situación el agente actúe de manera distinta. El esquema en el que se apoya el Reinforcement Learning es en el de Proceso de Decisión de Markov.

Casos de Uso del Aprendizaje por Refuerzo

El aprendizaje por refuerzo puede ser usado en robots, por ejemplo en brazos mecánicos en donde en vez de enseñar instrucción por instrucción a moverse, podemos dejar que haga intentos “a ciegas” e ir recompensando cuando lo hace bien.

También puede usarse en ambientes que interactúan con el mundo real, como en otro tipo de maquinaria industrial y para el mantenimiento predictivo, pero también en el ambiente financiero, por ejemplo para decidir cómo conformar una cartera de inversión sin intervención humana.

Otro caso de uso que está ganando terreno es el de usar RL para crear “webs personalizadas” para cada internauta. Y si lo piensas… tiene algo de sentido tomar el concepto de “premiar” al algoritmo si acierta con las sugerencias que hace al usuario si hace clic ó penalizar al modelo si sus recomendaciones no le son de utilidad.

También se utiliza el Reinforcement Learning para entrenar sistemas de navegación de coches, drones ó aviones.

Y los Videojuegos? que pintan en todo esto?

Imagen del DeepMind en acción

Los videojuegos suelen ser ejemplos del uso de RL, ¿porque? te preguntarás. Pues porque los videojuegos son un entorno YA programado en el que se está simulando un ambiente y en el que ocurren eventos a la vez. Por lo general el jugador es el agente que debe decidir qué movimientos hacer. En el Starcraft tenemos ejércitos enemigos movilizados e intentando aniquilarnos, hay que desplazar distintas unidades que tienen variadas cualidades y hay que hacerlo rápido, atacar, defender, conquistar. ¿Cómo haríamos esto con un modelo de ML tradicional? es suficiente una sola red neuronal? muchas? cómo interactúan?. Pero sobre todo… ¿cómo crearíamos el grupo de “etiquetas de salida” para entrenar a la red, ante un juego imprevisible? Estamos diciendo que hay cientos de miles de combinaciones de salidas posibles.

Entonces, ¿Cómo funciona el RL?

Bien, vamos a comentar cómo funcionaría la secuencia de un algoritmo que aprende por refuerzo.

Cómo dijimos antes, el agente deberá tomar decisiones para interactuar con el ambiente, dado un estado. Pero, de qué manera tomar esas decisiones?

Premios y Castigos

Al principio de todo, nuestro agente está “en blanco”, es decir, no sabe nada de nada de lo que tiene que hacer ni de cómo comportarse. Entonces podemos pensar en que tomará una de las posibles acciones aleatoriamente. E irá recibiendo pistas de si lo está haciendo bien ó mal en base a las recompensas. Entonces irá “tomando nota”, esto bien, esto mal.

Una recompensa para un humano es algún estímulo que le de placer. Podría ser un aumento de sueldo, chocolate, una buena noticia. Para nuestro modelo de ML la recompensa es sencillamente un Score: un valor numérico.

Supongamos que la acción “A” nos recompensa con 100 puntos. El Agente podría pensar “genial, voy a elegir A nuevamente para obtener 100 puntos” y puede que el algoritmo se estanque en una única acción y nunca logre concretar el objetivo global que queremos lograr.

Es decir que tenemos que lograr un equilibrio entre “explorar lo desconocido y explotar los recursos” en el ambiente. Eso es conocido como el dilema de exploración/explotación.

El agente explorará el ambiente e irá aprendiendo “cómo moverse” y cómo ganar recompensas (y evitar las penalizaciones). Al final almacenará el conocimiento en unas normas también llamadas “políticas“.

Pero… debo decir que es probable que el agente “muera” ó pierda la partida las primeras… ¿mil veces? Con esto me refiero a que deberemos entrenar miles y miles de veces al agente para que cometa errores y aciertos y pueda crear sus políticas hasta ser un buen Agente.

¿Fuerza Bruta? En serio? estamos en 2020, por favor!

Bueno a decir la verdad si… esto es un poco vergonzoso… pero cierto. La realidad es que para hacerle aprender a un coche autónomo a conducir, debemos hacerlo chocar, acelerar, conducir contramano y cometer todo tipo de infracciones para decirle “eso está mal, te quito los puntos” y para ello, hay que hacer que ejecute miles y miles de veces en un entorno de simulado.

Para entrenar a DeepMind a dominar al Starcraft ha tenido que jugar el equivalente a miles de horas humanas de juego, y miles de partidas, puede que lo que le llevaría a una persona años, se logra en 8 horas. Y con ese aprendizaje logra vencer a los campeones jugadores humanos.

Esto tiene un lado bueno y uno malo. El malo ya lo vemos; tenemos que usar la fuerza bruta para que aprenda. Lo bueno es que contamos con equipos muy potentes que nos posibilitan realizar esta atrocidad. Por otra parte, recordemos que estamos apuntando a un caso de uso mucho más grande y ambicioso que el de “sólo distinguir entre perritos y gatitos” 😉

Q-Learning, el algoritmo más usado

Ahora vamos a comentar uno de los modelos usados en Reinforcement Learning para poder concretar un ejemplo de su implementación. Es el llamado “Q-Learning”.

Repasemos los elementos que tenemos:

  • Políticas: Es una tabla (aunque puede tener n-dimensiones) que le indicará al modelo “como actuar” en cada estado.
  • Acciones: las diversas elecciones que puede hacer el agente en cada estado
  • Recompensas: si sumamos ó restamos puntaje con la acción tomada
  • Comportamiento “avaro” (greedy en inglés) del agente. Es decir, si se dejará llevar por grandes recompensas inmediatas, ó irá explorando y valorando las riquezas a largo plazo

El objetivo principal al entrenar nuestro modelo a través de las simulaciones será ir “rellenando” la tabla de Políticas de manera que las decisiones que vaya tomando nuestro agente obtengan “la mayor recompensa” a la vez que avanzamos y no nos quedamos estancados, es decir, pudiendo cumplir el objetivo global (ó final) que deseamos alcanzar.

A la política la llamaremos “Q” por lo que:

Q(estado, acción) nos indicará el valor de la política para un estado y una acción determinados.

Y para saber cómo ir completando la tabla de políticas nos valemos de la ecuación de Bellman.

Ecuación de Bellman

La ecuación matemática que utilizaremos será:

No lo explicaré en detalle, pues tomaría mucho, pero en resumen; lo que explica la ecuación es cómo ir actualizando las políticas Q^(s,a) en base al valor actual más una futura recompensa que recibiremos, en caso de tomar dicha acción. Hay dos ratios que afectan a la manera en que influye esa recompensa: el ratio de aprendizaje, que regula “la velocidad” en la que se aprende, y la “tasa de descuento” que tendrá en cuenta la recompensa a corto o largo plazo.

Ejercicio Python de RL: Pong con Matplotlib

Hagamos una máquina que aprenda a jugar al Pong sóla (código completo en github).

Para no tener que instalar ningún paquete adicional… usaremos el propio matplotlib como interface gráfica del juego.

Este es el plan: simularemos el ambiente del juego y su compotamiento en la Jupyter Notebook.

El agente será el “player 1” y sus acciones posible son 2:

  1. mover hacia arriba
  2. mover hacia abajo

Y las reglas del juego:

  • El agente tiene 3 vidas.
  • Si pierde… castigo, restamos 10 puntos.
  • Cada vez que le demos a la bola, recompensa, sumamos 10.
  • Para que no quede jugando por siempre, limitaremos el juego a
    • 3000 iteraciones máximo ó
    • alcanzar 1000 puntos y habremos ganado.

Agreguemos los imports que usaremos:

import numpy as np
import matplotlib.pyplot as plt
from random import randint
from time import sleep
from IPython.display import clear_output
from math import ceil,floor

%matplotlib inline

La clase Agente

Dentro de la clase Agente encontraremos la tabla donde iremos almacenando las políticas. En nuestro caso la tabla cuenta de 3 coordenadas:

  1. La posición actual del jugador.
  2. La posición “y” de la pelota.
  3. La posición en el eje “x” de la pelota.

Además en esta clase, definiremos el factor de descuento, el learning rate y el ratio de exploración.

Los métodos más importantes:

  • get_next_step() decide la siguiente acción a tomar en base al ratio de exploración si tomar “el mejor paso” que tuviéramos almacenado ó tomar un paso al azar, dando posibilidad a explorar el ambiente
  • update() aquí se actualizan las políticas mediante la ecuación de Bellman que vimos anteriormente. Es su implementación en python.
class PongAgent:
    
    def __init__(self, game, policy=None, discount_factor = 0.1, learning_rate = 0.1, ratio_explotacion = 0.9):

        # Creamos la tabla de politicas
        if policy is not None:
            self._q_table = policy
        else:
            position = list(game.positions_space.shape)
            position.append(len(game.action_space))
            self._q_table = np.zeros(position)
        
        self.discount_factor = discount_factor
        self.learning_rate = learning_rate
        self.ratio_explotacion = ratio_explotacion

    def get_next_step(self, state, game):
        
        # Damos un paso aleatorio...
        next_step = np.random.choice(list(game.action_space))
        
        # o tomaremos el mejor paso...
        if np.random.uniform() <= self.ratio_explotacion:
            # tomar el maximo
            idx_action = np.random.choice(np.flatnonzero(
                    self._q_table[state[0],state[1],state[2]] == self._q_table[state[0],state[1],state[2]].max()
                ))
            next_step = list(game.action_space)[idx_action]

        return next_step

    # actualizamos las politicas con las recompensas obtenidas
    def update(self, game, old_state, action_taken, reward_action_taken, new_state, reached_end):
        idx_action_taken =list(game.action_space).index(action_taken)

        actual_q_value_options = self._q_table[old_state[0], old_state[1], old_state[2]]
        actual_q_value = actual_q_value_options[idx_action_taken]

        future_q_value_options = self._q_table[new_state[0], new_state[1], new_state[2]]
        future_max_q_value = reward_action_taken  +  self.discount_factor*future_q_value_options.max()
        if reached_end:
            future_max_q_value = reward_action_taken #maximum reward

        self._q_table[old_state[0], old_state[1], old_state[2], idx_action_taken] = actual_q_value + \
                                              self.learning_rate*(future_max_q_value -actual_q_value)
    
    def print_policy(self):
        for row in np.round(self._q_table,1):
            for column in row:
                print('[', end='')
                for value in column:
                    print(str(value).zfill(5), end=' ')
                print('] ', end='')
            print('')
            
    def get_policy(self):
        return self._q_table

La clase Environment

En la clase de Ambiente encontramos implementada la lógica y control del juego del pong. Se controla que la pelotita rebote, que no se salga de la pantalla y se encuentran los métodos para graficar y animar en matplotlib.

Por Defecto se define una pantalla de 40 pixeles x 50px de alto y si utilizamos la variable “movimiento_px = 5” nos quedará definida nuestra tabla de políticas en 8 de alto y 10 de ancho (por hacer 40/5=8 y 50/5=10). Estos valores se pueden modificar a gusto!

Además, muy importante, tenemos el control de cuándo dar las recompensas y penalizaciones, al perder cada vida y detectar si el juego a terminado

class PongEnvironment:
    
    def __init__(self, max_life=3, height_px = 40, width_px = 50, movimiento_px = 3):
        
        self.action_space = ['Arriba','Abajo']
        
        self._step_penalization = 0
        
        self.state = [0,0,0]
        
        self.total_reward = 0
        
        self.dx = movimiento_px
        self.dy = movimiento_px
        
        filas = ceil(height_px/movimiento_px)
        columnas = ceil(width_px/movimiento_px)
        
        self.positions_space = np.array([[[0 for z in range(columnas)] 
                                                  for y in range(filas)] 
                                                     for x in range(filas)])

        self.lives = max_life
        self.max_life=max_life
        
        self.x = randint(int(width_px/2), width_px) 
        self.y = randint(0, height_px-10)
        
        self.player_alto = int(height_px/4)

        self.player1 = self.player_alto  # posic. inicial del player
        
        self.score = 0
        
        self.width_px = width_px
        self.height_px = height_px
        self.radio = 2.5

    def reset(self):
        self.total_reward = 0
        self.state = [0,0,0]
        self.lives = self.max_life
        self.score = 0
        self.x = randint(int(self.width_px/2), self.width_px) 
        self.y = randint(0, self.height_px-10)
        return self.state

    def step(self, action, animate=False):
        self._apply_action(action, animate)
        done = self.lives <=0 # final
        reward = self.score
        reward += self._step_penalization
        self.total_reward += reward
        return self.state, reward , done

    def _apply_action(self, action, animate=False):
        
        if action == "Arriba":
            self.player1 += abs(self.dy)
        elif action == "Abajo":
            self.player1 -= abs(self.dy)
            
        self.avanza_player()

        self.avanza_frame()

        if animate:
            clear_output(wait=True);
            fig = self.dibujar_frame()
            plt.show()

        self.state = (floor(self.player1/abs(self.dy))-2, floor(self.y/abs(self.dy))-2, floor(self.x/abs(self.dx))-2)
    
    def detectaColision(self, ball_y, player_y):
        if (player_y+self.player_alto >= (ball_y-self.radio)) and (player_y <= (ball_y+self.radio)):
            return True
        else:
            return False
    
    def avanza_player(self):
        if self.player1 + self.player_alto >= self.height_px:
            self.player1 = self.height_px - self.player_alto
        elif self.player1 <= -abs(self.dy):
            self.player1 = -abs(self.dy)

    def avanza_frame(self):
        self.x += self.dx
        self.y += self.dy
        if self.x <= 3 or self.x > self.width_px:
            self.dx = -self.dx
            if self.x <= 3:
                ret = self.detectaColision(self.y, self.player1)

                if ret:
                    self.score = 10
                else:
                    self.score = -10
                    self.lives -= 1
                    if self.lives>0:
                        self.x = randint(int(self.width_px/2), self.width_px)
                        self.y = randint(0, self.height_px-10)
                        self.dx = abs(self.dx)
                        self.dy = abs(self.dy)
        else:
            self.score = 0

        if self.y < 0 or self.y > self.height_px:
            self.dy = -self.dy

    def dibujar_frame(self):
        fig = plt.figure(figsize=(5, 4))
        a1 = plt.gca()
        circle = plt.Circle((self.x, self.y), self.radio, fc='slategray', ec="black")
        a1.set_ylim(-5, self.height_px+5)
        a1.set_xlim(-5, self.width_px+5)

        rectangle = plt.Rectangle((-5, self.player1), 5, self.player_alto, fc='gold', ec="none")
        a1.add_patch(circle);
        a1.add_patch(rectangle)
        #a1.set_yticklabels([]);a1.set_xticklabels([]);
        plt.text(4, self.height_px, "SCORE:"+str(self.total_reward)+"  LIFE:"+str(self.lives), fontsize=12)
        if self.lives <=0:
            plt.text(10, self.height_px-14, "GAME OVER", fontsize=16)
        elif self.total_reward >= 1000:
            plt.text(10, self.height_px-14, "YOU WIN!", fontsize=16)
        return fig

El juego: Simular miles de veces para enseñar

Finalmente definimos una función para jugar, donde indicamos la cantidad de veces que queremos iterar la simulación del juego e iremos almacenando algunas estadísticas sobre el comportamiento del agente, si mejora el puntaje con las iteraciones y el máximo puntaje alcanzado.

def play(rounds=5000, max_life=3, discount_factor = 0.1, learning_rate = 0.1,
         ratio_explotacion=0.9,learner=None, game=None, animate=False):

    if game is None:
        game = PongEnvironment(max_life=max_life, movimiento_px = 3)
        
    if learner is None:
        print("Begin new Train!")
        learner = PongAgent(game, discount_factor = discount_factor,learning_rate = learning_rate, ratio_explotacion= ratio_explotacion)

    max_points= -9999
    first_max_reached = 0
    total_rw=0
    steps=[]

    for played_games in range(0, rounds):
        state = game.reset()
        reward, done = None, None
        
        itera=0
        while (done != True) and (itera < 3000 and game.total_reward<=1000):
            old_state = np.array(state)
            next_action = learner.get_next_step(state, game)
            state, reward, done = game.step(next_action, animate=animate)
            if rounds > 1:
                learner.update(game, old_state, next_action, reward, state, done)
            itera+=1
        
        steps.append(itera)
        
        total_rw+=game.total_reward
        if game.total_reward > max_points:
            max_points=game.total_reward
            first_max_reached = played_games
        
        if played_games %500==0 and played_games >1 and not animate:
            print("-- Partidas[", played_games, "] Avg.Puntos[", int(total_rw/played_games),"]  AVG Steps[", int(np.array(steps).mean()), "] Max Score[", max_points,"]")
                
    if played_games>1:
        print('Partidas[',played_games,'] Avg.Puntos[',int(total_rw/played_games),'] Max score[', max_points,'] en partida[',first_max_reached,']')
        
    #learner.print_policy()
    
    return learner, game

Para entrenar ejecutamos la función con los siguientes parámetros:

  • 6000 partidas jugará
  • ratio de explotación: el 85% de las veces será avaro, pero el 15% elige acciones aleatorias, dando lugar a la exploración.
  • learning rate = se suele dejar en el 10 por ciento como un valor razonable, dando lugar a las recompensas y permitiendo actualizar la importancia de cada acción poco a poco. Tras más iteraciones, mayor importancia tendrá esa acción.
  • discount_factor = También se suele empezar con valor de 0.1 pero aquí utilizamos un valor del 0.2 para intentar indicar al algoritmo que nos interesa las recompensas a más largo plazo.
learner, game = play(rounds=6000, discount_factor = 0.2, learning_rate = 0.1, ratio_explotacion=0.85)

Y vemos la salida del entreno, luego de unos 2 minutos:

Begin new Train! 
-- Partidas[ 500 ] Avg.Puntos[ -234 ]  AVG Steps[ 116 ] Max Score[ 10 ] 
-- Partidas[ 1000 ] Avg.Puntos[ -224 ]  AVG Steps[ 133 ] Max Score[ 100 ] 
-- Partidas[ 1500 ] Avg.Puntos[ -225 ]  AVG Steps[ 134 ] Max Score[ 230 ] 
-- Partidas[ 2000 ] Avg.Puntos[ -223 ]  AVG Steps[ 138 ] Max Score[ 230 ] 
-- Partidas[ 2500 ] Avg.Puntos[ -220 ]  AVG Steps[ 143 ] Max Score[ 230 ] 
-- Partidas[ 3000 ] Avg.Puntos[ -220 ]  AVG Steps[ 145 ] Max Score[ 350 ] 
-- Partidas[ 3500 ] Avg.Puntos[ -220 ]  AVG Steps[ 144 ] Max Score[ 350 ] 
-- Partidas[ 4000 ] Avg.Puntos[ -217 ]  AVG Steps[ 150 ] Max Score[ 350 ] 
-- Partidas[ 4500 ] Avg.Puntos[ -217 ]  AVG Steps[ 151 ] Max Score[ 410 ] 
-- Partidas[ 5000 ] Avg.Puntos[ -216 ]  AVG Steps[ 153 ] Max Score[ 510 ] 
-- Partidas[ 5500 ] Avg.Puntos[ -214 ]  AVG Steps[ 156 ] Max Score[ 510 ] 
Partidas[ 5999 ] Avg.Puntos[ -214 ] Max score[ 510 ] en partida[ 5050 ]

En las salidas vemos sobre todo cómo va mejorando en la cantidad de “steps” que da el agente antes de perder la partida.

Veamos el resultado!

Ya contamos con nuestro agente entrenado, ahora veamos qué tal se comporta en una partida de pong, y lo podemos ver jugar, pasando el parámetro animate=True.

Antes de jugar, instanciamos un nuevo agente “learner2” que utilizará las políticas que creamos anteriormente. A este agente le seteamos el valor de explotación en 1, para evitar que tome pasos aleatorios.

learner2 = PongAgent(game, policy=learner.get_policy())
learner2.ratio_explotacion = 1.0  # con esto quitamos las elecciones aleatorias al jugar
player = play(rounds=1, learner=learner2, game=game, animate=True)

Y veremos nuestro juego de Pong en acción!

En mi caso, con las 6 mil iteraciones de entrenamiento fue suficiente alcanzar los 500 puntos y ganar (puedes ir variando el objetivo a 500 puntos ó a 1000, la cantidad de vidas, etc.)

La Tabla de políticas resultante

Quiero brevemente comentar la tabla de políticas que hemos creado luego de entrenar.

En este ejemplo, mostraré una tabla de 3 coordenadas. La primera toma valores del 0 al 7 (posición del jugador), la segunda también 8 valores (altura de la bola de pong) y la tercera va del 0 al 9 con el desplazamiento horizontal de la pelota.

Supongamos que el player está situado en la posición “de abajo de todo”, es decir, en la posición cero.

Dentro de esa posición queda conformada la siguiente tabla:

Aquí vemos la tabla con las acciones a tomar si el jugador está en la posición cero y según donde se encuentre la bola en los valores x e y. Recuerda que tenemos creadas 8 tablas cómo esta, para cada posición del player.

Si nos fijamos en la coordenada de la bola (x8, y1) vemos los valores 1.9 para subir y -9 para bajar. Claramente la recompensa mayor está en la acción de subir. Pero si la pelotita estuviera en (x9,y4) la mejor acción será Bajar, aunque tenga un puntaje negativo de -16,7 será mejor que restar 46.

Conclusiones

Hay muchos más detalles y lecturas adicionales para dominar el tema, pero en este artículo hemos explicado los conceptos básicos del reinforcement learning, sus diferencias con el aprendizaje supervisado y sus características.

Además conocimos su implementación más conocida, el Q-Learning y realizamos un juego completo en Python en donde el Agente sin tener conocimiento previo de las reglas ni del entorno logra aprender y volverse un muy buen jugador de Pong tras miles de simulaciones.

Debo decir que una evolución muy interesante del Aprendizaje por Refuerzo es el Aprendizaje por Refuerzo Profundo en donde aparecen las redes neuronales a mejorar y perfeccionar al modelo. Escibiré sobre ello en un próximo artículo!

Deseos Finales

Aprovecho a desearles un muy buen fin de año y a que puedan empezar el 2021 con muchos planes y muchas ganas de seguir aprendiendo sobre Machine Learning y la ciencia de datos.

También les invito a descargar ó comprar “el libro del blog” en formato digital y como novedad, he logrado publicar en la tienda de Amazon la versión del libro en formato papel, en gran parte por algunos de vosotros que me lo pidieron. Así que mil gracias porque gracias a ese empuje y ánimo que me dieron, puedo decir que termino el año con mi primer libro publicado, lo cual para mi es un sueño cumplido! Y -perdón la insistencia con esto- pero ciertamente este año ha sido un año muy difícil para mi al igual que para todos y jamás hubiera pensado haberlo podido conseguir. Es un hito en mi vida.

Muchas gracias querido lector, desde aquí te envío un sincero abrazo virtual!.

Material del Artículo

Descarga la notebook completa desde GitHub aqui

Recursos Adicionales

Otros artículos relacionados:

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

El libro del Blog

Si te gustan los contenidos del blog y quieres darme una mano, puedes comprar el libro en papel, ó en digital.

The post Aprendizaje por Refuerzo first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/aprendizaje-por-refuerzo/feed/ 1 5911
Perfiles y Roles para Proyectos IA, Machine Learning y Data Science https://www.aprendemachinelearning.com/perfiles-roles-proyectos-ia-ml-data-science/ https://www.aprendemachinelearning.com/perfiles-roles-proyectos-ia-ml-data-science/#comments Wed, 21 Oct 2020 12:00:00 +0000 https://www.aprendemachinelearning.com/?p=6744 Queremos desarrollar un proyecto que contiene un alto grado de componente de Inteligencia Artificial, ya sea mediante Aprendizaje Automático ó Deep Learning, para predicción, clasificación ó clusterización (entre otros). ¿Qué personas debemos contratar? ¿Cómo podemos conformar un equipo para enfrentar este desafío? ¿Cuál es el...

The post Perfiles y Roles para Proyectos IA, Machine Learning y Data Science first appeared on Aprende Machine Learning.

]]>

Queremos desarrollar un proyecto que contiene un alto grado de componente de Inteligencia Artificial, ya sea mediante Aprendizaje Automático ó Deep Learning, para predicción, clasificación ó clusterización (entre otros). ¿Qué personas debemos contratar? ¿Cómo podemos conformar un equipo para enfrentar este desafío? ¿Cuál es el ciclo de vida de un proyecto de IA?

En este artículo intentaré comentar los seis perfiles más frecuentes solicitados por la industria en la actualidad, sus diversos roles. El artículo esta fuertemente basado en el reporte 2020 de Workera.

El proyecto de ML

Primero definamos en grandes rasgos las diversas etapas que conforman el desarrollo de un proyecto de Machine Learning.

  1. Análisis de Negocio
  2. Infraestructura de IA
  3. Ingeniería de Datos
  4. Modelado
  5. Implementación / Despliegue

1-Análisis de Negocio

En esta etapa se definen los objetivos que se desean alcanzar mediante el uso de la IA en el proyecto. Además se crean ó sugieren las métricas con las que se evaluará si los resultados que se obtengan darán valor -o no- al negocio.

Esta etapa es la primera e implica que al iterar el ciclo de vida del proyecto será la que decidirá si continuar o abandonar el proyecto. Entre otras cosas, se puede valer de visualizaciones y reportes (ó paneles) para lograr comprender el comportamiento de los modelos.

2-Infraestructura de IA

La infraestructura es una “etapa” transversal al resto de etapas, pues puede afectar al desarrollo de las mismas. Es conveniente contar con una mínima infraestructura sobre la que apoyarse desde el principio y que ese soporte sea flexible y escalable bajo demanda.

Necesitaremos ambientes para desarrollo, test y despliegue pero también herramientas, frameworks y entornos para negocio, seguridad, medios de almacenamiento, backups y auditoría. Debemos dar asistencia -o no- 24×7, tener algún mecanismo de feedback ó soporte técnico, repositorios para código, accesos restringidos a roles de usuario.

Una decisión importante también será si nosotros mismos montaremos y mantendremos la infraestructura (y sus costes) ó si nos apoyaremos en servicios existentes en la nube como AWS, Azure ó GCP.

3-Ingeniería de Datos

Esta etapa incluye la recolección de datos desde diversas fuentes y su tratamiento, preprocesado y futuro mantenimiento. Podemos tener uno ó muchos orígenes, bases de datos, archivos semi-estructurados ó datos sin estructura como ficheros de video o sonido. Acceso a información propia ó mediante APIs públicas ó de pago a terceros.

El tratamiento puede incluir múltiples transformaciones a datos existentes, cálculo de medias ó desvíos, agrupaciones, imputaciones ó reemplazo, descarte de columnas ó filas y hasta la generación de features sintéticas.

Todo esto sobre algunos megas ó a gigabits de información que debemos procesar en tiempo y forma. Aparecen cuestiones como el procesado masivo distribuido y en paralelo.

Y no olvidemos aquí, de ser necesario el asunto de las clases desbalanceadas y cómo equilibrarlas.

4-Modelado

Esta es la etapa donde ocurre la magia 😉 aquí es donde usaremos todos nuestros mayores skills en Data Science, Machine Learning, matemáticas y estadística, ingenio y creatividad.

Seleccionar modelos, algoritmos, selección de features, tuneo de hiperparámetros, entrenamiento, evaluación, split, métricas (técnicas y de negocio), optimización, interpretabilidad… predicción, clasificación, clustering, uso o no de redes neuronales, prueba y error, arquitecturas de redes, NLP, combinación, permutación, ensambles… BANG!

5-Implementación / Despliegue

Durante la fase de implementación y despliegue deberemos formalizar el código prototipo y pruebas realizadas anteriormente en un pipeline robusto y consistente.

Debemos combinar las etapas de obtención de datos con la de modelado para que puedan interelacionarse y mantenerse en el tiempo.

Aquí es importante contar con un protocolo sobre cómo hacer el pasaje desde entornos de desarrollo a test y producción.

Además la fase de predicción puede requerir un despliegue como servicio web ó como un proceso batch ó puede tener otro tipo de endpoint como colas MQ u otro tipo de invocacion mediante sockets, definir su necesidad de tiempo real ó no.

Se debe contemplar el reentreno de los modelos, tiempos, triggers y condiciones para decidir si se reemplazará o no el modelo actual.

Y vuelta a empezar…

No olvidemos que estos 5 pasos son iterativos, con lo cual luego de la implementación volveríamos a comenzar en la etapa de Análisis de negocio, evaluando los resultados ó repercusiones obtenidas.

Los 6 Roles del equipo IA

A continuación comentaremos los 6 roles que cubren las diversas etapas del ciclo de vida de los proyectos de IA. Muchas veces estos roles se superponen unos a otros y muchas veces veremos cómo podemos identificarnos con más de uno de los roles. Estos están planteados como para lograr una especialidad en cada rol y obtener los beneficios -en una gran compañía sobretodo- que proporciona el supuesto de la separación de tareas.

  1. Data Scientist
  2. Machine Learning Engineer
  3. Data Analyst
  4. Software Engineer ML
  5. ML Researcher
  6. Software Engineer

1-Data Scientist

Skills de un Data Scientist – workera.ai

El científico de datos puede desarrollar las etapas de Ingeniería de Datos, modelado y Análisis de Negocio. Deberá tener fundamentos científicos sólidos así como habilidades en comunicación para poder transmitir los hallazgos a otros miembros del equipo ó a usuarios de negocio.

TOOLS: Python, numpy, scikit learn, Tensorflow, Pytorch, SQL, Tableau, Excel, PowerBI, Git, Jupyter Notebook.

2-Machine Learning Engineer

Skills de un Machine Learning Engineer – workera.ai

Pueden desarrollar las tareas de Ingeniería en datos, modelado y despliegue. En algunos casos también pueden colaborar con la analíticas de negocio y en la infraestructura.

Deben tener habilidades en ingeniería pero también ciencias. Sus competencias en comunicación pueden depender de las necesidades del equipo y del resto de roles. Se prevé que este rol esté al tanto de las últimas tendencias en algoritmos y papers relacionados con Machine Learning y el uso y técnicas de Deep Learning.

TOOLS: Python, SQL, numpy, scikit learn, Tensorflow, Pytorch, Cloud: AWS, Azure, GCP, Git, Jupyter Notebook, JIRA.

3-Data Analyst

Skills de un Data Analyst – workera.ai

Preparado para las fases de Ingeniería de Datos y Análisis de Negocios. Por lo general tienen un gran conocimiento de SQL y manejo de bases de datos y analítica avanzada de negocios, visualización y reporting.

Por lo general se pretende de este rol muy buenas habilidades comunicativas, y se les exige menos en capacidad algorítmica ó de programación.

TOOLS: Python, SQL, Tableau, PowerBI, Excel, PowerPoint, A/B testing.

4-Software Engineer ML

Skills de un Software Engineer en Machine Learning – workera.ai

Personas con este título podrán desarrollar las etapas de Ingeniería de Datos, modelado, despliegue e infraestructura.

Deberían trabajar bien con otros miembros que trabajen con la parte de negocio. Este rol es conveniente para etapas tempranas de equipos o startups pues puede cubrir multitud de tareas, logrando prototipos y demostrando gran versatilidad.

TOOLS: Python, SQL, numpy, scikit learn, Tensorflow, Pytorch, AWS, GCP, Azure, Git, Jupyter Notebook, JIRA.

5-ML Researcher

Skills de un Machine Learning Researcher – workera.ai

Este rol puede llevar las etapas de Ingeniería de datos y modelado. Desarrollan su mayor potencial en un ambiente de investigación, donde puedan dar rienda a sus conocimientos para buscar y descubrir patrones en los datos. Debe tener excelentes habilidades y conocimiento científico.

También puede especializarse en Deep Learning ó en algun área en particular como NLP, visión artificial ó motores de recomendación.

TOOLS: Python, SQL, numpy, scikit learn, Tensorflow, Pytorch, Git, Jupyter Notebook, Arxiv, NeurIPS, papers.

6-Software Engineer

Skills de un Software Engineer – workera.ai

Este rol -ahora muy ligado a “devops”- puede ocuparse de las etapas de Ingeniería de Datos e Infraestructura.

Demuestran gran habilidad en programación y manejo de software y diversas herramientas ó plataformas especializadas.

TOOLS: Python, SQL, AWS, GCP, Azure, Git, Jupyter Notebook, JIRA.

Las Habilidades del buen Soldado ML

Data Science tech Stack 2020

Vamos a listar algunas de las habilidades y herramientas más recurrentes al solicitar los servicios de esta buena gente:

Machine Learning:

Deep Learning

Data Science

  • Probabilidad (Bayes, condicional)
  • Estadística (hipótesis, bias/varianza)
  • Análisis de Datos (Visualización, métricas)

Matemáticas

  • Álgebra lineal (vectores, matrices)
  • Cálculo (derivadas, integrales)
  • Funciones matemáticas (min, max)

Algorithmic Coding

  • Programación de algoritmos
  • Estructuras de datos
  • Ordenamiento y búsqueda

Software Engineering

  • Manejo de Software científico
  • Programación Orientada a Objetos
  • Rest Apis
  • Base de Datos / Sql y NoSql
  • Repositorios (git), TDD

Conclusiones

En el articulo hemos visto los 6 roles más frecuentemente citados en las búsquedas laborales y los cuales conforman los perfiles principales para crear un equipo de desarrollo de proyectos de Machine Learning. Recuerden que muchas veces estos roles y sus habilidades no están tan bien definidas y abarcan mucho más de lo que aquí se comenta.

También suele ocurrir roles muy fuertemente pegados a una sola tecnología ó plataforma; en ese caso mi consejo es tratar de ser generalista y comprender los conceptos de fondo. Por ejemplo, si para un proyecto en particular se buscan personas expertas en AWS, conocer Azure o Google Cloud nos puede dar expertise en casi las mismas tareas, aunque con distintos “sabores”.

Por último no dejar de decir que este es un ecosistema bastante nuevo y cambiante… con lo cual… todo puede cambiar!! Hay que formarse continuamente!

Más Recursos

El primer y principal recurso que quiero enlazar es la propia web de Workera en donde me base para redactar el artículo:

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

Aún no realizaste el ejercicio práctico de detección de objetos con Python, Keras y Tensorflow? Anímate!

El libro del Blog

Si te gustan los contenidos del blog y quieres darme una mano, puedes comprar el libro en papel, ó en digital.

The post Perfiles y Roles para Proyectos IA, Machine Learning y Data Science first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/perfiles-roles-proyectos-ia-ml-data-science/feed/ 2 6744
Modelos de Detección de Objetos https://www.aprendemachinelearning.com/modelos-de-deteccion-de-objetos/ https://www.aprendemachinelearning.com/modelos-de-deteccion-de-objetos/#respond Fri, 21 Aug 2020 08:00:00 +0000 https://www.aprendemachinelearning.com/?p=6747 Luego de haber hecho un ejercicio Práctico de Detección de objetos en imágenes por medio de redes neuronales, veremos la teoría que hay detrás de estos algoritmos. Para comprender el artículo doy por sentado que ya tienes conocimiento de cómo funcionan las redes neuronales y...

The post Modelos de Detección de Objetos first appeared on Aprende Machine Learning.

]]>
Luego de haber hecho un ejercicio Práctico de Detección de objetos en imágenes por medio de redes neuronales, veremos la teoría que hay detrás de estos algoritmos.

Para comprender el artículo doy por sentado que ya tienes conocimiento de cómo funcionan las redes neuronales y de la teoría de Clasificación de imágenes. Si no, te recomiendo que leas primero esos artículos.

Agenda

  • Introducción: ¿Qué es la detección de imágenes?
  • Primera intuición de detección a partir de la clasificación con CNN
  • R-CNN: búsqueda selectiva
    • ¿Cómo funciona R-Cnn?
  • Problemas y mejoras: fast y faster r-cnn
  • Detección Rápida: YOLO
    • ¿Cómo funciona YOLO?
    • Arquitectura de la red Darknet
  • Otras alternativas
    • 2016 – Single Shot Detection
    • 2018 – RetinaNet
    • 2019 – Google Spinet
    • 2020 – Facebook saca del horno DETR
  • Resumen

Introducción: ¿Qué es la detección de imágenes?

Podemos tener la errónea intuición de que la detección de imágenes sea una tarea sencilla, pero veremos que realmente no lo es y de hecho es un gran problema a resolver. Nosotros los humanos podemos ver una foto y reconocer inmediatamente cualquier objeto que contenga de un vistazo rápido, si hay objetos pequeños o grandes, si la foto es oscura ó hasta algo borrosa. Imaginemos un niño escondido detrás de un árbol donde apenas sobresale un poco su cabeza ó un pie.

Para la detección de imágenes mediante Algoritmos de Machine Learning esto implica una red neuronal convolucional que detecte una cantidad limitada (ó específica) de objetos, no pudiendo detectar objetos que antes no hubiera visto, ó si están en tamaños que logra discernir y todas las dificultades de posibles “focos”, rotación del objeto, sombras y poder determinar en qué posición -dentro de la imagen- se encuentra.

Si es difícil con 1 objeto… imagínate con muchos!.

¿En qué consiste la detección de objetos?

Un algoritmo de Machine Learning de detección, para considerarse como tal deberá:

  • Detectar multiples objetos.
  • dar la posición X e Y del objeto en la imagen (o su centro) y dibujar un rectángulo a su alrededor.
  • Otra alternativa es la segmentación de imágenes (no profundizaremos en este artículo).
  • Detectar “a tiempo”… o puede que no sirva el resultado. Esta es una característica que debemos tener en cuenta si por ejemplo queremos hacer detección en tiempo real sobre video.

Nueva Salida

Entonces para entrenar nuestra máquina de manera supervisada deberemos indicar la clase del objeto (por ejemplo perro ó gato) y además la posición dentro de la imagen, X, Y el ancho y alto del objeto.

Y por si esto fuera poco, podrían ser múltiples objetos en la misma imagen, con lo cual para detectar 2 perros en una foto, necesitamos como salida 10 neuronas.

Este es un gran cambio, pues en clasificación de imágenes veníamos acostumbrados a devolver un array con por ejemplo Perro = [1 0] y Gato = [0 1].

La nueva salida deberá contener adicionalmente la posición (por ej. 54,45) y dimensión (por ej. 100,100) de cada clase, resultando en algo mínimo como

  • [1 0 100 100 54 45] pudiendo detectar sólo 1 objeto ó
  • [1 0 100 100 54 45 0 1 200 200 30 25] para 2 objetos.

Primera intuición: detección a partir de la clasificación

Podemos partir de este punto: tenemos una red CNN entrenada para detectar perros y gatos y supongamos que tiene una muy buena taza de aciertos. A esta red le pasamos una imagen nueva y nos devuelve “perro” ó “gato”. Agregaremos una tercera salida “otros” por si le pasamos la foto de algo que no sepa reconocer .

Entre las redes CNN pre-entregadas más conocidas están Alexnet, Resnet, y VGG

Si a nuestra red pre-entrenada, le pasamos una imagen con 2 perros será incapaz de detectarlos, puede que no detecte ni siquiera a uno.

Si le pasamos una imagen con perros y gatos, tampoco los podrá identificar y mucho menos localizar.

Entonces lo que el “sentido común de ingenieros” nos dice es: “vamos a iterar”. Es decir, iteremos un “área reducida” dentro de la foto de izquierda a derecha y de arriba abajo y le aplicamos la CNN pre-entrenada para ver si detecta algo.

Al ir iterando, lograremos detectar los 2 animales de la foto.

La foto original
El resultado deseado
Comenzamos a iterar…
Perro detectado
Otro tamaño de bounding-box…
iteramos de izq-der, arriba abajo…
Gato detectado!

Sin embargo esta solución trae consigo múltiples inconvenientes:

  1. ¿De qué tamaño será la ventana deslizante? y de hecho, podría ser de diversos tamaños.
  2. ¿Cuántos píxeles nos moveremos hacia izquierda (y luego hacia abajo)?
  3. Dependiendo de esos factores, el tiempo de cómputo podría ser muy largo, pues para cada movimiento implica realizar una clasificación individual con la CNN.
  4. Si detectamos algún objeto dentro de la ventana, ¿quiere decir que tengo los valores x e y? No necesariamente.
  5. Si nos movemos apenas pixeles con la ventana, podemos estar detectando al “mismo perro” múltiples veces
  6. Surge una problemática de poder distinguir entre animales si estos se encuentran muy cercanos.
Podemos tener dos cajas que detectan al mismo perro.
Esta detección es correcta, 2 perros: pero podría ocurrir…
…detectar por error a 2 perros dentro de una misma caja

De los puntos 5 y 6 surge la necesidad de crear una nueva métrica específica para la detección de imágenes en donde podamos evaluar al mismo tiempo si la clase de objeto es correcta y si la posición del “bounding box” (X,Y, alto y ancho) es buena. Esa métrica será “mAP“.

A raíz de estos puntos, surgen estrategias para intentar solventarlos. Veamos algunas.

R-CNN: búsqueda selectiva

En 2014 surgen las “Region Based Convolutional Neural Networks” con la siguiente propuesta: primero determinar “regiones de interés” dentro de la imagen (esto es conocido como “selective search”) y luego realizar clasificación de imágenes sobre esas áreas usando una red pre-entrenada.

Esto implica un primer algoritmo sobre la imágen que pueda determinar las áreas de interés que pueden llegar a ser 2000 regiones de diversos tamaños (si había más, se descartan). Luego pasar esas regiones por la CNN y mediante un clasificador binario validar si eran de clases correctas y eliminar las de poca confianza. Finalmente un regresor se encargaría de ajustar correctamente la posición de la localización.

La selección de las regiones podría ser por ejemplo “áreas contiguas con un mismo tono de color” ó detección de líneas que delimiten áreas, ó cambios bruscos en contraste y brillo. Son pasadas “rápidas” sobre una imagen, similar a como lo hace un editor de imágenes.

Fuente:  https://arxiv.org/abs/1311.2524

Para evitar el solapamiento del mismo objeto en diversas áreas se utiliza el concepto de IoU ó “Intersection over Union”.

IoU: nos da un porcentaje de acierto del área de predicción frente a la bounding-box real que queríamos detectar.

El IoU en conjunto con “Non-Máximum-Supression” ayudan a seleccionar las áreas del objeto que queremos localizar.

NMS: nos permite quedarnos de entre muchas cajas que detectaron al mismo objeto y se superponen, con la que mejor se ajusta al resultado. Nos quedamos con la mejor y eliminamos al resto.

A pesar de todas estas mejoras, la detección de objetos sobre una sola imagen podía tomar unas 25 segundos. Y el entrenamiento de la propia red es muy lento.

Mejoras sobre R-CNN: fast y faster R-cnn

Surgen otros 2 algoritmos: fast R-CNN y luego faster R-CNN para intentar mejorar el tiempo de detección.

Fast R-CNN mejora el algoritmo inicial haciendo reutilización de algunos recursos como el de las features extraídas por la CNN agilizando el entreno y detección de las imágenes. Esta nueva red tiene mejoras también en el IOU y en la función de Loss para mejorar el posicionamiento de la “caja delimitante”. Sin embargo no ofrece un aumento dramático de velocidad en el entrenamiento y detección.

Faster R-CNN logra una mejora en velocidad al integrar el algoritmo de “región proposal” sobre la propia CNN. Además aparece el concepto de usar “anchor” fijos, es decir, ciertos tamaños pre calculados para la detección de objetos específicos de la red. Por ejemplo, podemos definir 3 tamaños de ventana en 3 escalas distintas de tamaños, es decir un total de 9 anclas.

Faster-R-CNN. Fuente https://arxiv.org/abs/1506.01497

Mask R-CNN

No entraré en detalle, esta red, intenta hacer uso de las R-CNN pero en vez de detectar el “bounding box” de cada objeto, intentará hacer segmentación de imagen, definiendo la superficie de cada objeto.

Fuente: https://arxiv.org/abs/1703.06870

Detección Rápida: YOLO

En 2016 crean YOLO, una red que quiere decir “You Only Look Once“. Esta red hace una única pasada a la red convolucional y detecta todos los objetos para los que ha sido entrenada para clasificar. Al ser un “sólo cálculo” y sin necesidad de iterar, logra velocidades nunca antes alcanzadas con ordenadores que no tienen que ser tan potentes. Esto permite detección sobre video en tiempo real de cientos de objetos en simultáneo y hasta su ejecución en dispositivos móviles.

¿Cómo funciona YOLO ?

Yolo es una solución que reutiliza varias técnicas que vimos anteriormente con un “twist-plot” final.

Yolo define una grilla de tamaño fijo sobre la imagen de 13×13. Sobre esas celdas intentará detectar objetos valiéndose de anchors fijos, por ejemplo de 3 anclas con 3 tamaños distintos (9 predicciones por cada celda). Hace uso de IoU y Non-Max-supression. También tiene asociada una red de regresión al final para las posiciones de los bounding-boxes.

Yolo utiliza una grilla fija, en este caso de 13×13
Aqui vemos ejemplo de 5 anclas de distintos tamaños

La “grandiosidad” de YOLO consiste en su red CNN. Antes vimos que R-CNN utilizaba algún algoritmo adicional para seleccionar las regiones de interés sobre las que realiza las predicciones. En cambio YOLO, utiliza la misma Red CNN de clasificación con un “truco” por el cual no necesita iterar la grilla de 13×13, si no que la propia red se comporta como si hiciera un especie de “offset” que le permite hacer la detección en simultáneo de las 169 casillas.

YOLO utiliza una red CNN llamada Darknet, aunque también puede ser entrenada con cualquier otra red Convolucional. Al mismo tiempo de entrenarse se crea la red con este <<offset>> que comentaba.

Este video te ayudará comprender el funcionamiento de YOLO, explicado nada más y nada menos que por Andrew Ng.

Además Yolo utiliza las neuronas de tipo convolucional al final de la cadena sin necesidad de hacer la transformación a una red “tradicional”.

Gracias a estos retoques, logra la sorprendente capacidad de casi 60 FPS (cuadros por segundo) en ordenadores normales. Se le critica que si bien es rápida, suele tener menor porcentaje de aciertos frente a las R-CNN.

Pero con el paso del tiempo fueron evolucionando las versiones YoloV2, V3 y recientemente V4 que están enfocadas a mejorar esa precisión de las bounding boxes, a la vez que mantienen su rapidez.

Resultados de YOLOv3 sobre el Dataset COCO.

Arquitectura de la Red

La arquitectura se basa en una red convolucional GoogleNet y consta de 24 capas convolucionales. El autor la bautizó como Darknet. Embebe en su salida tanto la parte que clasifica las imágenes como la de posicionamiento y tamaño de los objetos.

Por ejemplo par el CocoDataset que debe detectar 80 objetos diferentes, tendremos como salida:

Tamaño de grillaCantidad AnclasCantidad de clases Ccore, X, Y, Alto, Ancho
13 * 13* 3 * (80 +* 5)

Para este ejemplo nos dará un array de 43.095 datos siendo el máximo de objetos que puede detectar y localizar 13x13x3 = 507 objetos de 80 clases en la misma foto en una sola pasada. (Realmente hará 13x13x3 x3 tamaños = 1521 predicciones). Sorprendente!.

Crea tu propia red de detección de objetos YOLO siguiendo este ejercicio explicado paso a paso y con todo el código Python en una Jupyter Notebook usando Keras y Tensorflow

Otras Alternativas para Detección

Comentaremos brevemente otras técnicas que surgieron y que también se pueden utilizar.

SSD – Single Shot Detector

Tiene una estructura piramidal en su CNN en la que las capas van disminuyendo gradualmente. Esto le permite poder detectar objetos grandes y pequeños. No utiliza una grilla predefinida, pero cuenta con “anclas” de distintas proporciones que se van escalando a medida que descendemos por la pirámide (mapa de features más pequeños, con anclas proporcionalmente más grandes).

RetinaNet (2018)

RetinaNet también se basa en una estructura de CNN piramidal mejorada para reconocer objetos de diversos tamaños en una sola pasada. Innova con una nueva función de pérdida llamada <<Focal Loss>>.

Google: Spinet (dic 2019)

Google Spinet rompe con la estructura piramidal y propone una arquitectura novedosa llamada “scale-permuted” en la que se alternan diversos tamaños en las convoluciones.

Facebook: DETR (junio 2020)

Facebook propone una “End to End object detection with Transformers“. Es decir, utilizar la más novedosa y efectiva técnica de redes neuronales utilizada en NLP pero aplicada a la detección de imágenes! Muy ingenioso!

Resumen

La tarea de Detección de objetos en imágenes fue impulsora de mejora tanto en redes neuronales convolucionales como en la arquitectura general utilizada poniendo a prueba el valor real del deeplearning, entrelazando redes con funciones específicas.

Los logros obtenidos son enormes, de gran aplicación y como vemos sigue siendo un campo en desarrollo, en donde grandes como Google y Facebook siguen innovando con nuevas propuestas, aún con un mundo bajo Pandemia.

Las aplicaciones que tiene la detección de imágenes van desde seguridad, conducción de coches autónomos hasta salud y poder dar visión -al fin- a los robots 😉

Si te suscribes salvas un gatito (o no)

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

Aún no realizaste el ejercicio práctico de detección de objetos con Python, Keras y Tensorflow? Anímate!

El libro del Blog

Si te gustan los contenidos del blog puedes comprar el libro en papel ó en

formato digital (el precio lo pones tú!)…

The post Modelos de Detección de Objetos first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/modelos-de-deteccion-de-objetos/feed/ 0 6747
Detección de outliers en Python https://www.aprendemachinelearning.com/deteccion-de-outliers-en-python-anomalia/ https://www.aprendemachinelearning.com/deteccion-de-outliers-en-python-anomalia/#comments Tue, 02 Jun 2020 10:00:00 +0000 https://www.aprendemachinelearning.com/?p=7216 En este nuevo artículo de Aprende Machine Learning explicaremos qué son los outliers y porqué son tan importantes, veremos un ejemplo práctico paso a paso en Python, visualizaciones en 1, 2 y 3 dimensiones y el uso de una librería de propósito general. Puedes encontrar...

The post Detección de outliers en Python first appeared on Aprende Machine Learning.

]]>
En este nuevo artículo de Aprende Machine Learning explicaremos qué son los outliers y porqué son tan importantes, veremos un ejemplo práctico paso a paso en Python, visualizaciones en 1, 2 y 3 dimensiones y el uso de una librería de propósito general.

Puedes encontrar la Jupyter Notebook completa en GitHub.  

¿Qué son los Outliers?

Es interesante ver las traducciones de “outlier” -según su contexto- en inglés:

  • Atípico
  • Destacado
  • Excepcional
  • Anormal
  • Valor Extremo, Valor anómalo, valor aberrante!!

Eso nos da una idea, ¿no?

Es decir, que los outliers en nuestro dataset serán los valores que se “escapan al rango en donde se concentran la mayoría de muestras”. Según Wikipedia son las muestras que están distantes de otras observaciones.

Detección de Outliers

¿Y por qué nos interesa detectar esos Outliers? Por que pueden afectar considerablemente a los resultados que pueda obtener un modelo de Machine Learning… Para mal… ó para bien! Por eso hay que detectarlos, y tenerlos en cuenta. Por ejemplo en Regresión Lineal ó algoritmos de Ensamble puede tener un impacto negativo en sus predicciones.

Outliers Buenos vs Outliers Malos

Los Outliers pueden significar varias cosas:

  1. ERROR: Si tenemos un grupo de “edades de personas” y tenemos una persona con 160 años, seguramente sea un error de carga de datos. En este caso, la detección de outliers nos ayuda a detectar errores.
  2. LIMITES: En otros casos, podemos tener valores que se escapan del “grupo medio”, pero queremos mantener el dato modificado, para que no perjudique al aprendizaje del modelo de ML.
  3. Punto de Interés: puede que sean los casos “anómalos” los que queremos detectar y que sean nuestro objetivo (y no nuestro enemigo!)

Instala tu ambiente de desarrollo python con Anaconda, aquí explicamos cómo

Muchas veces es sencillo identificar los outliers en gráficas. Veamos ejemplos de Outliers en 1, 2 y 3 dimensiones.

Outliers en 1 dimensión

Si analizáramos una sola variable, por ejemplo “edad”, veremos donde se concentran la mayoría de muestras y los posibles valores “extremos”. Pasemos a un ejemplo en Python!

import matplotlib.pyplot as plt
import numpy as np

edades = np.array([22,22,23,23,23,23,26,27,27,28,30,30,30,30,31,32,33,34,80])
edad_unique, counts = np.unique(edades, return_counts=True)

sizes = counts*100
colors = ['blue']*len(edad_unique)
colors[-1] = 'red'

plt.axhline(1, color='k', linestyle='--')
plt.scatter(edad_unique, np.ones(len(edad_unique)), s=sizes, color=colors)
plt.yticks([])
plt.show()
En azul los valores donde se concentra la mayoría de nuestras filas. En rojo un outlier, ó “valor extremo”.

En el código, importamos librerías, creamos un array de edades con Numpy y luego contabilizamos las ocurrencias.

Al graficar vemos donde se concentran la mayoría de edades, entre 20 y 35 años. Y una muestra aislada con valor 80.

Outliers en 2 Dimensiones

Ahora supongamos que tenemos 2 variables: edad e ingresos. Hagamos una gráfica en 2D. Además, usaremos una fórmula para trazar un círculo que delimitará los valores outliers: Los valores que superen el valor de la “media más 2 desvíos estándar” (el área del círculo) quedarán en rojo.

from math import pi

salario_anual_miles = np.array([16,20,15,21,19,17,33,22,31,32,56,30,22,31,30,16,2,22,23])
media = (salario_anual_miles).mean()
std_x = (salario_anual_miles).std()*2
media_y = (edades).mean()
std_y = (edades).std()*2

colors = ['blue']*len(salario_anual_miles)
for index, x in enumerate(salario_anual_miles):
    if abs(x-media) > std_x:
        colors[index] = 'red'
        
for index, x in enumerate(edades):
    if abs(x-media_y) > std_y:
        colors[index] = 'red'

plt.scatter(edades, salario_anual_miles, s=100, color=colors)
plt.axhline(media, color='k', linestyle='--')
plt.axvline(media_y, color='k', linestyle='--')

v=media     #y-position of the center
u=media_y    #x-position of the center
b=std_x     #radius on the y-axis
a=std_y    #radius on the x-axis

t = np.linspace(0, 2*pi, 100)
plt.plot( u+a*np.cos(t) , v+b*np.sin(t) )

plt.xlabel('Edad')
plt.ylabel('Salario Anual (miles)')
plt.show()
Dentro del circulo azul, los valores que están en la media y en rojo los outliers: 3 valores que superan en más de 2 veces el desvío estándar.

Veamos -con la ayuda de seaborn-, la línea de tendencia de la misma distribución con y sin outliers:

CON OUTLIERS: La línea de tendencia se mantiene plana sobre todo por el outlier de la edad
SIN OUTLIERS: Al quitar los outliers la tendencia empieza a tener pendiente

Con esto nos podemos dar una idea de qué distinto podría resultar entrenar un modelo de Machine Learning con ó sin esas muestras anormales.

Visualizar Outliers en 3D

Vamos viendo que algunas de las muestras del dataset inicial van quedando fuera!

¿Qué pasa si añadimos una 3ra dimensión nuestro dataset? Por ejemplo, la dimensión de “compras por mes” de cada usuario.

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(7,7))
ax = fig.gca(projection='3d')

compras_mes = np.array([1,2,1,20,1,0,3,2,3,0,5,3,2,1,0,1,2,2,2])
media_z = (compras_mes).mean()
std_z = (compras_mes).std()*2

for index, x in enumerate(compras_mes):
    if abs(x-media_z) > std_z:
        colors[index] = 'red'

ax.scatter(edades, salario_anual_miles, compras_mes, s=20, c=colors)
plt.xlabel('Edad')
plt.ylabel('Salario Anual (miles)')
ax.set_zlabel('Compras mensuales')

plt.show()
Vemos en 3 dimensiones que hay valores que escapan a la <<distribución normal>>. Valores atípicos en rojo.

En el caso de las compras mensuales, vemos que aparece un nuevo “punto rojo” en el eje Z. Debemos pensar si es un usuario que queremos descartar ó que por el contrario, nos interesa analizar.

Outliers en N-dimensiones

La realidad es que en los modelos con los que trabajamos constan de muchas dimensiones, podemos tener 30, 100 ó miles. Entonces ya no parece tan sencillo visualizar los outliers.

Podemos seguir detectando los outliers “a ciegas” y manejarlos. O mediante una librería (más adelante se comenta en el artículo).

Podemos graficar múltiples dimensiones haciendo una reducción de dimensiones con PCA ó con T-SNE.

NOTA: tenemos que pensar que -suponiendo que no hay error en los datos- un valor que analizado en 1 sóla dimensión es un Outlier, analizado en conjunto en “N-dimensiones” puede que NO LO SEA. Entonces no siempre es válida la estrategia de analizar la variable aislada del resto.

Imaginemos que luego de aplicar PCA sobre un conjunto obtenemos los siguientes clusters:

Aquí vemos claramente que hay valores que no “encajan” en ningún conjunto: los outliers. Esto a veces se podría corresponder con “Anomaly detection”.

Una gráfica de detección sencilla: Boxplots

Una gráfica bastante interesante de conocer es la de los Boxplots, muy utilizados en el mundo financiero. En nuestro caso, podemos visualizar las variables y en esa “cajita” veremos donde se concentra el 50 por ciento de nuestra distribución (percentiles 25 a 75), los valores mínimos y máximos (las rayas en “T”) y -por supuesto- los outliers, esos “valores extraños” y alejados.

green_diamond = dict(markerfacecolor='g', marker='D')
fig, ax = plt.subplots()
ax.set_title('Boxplot por Edades')
ax.boxplot(edades, flierprops=green_diamond, labels=["Edad"])
Ese diamante verde está muy alejado de nuestra media!

Una vez detectados, ¿qué hago?

Según la lógica de negocio podemos actuar de una manera u otra.

Por ejemplo podríamos decidir:

  • Las edades fuera de la distribución normal, eliminar.
  • El salario que sobrepasa el límite, asignar el valor máximo (media + 2 sigmas).
  • Las compras mensuales, mantener sin cambios.

PyOD: Librería Python para Detección de Outliers

En el código utilicé una medida conocida para la detección de outliers que puede servir: la media de la distribución más 2 sigmas como frontera. Pero existen otras estrategias para delimitar outliers.

Una librería muy recomendada es PyOD. Posee diversas estrategias para detectar Outliers. Ofrece distintos algoritmos, entre ellos Knn que tiene mucho sentido, pues analiza la cercanía entre muestras, PCA, Redes Neuronales, veamos cómo utilizarla en nuestro ejemplo.

!pip install pyod  # instala la librería

from pyod.models.knn import KNN
import pandas as pd

X = pd.DataFrame(data={'edad':edades,'salario':salario_anual_miles, 'compras':compras_mes})

clf = KNN(contamination=0.18)
clf.fit(X)
y_pred = clf.predict(X)
X[y_pred == 1]
La librería PyOd detecta los registros anómalos

Para problemas en la vida real, con múltiples dimensiones conviene apoyarnos en una librería como esta que nos facilitará la tarea de detección y limpieza/transformación del dataset.

Conclusiones

Hemos visto lo importante que son los outliers y el impacto que pueden tener al entrenar un modelo de ML. La mayoría de los datasets tendrán muestras “fuera de rango”, por lo que debemos tenerlas en cuenta y decidir cómo tratarlas.

Para algunos problemas, nos interesa detectar esos outliers y de hecho será nuestro objetivo localizar esas anomalías.

Para trabajar con muestras con decenas o cientos de dimensiones nos conviene utilizar una librería como PyOd que realiza muy bien su trabajo!

Espero que el artículo haya sido de tu interés! No olvides compartir y para cualquier consulta deja tu comentario!

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente a tus contactos para evitar problemas. Gracias!

Recursos

Descarga la Notebook Ejercicio_Outliers que acompaña este artículo desde mi cuenta de Github

Enlaces de Interés

La libreria pyod anomaly detection 

How to Identify Outliers in your Data

Effective Outlier Detection Techniques in Machine Learning

How to Make Your Machine Learning Models Robust to Outliers

Machine Learning | Outlier

Three methods to deal with outliers

Outlier Detection and Anomaly Detection with Machine Learning

El libro del Blog

Si te gustan los contenidos del blog y quieres darme una mano, puedes comprar el libro en papel, ó en digital.

The post Detección de outliers en Python first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/deteccion-de-outliers-en-python-anomalia/feed/ 1 7216
Sets de Entrenamiento, Test y Validación https://www.aprendemachinelearning.com/sets-de-entrenamiento-test-validacion-cruzada/ https://www.aprendemachinelearning.com/sets-de-entrenamiento-test-validacion-cruzada/#comments Tue, 03 Mar 2020 08:00:00 +0000 https://www.aprendemachinelearning.com/?p=7152 Vamos a comentar las diferencias entre los conjuntos de Entrenamiento, Validación y Test utilizados en Machine Learning ya que suele haber bastante confusión en para qué es cada uno y cómo utilizarlos adecuadamente. Intentaré hacerlo mediante un ejemplo práctico por eso de ser didácticos 🙂...

The post Sets de Entrenamiento, Test y Validación first appeared on Aprende Machine Learning.

]]>
Vamos a comentar las diferencias entre los conjuntos de Entrenamiento, Validación y Test utilizados en Machine Learning ya que suele haber bastante confusión en para qué es cada uno y cómo utilizarlos adecuadamente.

Intentaré hacerlo mediante un ejemplo práctico por eso de ser didácticos 🙂

Además veremos que tenemos distintas técnicas de hacer la validación del modelo y aplicarlas con Scikit Learn en Python.

Un nuevo Mundo

Al principio de los tiempos, sólo tenemos un conjunto Pangea que contiene todo nuestro dato disponible. Digamos que tenemos un archivo csv con 10.000 registros.

Para entrenar nuestro modelo de Machine Learning y poder saber si está funcionando bien, alguien dijo: Separemos el conjunto de datos inicial en 2: conjunto de entrenamiento (train) y conjunto de Pruebas (test). Por lo general se divide haciendo “80-20”. Y se toman muestras aleatorias -no en secuencia, si no, mezclado.

Para hacer el ejemplo sencillo, supongamos que queremos hacer clasificación usando un algoritmo supervisado, con lo cual tendremos:

  • X_train con 8.000 registros para entrenar
  • y_train con las “etiquetas” de los resultados esperados de X_train
  • X_test con 2.000 registros para test
  • y_test con las “etiquetas” de los resultados de X_test

Hágase el conjunto de Test

Lo interesante y a destacar de esto es que una vez los separamos en 8.000 registros para entrenar y 2.000 para probar, usaremos sólo esos 8.000 registros para alimentar al modelo al entrenarlo haciendo:

modelo.fit(X_train, y_train)

Luego de entrenar nuestro modelo y habiendo decidido como métrica de negocio el Accuracy (el % de aciertos) obtenemos un 75% sobre el set de entrenamiento (y asumimos que ese porcentaje nos sirve para nuestro objetivo de negocio).

Los 2.000 registros que separamos en X_test aún nunca han pasado por el modelo de ML. ¿Se entiende esto? porque eso es muy importante!!! Cuando usemos el set de test, haremos:

modelo.predict(X_test)

Como verás, no estamos usando fit()!!! sólo pasaremos los datos sin la columna de “y_test” que contiene las etiquetas. Además remarco que estamos haciendo predicción; me refiero a que el modelo NO se está entrenando ni <<incorporando conocimiento>>. El modelo se limita a “ver la entrada y escupir una salida”.

Cuando hacemos el predict() sobre el conjunto de test y obtenemos las predicciones, las podemos comprobar y contrastar con los valores reales almacenados en y_test y hallar así la métrica que usamos. Los resultados que nos puede dar serán:

  1. Si el accuracy en Test es <<cercano>> al de Entrenamiento (dijimos 75%) por ejemplo en este caso si estuviera entre 65 ú 85% quiere decir que nuestro modelo entrenado está generalizando bien y lo podemos dar por bueno (siempre y cuando estemos conformes con las métricas obtenidas).
  2. Si el Accuracy en Test es muy distinto al de Entrenamiento tanto por encima como por debajo, nos da un 99% ó un 25% (lejano al 75%) entonces es un indicador de que nuestro modelo no ha entrenado bien y no nos sirve. De hecho este podría ser un indicador de Overfitting.

Para evaluar mejor el segundo caso, es donde aparece el “conjunto de Validación”.

Al Séptimo día Dios creo el Cross-Validation

Si el conjunto de Train y Test nos está dando métricas muy distintas esto es que el modelo no nos sirve.

Para mejorar el modelo, podemos pensar en Tunear sus parámetros y volver a entrenar y probar, podemos intentar obtener más registros, cambiar el preprocesado de datos, limpieza, balanceo de clases, selección de features, generación de features… De hecho, podemos pensar que seleccionamos un mal modelo, y podemos intentar con distintos modelos: de árbol de decisión, redes neuronales, ensambles

La técnica de Validación Cruzada nos ayudará a medir el comportamiento el/los modelos que creamos y nos ayudará a encontrar un mejor modelo rápidamente.

Aclaremos antes de empezar: hasta ahora contamos con 2 conjuntos: el de Train y Test. El “set de validación” no es realmente un tercer set si no que “vive” dentro del conjunto de Train. Reitero: el set de validación no es un conjunto que apartemos de nuestro archivo csv original. El set de validación se utilizará durante iteraciones que haremos con el conjunto de entrenamiento.

Técnicas de Validación Cruzada

Entonces volvamos a tener las cosas claras: SOLO tenemos conjunto de Train y Test, ok?. El de Test seguirá tratándose como antes: lo apartamos y lo usaremos al final, una vez entrenemos el modelo.

Dentro del conjunto de Train, y siguiendo nuestro ejemplo inicial, tenemos 8.000 registros. La validación más común utilizada y que nos sirve para entender el concepto es “K-folds”, vamos a comentarla:

Cross-Validation: K-fold con 5 splits

Lo que hacemos normalmente al entrenar el modelo es pasarle los 8.000 registros y que haga el fit(). Con K-Folds -en este ejemplo de 5 splits- para entrenar, en vez de pasarle todos los registros directamente al modelo, haremos así:

  • Iterar 5 veces:
    1. Apartaremos 1/5 de muestras, es decir 1600.
    2. Entrenamos al modelo con el restante 4/5 de muestras = 6400.
    3. Mediremos el accuracy obtenido sobre las 1600 que habíamos apartado.
  • Esto quiere decir que hacemos 5 entrenamientos independientes.
  • El Accuracy final será el promedio de las 5 accuracies anteriores.
En amarillo las muestras para entrenar y en verde el conjunto de Validación.

Entonces fijémonos que estamos “ocultando” una quinta parte del conjunto de train durante cada iteración. Esto es similar a lo que explique antes, pero esta vez aplicado al momento de entrenamiento. Al cabo de esas 5 iteraciones, obtenemos 5 accuracies que deberían ser “similares” entre sí, esto sería un indicador de que el modelo está funcionando bien.

Ejemplo K-Folds en Python

Veamos en código python usando la librería de data science scikit-learn como podemos hacer el cross-validation con K-Folds:

from sklearn import datasets, metrics
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression

iris = datasets.load_iris()

X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=0)

kf = KFold(n_splits=5)

clf = LogisticRegression()

clf.fit(X_train, y_train)

score = clf.score(X_train,y_train)

print("Metrica del modelo", score)

scores = cross_val_score(clf, X_train, y_train, cv=kf, scoring="accuracy")

print("Metricas cross_validation", scores)

print("Media de cross_validation", scores.mean())

preds = clf.predict(X_test)

score_pred = metrics.accuracy_score(y_test, preds)

print("Metrica en Test", score_pred)

En el ejemplo vemos los pasos descritos anteriormente:

  • Cargar el dataset
  • Dividir en Train y Test (en 80/20)
  • Creamos un modelo de Regresión Logística (podría ser otro) y lo entrenamos con los datos de Train
  • Hacemos Cross-Validation usando K-folds con 5 splits
  • Comparamos los resultados obtenidos en el modelo inicial, en el cross validation y vemos que son similares.
  • Finalmente hacemos predict sobre el Conjunto de Test y veremos que también obtenemos buen Accuracy

Más técnicas para Validación del modelo

Otras técnicas usadas y que nos provee sklearn para python son:

Stratified K-Fold

Statified K-fold es una variante mejorada de K-fold, que cuando hace los splits (las divisiones) del conjunto de train tiene en cuenta mantener equilibradas las clases. Esto es muy útil, porque imaginen que tenemos que clasificar en “SI/NO” y si una de las iteraciones del K-fold normal tuviera muestras con etiquetas sólo “SI” el modelo no podría aprender a generalizar y aprenderá para cualquier input a responder “SI”. Esto lo soluciona el Stratified K-fold.

Leave P Out

Leave P Out selecciona una cantidad P por ejemplo 100. Entonces se separarán de a 100 muestras contra las cuales validar y se iterará como se explico anteriormente. Si el valor P es pequeño, esto resultará en muchísimas iteraciones de entrenamiento con un alto coste computacional (y seguramente en tiempo). Si el valor P es muy grande, podría contener más muestras que las usadas para entrenamiento, lo cual sería absurdo. Usar esta técnica con algo de sentido común y manteniendo un equilibrio entre los scores y el tiempo de entreno.

ShuffleSplit

ShuffleSplit primero mezcla los datos y nos deja indicar la cantidad de splits (divisiones) es decir las iteraciones independientes que haremos y también indicar el tamaño del set de validación.

Instala tu ambiente de Desarrollo Python siguiendo esta guía paso a paso

Series Temporales: Atención al validar

Para problemas de Series temporales tenemos que prestar especial cuidado con los datos. Pues si pasamos al modelo “dato futuro” antes de tiempo estaríamos haciendo Data Leakage, esto es como si le hiciéramos spoiler al modelo y le contaremos el final de la película antes de que la vea. Esto causaría overfitting.

Para empezar al hacer el split inicial de datos estos deberán estar ordenados por fecha y no podemos mezclarlos.

Para ayudarnos con el cross-validation sklearn nos provee de TimeSeriesSplit.

TimeSeriesSplit

TimeSeriesSplit es una variante adaptada de K-folds que evita “la fuga” de datos. Para hacerlo va iterando los “folds” de a uno (usando una ventana de tiempo que se desplaza) y usando el “fold más reciente” cómo el set de validación. Se puede entender mejor viendo una animación:

En Amarillo las muestras para entrenar y en verde el conjunto de Validación.

Practicar con un ejercicio en Python de Series Temporales!

Pero entonces? Cuando uso Cross-Validation?

Es una buena práctica usar cross-validation en nuestros proyectos. De hecho usarlo nos ayudará a elegir el modelo correcto y nos da mayor seguridad y respaldo ante nuestra decisión.

PERO… (siempre hay un pero)

En casos en los que hacer 1 sólo entrenamiento “normal” tome muchísimo tiempo y recursos, podría ser nuestra perdición. Imaginen que hacer un k-folds de 10 implica hacer 10 entrenos -aunque un poco más pequeños-, pero que consumirían mucho tiempo y dinero.

Entonces en la medida de lo posible siempre usar validación cruzada. Y -vuelvo a reforzar el concepto- luego se probará el modelo contra el conjunto de Pruebas (test).

Para hacer tuneo de Hiper-parámetros como RandomSearch, GridSearch ó Tuneo Bayesiano es muy útil hacer Cross-Validation.

¿Si ya estoy “conforme” y quiero llevar el modelo a un entorno de Producción?

Supongamos que el entrenamiento haciendo Cross Validation y el predict() en Test nos están dando buenos accuracy (y similares) y estamos conformes con nuestro modelo. PUES si lo queremos usar en un entorno REAL y productivo, ANTES de publicarlo es recomendado que agreguemos el conjunto de test al modelo!!!, pues así estaremos aprovechando el 100% de nuestros datos. Espero que esto último también se entienda porque es super importante: lo que estoy diciendo es que si al final de todas nuestras iteraciones, pre procesado de dato, mejoras de modelo, ajuste de hiper-parámetros y comparando con el conjunto de test, estamos seguros que el modelo funciona correctamente, es entonces ahora, que usaremos las 10.000 muestras para entrenar al modelo, y ese modelo final, será el que publicamos en producción.

Es una última iteración que debería mejorar el modelo final aunque este no lo podemos contrastar contra nada… excepto con su comportamiento en el entorno real.

Si esta última iteración te causara dudas, no la hagas, excepto que tu problema sea de tipo Serie Temporal. En ese caso sí que es muy importante hacerlo o quedaremos con un modelo que no “es el más actual”.

Resumen, Conclusiones y por favor Que quede claro!

Lo más importante que quisiera que quede claro es que entonces tenemos 2 conjuntos: uno de Train y otro de Test. El “conjunto de validación” no existe como tal, si no, que “vive temporalmente” al momento de entrenar y nos ayuda a obtener al mejor modelo de entre los distintos que probaremos para conseguir nuestro objetivo. Esa técnica es lo que se llama Validación Cruzada ó en inglés cross-validation.

NOTA: en los ejemplos de la documentación de sklearn podremos ver que usan las palabras train y test. Pero conceptualmente se está refiriendo al conjunto de validación y no al de Test que usaremos al final. Esto es en parte el causante de tanta confusión con este tema.

Tener en cuenta el tamaño de split 80/20 es el usual pero puede ser distinto, y esta proporción puede cambiar sustancialmente las métricas obtenidas del modelo entrenado! Ojo con eso. El tamaño ideal dependerá del dominio de nuestro problema, deberemos pensar en una cantidad de muestras para test que nos aseguren que estamos el modelo creado está funcionando correctamente. Teniendo 10.000 registros puede que con testear 1000 filas ya estemos conformes ó que necesitemos 4000 para estar mega-seguros. Por supuesto debemos recordar que las filas que estemos “quitando” para testear, no las estamos usando al entrenar.

Otro factor: al hacer el experimento y tomar las muestras mezcladas, mantener la “semilla” ó no podremos reproducir el mismo experimento para comparar y ver si mejora o no. Este suele ser un parámetro llamado “random_state” y está bien que lo usemos para fijarlo.

Recomendaciones finales:

  • En principio separar Train y Test en una proporción de 80/20
  • Hacer Cross Validation siempre que podamos:
    • No usar K-folds. Usar Stratified-K-folds en su lugar.
    • La cantidad de “folds” dependerá del tamaño del dataset que tengamos, pero la cantidad usual es 5 (pues es similar al 80-20 que hacemos con train/test).
    • Para problemas de tipo time-series usar TimeSeriesSplit
  • Si el Accuracy (ó métrica que usamos) es similar en los conjuntos de Train (donde hicimos Cross Validation) y Test, podemos dar por bueno al modelo.

Recibe los artículos del Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente a tus contactos para evitar problemas. Gracias!

Recursos Adicionales

Otros artículos interesantes en inglés:

El libro del Blog

Si te gustan los contenidos del blog y quieres darme una mano, puedes comprar el libro en papel, ó en digital.

The post Sets de Entrenamiento, Test y Validación first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/sets-de-entrenamiento-test-validacion-cruzada/feed/ 7 7152
Análisis Exploratorio de Datos con Pandas en Python https://www.aprendemachinelearning.com/analisis-exploratorio-de-datos-pandas-python/ https://www.aprendemachinelearning.com/analisis-exploratorio-de-datos-pandas-python/#comments Thu, 12 Dec 2019 12:55:00 +0000 https://www.aprendemachinelearning.com/?p=7074 Veremos de qué se trata este paso inicial tan importante y necesario para comenzar un proyecto de Machine Learning. Aprendamos en qué consiste el EDA y qué técnicas utilizar. Veamos un ejemplo práctico y la manipulación de datos con Python utilizando la librería Pandas para...

The post Análisis Exploratorio de Datos con Pandas en Python first appeared on Aprende Machine Learning.

]]>
Veremos de qué se trata este paso inicial tan importante y necesario para comenzar un proyecto de Machine Learning. Aprendamos en qué consiste el EDA y qué técnicas utilizar. Veamos un ejemplo práctico y la manipulación de datos con Python utilizando la librería Pandas para analizar y Visualizar la información en pocos minutos.

Como siempre, podrás descargar todo el código de la Jupyter Notebook desde mi cuenta de Github (que contiene información extra). Y como BONUS encuentra una notebook con las funciones más útiles de Pandas!

¿Qué es el EDA?

Eda es la sigla en inglés para Exploratory Data Analysis y consiste en una de las primeras tareas que tiene que desempeñar el Científico de Datos. Es cuando revisamos por primera vez los datos que nos llegan, por ejemplo un archivo CSV que nos entregan y deberemos intentar comprender “¿de qué se trata?”, vislumbrar posibles patrones y reconociendo distribuciones estadísticas que puedan ser útiles en el futuro.

OJO!, lo ideal es que tengamos un objetivo que nos hayan “adjuntado” con los datos, que indique lo que se quiere conseguir a partir de esos datos. Por ejemplo, nos pasan un excel y nos dicen “Queremos predecir ventas a 30 días”, ó Clasificar casos malignos/benignos de una enfermedad”, “Queremos identificar audiencias que van a realizar re-compra de un producto”, “queremos hacer pronóstico de fidelización de clientes/abandonos”, “Quiero detectar casos de fraude en mi sistema en tiempo real”.

EDA deconstruido

Al llegar un archivo, lo primero que deberíamos hacer es intentar responder:

  • ¿Cuántos registros hay?
    • ¿Son demasiado pocos?
    • ¿Son muchos y no tenemos Capacidad (CPU+RAM) suficiente para procesarlo?
  • ¿Están todas las filas completas ó tenemos campos con valores nulos?
    • En caso que haya demasiados nulos: ¿Queda el resto de información inútil?
  • ¿Que datos son discretos y cuales continuos?
    • Muchas veces sirve obtener el tipo de datos: texto, int, double, float
  • Si es un problema de tipo supervisado:
    • ¿Cuál es la columna de “salida”? ¿binaria, multiclase?
    • ¿Esta balanceado el conjunto salida?
  • ¿Cuales parecen ser features importantes? ¿Cuales podemos descartar?
  • ¿Siguen alguna distribución?
  • ¿Hay correlación entre features (características)?
  • En problemas de NLP es frecuente que existan categorías repetidas ó mal tipeadas, ó con mayusculas/minúsculas, singular y plural, por ejemplo “Abogado” y “Abogadas”, “avogado” pertenecerían todos a un mismo conjunto.
  • ¿Estamos ante un problema dependiente del tiempo? Es decir un TimeSeries.
  • Si fuera un problema de Visión Artificial: ¿Tenemos suficientes muestras de cada clase y variedad, para poder hacer generalizar un modelo de Machine Learning?
  • ¿Cuales son los Outliers? (unos pocos datos aislados que difieren drásticamente del resto y “contaminan” ó desvían las distribuciones)
    • Podemos eliminarlos? es importante conservarlos?
    • son errores de carga o son reales?
  • ¿Tenemos posible sesgo de datos? (por ejemplo perjudicar a clases minoritarias por no incluirlas y que el modelo de ML discrimine)

Puede ocurrir que tengamos set de datos incompletos y debamos pedir a nuestro cliente/proveedor ó interesado que nos brinde mayor información de los campos, que aporte más conocimiento ó que corrija campos.

¿Qué son los conjuntos de Train, Test y Validación en Machine Learning?

También puede que nos pasen múltiples fuentes de datos, por ejemplo un csv, un excel y el acceso a una base de datos. Entonces tendremos que hacer un paso previo de unificación de datos.

¿Qué sacamos del EDA?

El EDA será entonces una primer aproximación a los datos, ATENCIóN, si estamos mas o menos bien preparados y suponiendo una muestra de datos “suficiente”, puede que en “unas horas” tengamos ya varias conclusiones como por ejemplo:

  • Esto que quiere hacer el cliente CON ESTOS DATOS es una locura imposible! (esto ocurre la mayoría de las veces jeje)
  • No tenemos datos suficientes ó son de muy mala calidad, pedir más al cliente.
  • Un modelo de tipo Arbol es lo más recomendado usar
    • (reemplazar Arbol, por el tipo de modelo que hayamos descubierto como mejor opción!)
  • No hace falta usar Machine Learning para resolver lo que pide el cliente. (ESTO ES MUY IMPORTANTE!)
  • Es todo tan aleatorio que no habrá manera de detectar patrones
  • Hay datos suficientes y de buena calidad como para seguir a la próxima etapa.

A estas alturas podemos saber si nos están pidiendo algo viable ó si necesitamos más datos para comenzar.

Repito por si no quedó claro: el EDA debe tomar horas, ó puede que un día, pero la idea es poder sacar algunas conclusiones rápidas para contestar al cliente si podemos seguir o no con su propuesta.

Luego del EDA, suponiendo que seguimos adelante podemos tomarnos más tiempo y analizar en mayor detalle los datos y avanzar a nuevas etapas para aplicar modelos de Machine Learning.

Técnicas para EDA

Vamos a lo práctico!, ¿Que herramientas tenemos hoy en día? La verdad es que como cada conjunto de datos suele ser único, el EDA se hace bastante “a mano”, pero podemos seguir diversos pasos ordenados para intentar acercarnos a ese objetivo que nos pasa el cliente en pocas horas.

A nivel programación y como venimos utilizando Python, encontramos a la conocida librería Pandas, que nos ayudará a manipular datos, leer y transformarlos.

Instala el ambiente de desarrollo Python en tu ordenador siguiendo esta guía

Otra de las técnicas que más nos ayudaran en el EDA es visualización de datos (que también podemos hacer con Pandas).

Finalmente podemos decir que nuestra Intuición -basada en Experiencia previa, no en corazonadas- y nuestro conocimiento de casos similares también nos pueden aportar pistas para saber si estamos ante datos de buena calidad. Por ejemplo si alguien quiere hacer reconocimiento de imágenes de tornillos y tiene 25 imágenes y con muy mala resolución podremos decir que no tenemos muestras suficientes -dado nuestro conocimiento previo de este campo-.

Vamos a la práctica!

Un EDA de pocos minutos con Pandas (Python)

Vamos a hacer un ejemplo en pandas de un EDA bastante sencillo pero con fines educativos.

Vamos a leer un csv directamente desde una URL de GitHub que contiene información geográfica básica de los países del mundo y vamos a jugar un poco con esos datos.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

url = 'https://raw.githubusercontent.com/lorey/list-of-countries/master/csv/countries.csv'
df = pd.read_csv(url, sep=";")
print(df.head(5))

Veamos los datos básicos que nos brinda pandas:
Nombre de columnas

print('Cantidad de Filas y columnas:',df.shape)
print('Nombre columnas:',df.columns)

Columnas, nulos y tipo de datos

df.info()
En esta salida vemos las columnas, el total de filas y la cantidad de filas sin nulos. También los tipos de datos.

descripción estadística de los datos numéricos

df.describe()
Pandas filtra las features numéricas y calcula datos estadísticos que pueden ser útiles: cantidad, media, desvío estándar, valores máximo y mínimo.

Verifiquemos si hay correlación entre los datos

corr = df.set_index('alpha_3').corr()
sm.graphics.plot_corr(corr, xnames=list(corr.columns))
plt.show()
En este caso vemos baja correlación entre las variables. Dependiendo del algoritmo que utilicemos podría ser una buena decisión eliminar features que tuvieran alta correlación

Cargamos un segundo archivo csv para ahondar en el crecimiento de la población en los últimos años, filtramos a España y visualizamos

url = 'https://raw.githubusercontent.com/DrueStaples/Population_Growth/master/countries.csv'
df_pop = pd.read_csv(url)
print(df_pop.head(5))
df_pop_es = df_pop[df_pop["country"] == 'Spain' ]
print(df_pop_es.head())
df_pop_es.drop(['country'],axis=1)['population'].plot(kind='bar')
Crecimiento de la Población de España. El eje x no está establecido y aparece un id de fila.

Hagamos la comparativa con otro país, por ejemplo con el crecimiento poblacional en Argentina

df_pop_ar = df_pop[(df_pop["country"] == 'Argentina')]

anios = df_pop_es['year'].unique()
pop_ar = df_pop_ar['population'].values
pop_es = df_pop_es['population'].values

df_plot = pd.DataFrame({'Argentina': pop_ar,
                    'Spain': pop_es}, 
                       index=anios)
df_plot.plot(kind='bar')
Gráfica comparativa de crecimiento poblacional entre España y Argentina entre los años 1952 al 2007

Ahora filtremos todos los paises hispano-hablantes

df_espanol = df.replace(np.nan, '', regex=True)
df_espanol = df_espanol[ df_espanol['languages'].str.contains('es') ]
df_espanol

Visualizamos…

df_espanol.set_index('alpha_3')[['population','area']].plot(kind='bar',rot=65,figsize=(20,10))

Vamos a hacer detección de Outliers, (con fines educativos) en este caso definimos como limite superior (e inferior) la media más (menos) “2 veces la desviación estándar” que muchas veces es tomada como máximos de tolerancia.

anomalies = []

# Funcion ejemplo para detección de outliers
def find_anomalies(data):
    # Set upper and lower limit to 2 standard deviation
    data_std = data.std()
    data_mean = data.mean()
    anomaly_cut_off = data_std * 2
    lower_limit  = data_mean - anomaly_cut_off 
    upper_limit = data_mean + anomaly_cut_off
    print(lower_limit.iloc[0])
    print(upper_limit.iloc[0])

    # Generate outliers
    for index, row in data.iterrows():
        outlier = row # # obtener primer columna
        # print(outlier)
        if (outlier.iloc[0] > upper_limit.iloc[0]) or (outlier.iloc[0] < lower_limit.iloc[0]):
            anomalies.append(index)
    return anomalies

find_anomalies(df_espanol.set_index('alpha_3')[['population']])

Detectamos como outliers a Brasil y a USA. Los eliminamos y graficamos ordenado por población de menor a mayor.

# Quitemos BRA y USA por ser outlies y volvamos a graficar:
df_espanol.drop([30,233], inplace=True)
df_espanol.set_index('alpha_3')[['population','area']].sort_values(["population"]).plot(kind='bar',rot=65,figsize=(20,10))
Así queda nuestra gráfica sin outliers 🙂

En pocos minutos hemos podido responder: cuántos datos tenemos, si hay nulos, los tipos de datos (entero, float, string), la correlación, hicimos visualizaciones, comparativas, manipulación de datos, detección de ouliers y volver a graficar. ¿No está nada mal, no?

Más cosas! que se suelen hacer:

Otras pruebas y gráficas que se suelen hacer son:

  • Si hay datos categóricos, agruparlos, contabilizarlos y ver su relación con las clases de salida
  • gráficas de distribución en el tiempo, por ejemplo si tuviéramos ventas, para tener una primera impresión sobre su estacionalidad.
  • Rankings del tipo “10 productos más vendidos” ó “10 ítems con más referencias por usuario”.
  • Calcular importancia de Features y descartar las menos útiles.

Conclusiones

En el artículo vimos un repaso sobre qué es y cómo lograr hacer un Análisis Exploratorio de Datos en pocos minutos. Su importancia es sobre todo la de darnos un vistazo sobre la calidad de datos que tenemos y hasta puede determinar la continuidad o no de un proyecto.

Siempre dependerá de los datos que tengamos, en cantidad y calidad y por supuesto nunca deberemos dejar de tener en vista EL OBJETIVO, el propósito que buscamos lograr. Siempre debemos apuntar a lograr eso con nuestras acciones.

Como resultado del EDA si determinamos continuar, pasaremos a una etapa en la que ya preprocesaremos los datos pensando en la entrada a un modelo (ó modelos!) de Machine Learning.

La detección de Outliers podría comentarse en un artículo completo sobre el tema… YA salió!

¿Conocías el EDA? ¿Lo utilizas en tu trabajo? Espero tus comentarios!

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo.

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente a tus contactos para evitar problemas. Gracias!

Recursos

Como siempre, puedes descargar la notebook relacionada con este artículo desde aquí:

BONUS track: Notebook sobre manipulación de datos con Pandas

Como Bonus…. te dejo una notebook con los Casos más comunes de uso de Manipulación de datos con Pandas!

Artículos Relacionados

Estos son otros artículos relacionados que pueden ser de tu interés:

The post Análisis Exploratorio de Datos con Pandas en Python first appeared on Aprende Machine Learning.

]]>
https://www.aprendemachinelearning.com/analisis-exploratorio-de-datos-pandas-python/feed/ 14 7074