scieee AI-readable full text Open interactive document viewer

Future Vision: Aplicación web y servicio REST para la gestión de la red de visión artificial YOLOv7 usando Django, PostgreSQL, React y Docker

Ossorio Romero, Reyes

Abstract

Este proyecto se enfoca en la creación de un servicio llamado Future Vision, diseñado para permitir a los usuarios visualizar conjuntos de imágenes y realizar entrenamientos con el modelo YOLOv7 utilizando su hardware local. Adentrarse en el mundo de la visión por computadora puede resultar abrumador, por los que este proyecto busca ayudar a particulares y empresas que deseen iniciarse en este campo comenzando con redes y datos básicos. Para desarrollar esta idea se han implementado tres componentes:  Future Vision: Proporciona la interfaz de usuario. Está diseñado en JavaScript utilizando la librería de React.  Gestor web: Coordina el sistema y maneja las peticiones de la interfaz. Está desarrollado en Python utilizando el paquete de Django.  Motor de entrenamiento: Recibe peticiones de entrenamiento del gestor web y las ejecuta en local utilizando el código de YOLOv7. Además, se utilizan otras tecnologías para completar las características de los módulos anteriores:  Gestor de base de datos PostgreSQL: Mantiene la persistencia de los datos del gestor web.  Nginx: Coordina las peticiones entre la interfaz y el gestor web.  TensorBoard: Presenta estadísticas de los entrenamientos. Cada componente se encapsula en una imagen de Docker y se despliegan de forma conjunta utilizando la herramienta de Docker Compose.

Full text

Trabajo Fin de Grado en Ingeniería de las Tecnologías de Telecomunicación Future Vision: Aplicación web y servicio REST para la gestión de la red de visión artificial YOLOv7 usando Django, PostgreSQL, React y Docker Autora: Reyes Ossorio Romero Tutora: María Teresa Ariza Gómez Dpto. Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 20 24 iii Trabajo Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Future Vision: Aplicación web y servicio REST para la gestión de la red de visión artificial YOLOv7 usando Django, PostgreSQL, React y Docker Autora: Reyes Ossorio Romero Tutora: María Teresa Ariza Gómez Profesora titular Dpto. de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024 v Trabajo Fin de Grado: Future Vision: Aplicación web y servicio REST para la gestión de la red de visión artificial YOLOv7 usando Django, PostgreSQL, React y Docker Autora: Reyes Ossorio Romero Tutora: María Teresa Ariza Gómez El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2024 El Secretario del Tribunal vii A Bea ix Agradecimientos Quiero comenzar agradeciendo a mi tutora, Teresa, por su invaluable apoyo y orientación a lo largo de este trabajo. Asimismo, quiero expresar mi gratitud a todos mis profesores a lo largo de los años, quienes no solo me brindaron conocimientos, sino también herramientas valiosas para enfrentar los desafíos con pensamiento crítico y creatividad. Desde los primeros años de mi formación hasta este punto final, su esfuerzo y compromiso han sido fundamentales en mi desarrollo personal y profesional, y estoy profundamente agradecida por todo lo que me han enseñado. A mi familia y amigos, les agradezco profundamente por estar siempre presentes. Su apoyo, ya sea en los momentos de estudio o en los de descanso, ha sido esencial para que pudiera llegar hasta aquí. Este logro no habría sido posible sin vosotros a mi lado, brindándome ánimo y compañía a lo largo de todo el camino. Por último, agradezco a Bea por estar a mi lado y escucharme hablar eternamente sobre cosas que no entiende. Sin nuestros paseos y momentos de distracción, este trabajo no habría sido posible. Gracias por tu apoyo incondicional. xvii ÍNDICE DE TABLAS Tabla 1: Parámetros del comando de entrenamiento 51 Tabla 2: Parámetros del archivo de entorno 57 xix ÍNDICE DE FIGURAS Figura 1: Productos de Roboflow 3 Figura 2: Detección de objetos con cajas delimitadoras 7 Figura 3: Estimación de pose 7 Figura 4: Detección de objetos con cajas delimitadoras y máscaras de segmentación 8 Figura 5: Imagen etiquetada con cajas delimitadoras en formato YOLO (21) 8 Figura 6: Formato de etiquetas de cajas delimitadoras en formato YOLO (21) 9 Figura 7: Arquitectura de Docker 13 Figura 8: Esquema de componentes 17 Figura 9: Esquema de datos relacional 18 Figura 10: Tablas relacionadas con la autenticación y permisos 19 Figura 11: Tablas relacionadas con la gestión de datasets y los tokens JWT 20 Figura 12: Tablas relacionadas con la aplicación projects 21 Figura 13: Datos almacenados en la tabla content_type 22 Figura 14: Estructura de directorios multimedia 23 Figura 15: Clave secreta de la configuración de Django 24 Figura 16: Parámetro ALLOWED_HOST de la configuración de Django 24 Figura 17: Parámetro INSTALLED_APPS de la configuración de Django 25 Figura 18: Parámetro REST_FRAMEWORK de la configuración de Django 25 Figura 19: Parámetro SIMPLE_JWT de la configuración de Django 26 Figura 20: Parámetro CORS_ALLOWED_ORIGINS de la configuración de Django 27 Figura 21: Parámetro CORS_ALLOW_METHODS de la configuración de Django 27 Figura 22: Parámetro MIDDLEWARE de la configuración de Django 27 Figura 23: Archivo de configuración de URLs 28 Figura 24: Parámetro DATABASES de la configuración de Django 28 Figura 25: Parámetros de archivos multimedia de la configuración de Django 28 Figura 26: Parámetro LOGGING de la configuración de Django 29 Figura 27: Campos de la tabla auth_user 30 Figura 28: Valores insertados en la tabla auth_group 30 Figura 29: Campos de la tabla auth_user_groups 31 Figura 30: Campos de permisos sobre usuarios en la tabla auth_permisions 31 Figura 31: Permisos insertados en la tabla auth_group_permisions 31 Figura 32: Campos de la tabla token_blacklist_outstandingtoken 32 Figura 33: Campos de la tabla token_blacklist_blacklistedtoken 32 Figura 34: Endpoints de la aplicación de autenticación 33 Figura 35: Formato de carpetas para un dataset en formato Yolo sin subcategorías 34 Figura 36: Formato de carpetas para un dataset en formato Yolo con subcategorías 34 Figura 37: Formato de carpetas para un dataset en formato COCO sin subcategorías 34 Figura 38: Formato de carpetas para un dataset en formato COCO con subcategorías 35 Figura 39: Archivo de comprobación de estructura para Yolo con subcarpetas 35 Figura 40: Funciones para la verificación de directorios 36 Figura 41: Modelo Datasets 37 Figura 42: Serializador del modelo datasets 38 Figura 43: Endpoints de la aplicación datasets 38 Figura 44: Clase YoloData 39 Figura 45: Clase CocoData 40 Figura 46: Etiquetado de imágenes en formato Yolo 41 Figura 47: Cuerpo de petición de creación de subcategorías 42 Figura 48: Modelo Projects 43 Figura 49: Serializador de datos del modelo Projects 43 Figura 50: Modelo Training 44 Figura 51: Serializador de datos del modelo Training 44 Figura 52: Endpoints de la aplicación de proyectos 45 Figura 53: Vista para la creación de proyectos 45 Figura 54: Datos obtenidos del cuerpo de una petición de entrenamiento 46 Figura 55: Vista notify del gestor web 46 Figura 56: Vistas para descargar el log y los pesos de un entrenamiento 47 Figura 57: Archivo dockerfile utilizado para construir la imagen del gestor web 48 Figura 58: Cuerpo de la petición al motor de entrenamiento 50 Figura 59: Objeto que representa una sesión de entrenamiento 50 Figura 60: Creación y ejecución del fichero de entrenamiento de YOLOv7 52 Figura 61: Fichero dockerfile utilizado para construir la imagen del motor de entrenamiento 53 Figura 62: Fichero dockerfile utilizado para construir la imagen de Future Vision 54 Figura 63: Fichero de configuración de Nginx 56 Figura 64: Apartado del gestor web en el fichero Docker Compose 58 Figura 65: Fichero de inicio del gestor web 59 Figura 66: Apartado del motor de entrenamiento en el fichero Docker Compose 59 Figura 67: Fichero de inicio del motor de entrenamiento 60 Figura 68: Apartado de Future Vision en el fichero Docker Compose 60 Figura 69: Apartado de TensorBoard en el fichero Docker Compose 61 Figura 70: Apartado de la base de datos en el fichero Docker Compose 61 xxi Figura 71: Apartado de Nginx en el fichero Docker Compose 62 Figura 72: Página de inicio de sesión 63 Figura 73: Página de registro de usuarios 64 Figura 74: Página datasets sin datos guardados 65 Figura 75: Panel navegación desplegable de la barra superior 65 Figura 76: Botón de cierre de sesión de la barra superior 66 Figura 77: Panel de subida de conjuntos de datos 66 Figura 78: Página de datasets con datos cargados 67 Figura 79: Página de un dataset sin subconjuntos en formato Yolo 67 Figura 80: Página de un dataset con subconjuntos en formato Yolo y opción de etiqueta activa 68 Figura 81: Imagen de un dataset en formato COCO con etiquetas 68 Figura 82: Centro de control de paginación de imágenes dentro de un conjunto de datos 69 Figura 83: Cuadro de borrado de un conjunto de datos 69 Figura 84: Cuadro de modificación de un conjunto de datos 69 Figura 85: Cuadro de creación de subconjuntos de un conjunto de datos 70 Figura 86: Cuadro de guardado de cambios de un conjunto de datos 70 Figura 87: Página projects sin datos creados 71 Figura 88: Cuadro de creación de un nuevo proyecto 71 Figura 89: Página projects con datos creados 72 Figura 90: Página trainings sin datos creados 72 Figura 91: Cuadro de eliminación de un proyecto 73 Figura 92: Cuadro de creación de un nuevo entrenamiento 73 Figura 93: Pagina trainings con datos de un entrenamiento en proceso 74 Figura 94: Datos de entrenamiento en tiempo real de TensorBoard 74 Figura 95: Página trainings con datos de un entrenamiento finalizado 75 Figura 96: Fichero de log descargado de un entrenamiento 75 Figura 97: Contenido del fichero zip de pesos descargado de un entrenamiento 76 Figura 98: Vista de la página profile de un usuario administrador 76 Figura 99: Vista de la página profile de un usuario no administrador 77 Figura 100: Edición de datos del propio usuario 77 Figura 101: Página de agregación de un nuevo usuario 78 Figura 102: Página de vista de la lista de usuarios 78 Figura 103: Modificación del fichero de configuración de APT 80 Figura 104: Versión del driver de Nvidia y Cuda instaladas en el sistema 81 Figura 105: Verificación de la instalación de Docker 82 Figura 106: Comprobación de detección de tarjeta gráfica dentro de un contenedor de Docker 83 1 1 INTRODUCCIÓN El avance de los sistemas de inteligencia artificial y visión por computadora es cada vez más evidente en el mundo actual, con su integración en una amplia gama de tareas diarias como el control de vehículos, la seguridad del hogar y la asistencia lingüística. Este sector está experimentando un crecimiento exponencial con innovaciones y mejoras constantes. Para los técnicos y profesionales, es fundamental contar con una base sólida de conocimientos y herramientas que permitan aprender y aplicar estas tecnologías de manera efectiva. Este trabajo tiene como objetivo proporcionar una plataforma que sirva como punto de partida para individuos y empresas que deseen formarse en el campo de la visión por computadora. La plataforma facilita el proceso de aprendizaje al eliminar la necesidad de organizar manualmente los conjuntos de datos, así como de planificar entrenamientos y visualizar logs y gráficos, permitiendo a los usuarios centrarse en el análisis de los puntos finales. Estos datos se pueden compartir entre personas de una misma organización con un control de usuarios centralizado. Diseñada para funcionar de manera local, esta plataforma evita los costos y las complejidades asociadas con la computación en la nube. Además, otorga al usuario pleno control sobre sus datos y resultados, permitiéndole disponer de ellos para futuros proyectos según sus necesidades. 1.1 Motivación La motivación para desarrollar esta aplicación surge de una serie de problemas que observé trabajando en una empresa que se dedicaba a la realización de proyectos I+D basados en visión por computadora. Dentro de esta empresa se contaba con ordenadores personales y un servidor general, que tenía más potencia para realizar los entrenamientos. A dicho servidor solo se podía acceder mediante la herramienta de SSH para realizar los entrenamientos, aunque para otras tareas comunes de visión artificial si contábamos con unas herramientas locales desplegadas en el servidor con interfaz gráfica. Dentro de la empresa, en ocasiones, había becarios que, al igual que yo al empezar, tenían pocas nociones de cómo realizar entrenamientos o visualizar los datos, y es que con la cantidad de herramientas que existen hoy en día, el mundo de la visión por computadora puede resultar abrumador para las personas que recién se adentren en él. Por ello, tener una interfaz gráfica sencilla y amigable puede ayudar a que la curva de aprendizaje sea menor. Para realizar una actividad que requiere visualización de datos como imágenes y gráficos, resulta casi imposible hacer la mayoría de las tareas desde una terminal y si no se dispone de una conexión a internet rápida, puede resultar tedioso el traspaso de datos entre ordenadores. Asimismo, dentro de una organización es esencial organizar los datos y controlar el acceso, sobre todo cuando se trabaja con grandes cantidades de imágenes que deben de ser mantenidas durante un largo periodo de tiempo. Por ello, el trabajo del administrador se ve facilitado cuando se cuenta con un entorno que automatice y facilite el control de usuarios. Frente a todos estos problemas, me fue evidente la necesidad de contar con un entorno gráfico de organización de datos y entrenamientos sencillo que funcione de forma local, para dejar en manos del administrador y de la empresa la seguridad y disponibilidad de sus datos. 1.2 Objetivos El objetivo principal de este Trabajo de Fin de Grado es crear el inicio de una plataforma que permita mantener conjuntos de datos y entrenamientos usando los recursos del usuario de forma local. La aplicación debe de tener una arquitectura escalable para poder recoger más tecnologías en el futuro. 8 Figura 4: Detección de objetos con cajas delimitadoras y máscaras de segmentación Para que un modelo de visión por ordenador, en este caso YOLOv7, obtenga la salida determinada debe ser entrenado con un conjunto de imágenes que contengan anotaciones del mismo tipo que se desee en la salida. Para ello, los conjuntos de datos deben ser etiquetados. Este es un proceso, típicamente realizado de manera manual, en el que se indica dentro de una imagen donde están los objetos a detectar. En el caso de querer llevar a cabo un entrenamiento de un modelo de YOLO, dichas anotaciones deben de ser pasadas al script de entrenamiento en un formato determinado. Este formato parte de que dentro del conjunto de datos existen dos carpetas de nombres labels y images. Dentro de la primera, se guardarán los archivos de etiquetas y dentro de la segunda los archivos de imágenes. Para poder relacionar el contenido entre ambas carpetas, los archivos deben de tener el mismo nombre, excepto por la extensión. Es decir, si existe una imagen de nombre “0002.png” el archivo que contiene los datos etiquetados para esa imagen tiene el nombre “0002.txt”. Para que el modelo pueda entrenar con cajas delimitadoras, se tienen que indicar dentro del archivo de etiquetado las coordenadas de los objetos a estudiar dentro de las imágenes. Estas coordenadas se indican como x_center, y_center, width, height. X_center y y_center son las coordenadas del centro del objeto y se expresan como una fracción de la altura y la anchura de la imagen, respectivamente. Por ejemplo, un valor x_center de 0.5 significa que el centro del objeto está en la mitad del ancho de la imagen. Width y height son también proporcionales relativas al tamaño de la imagen. Un width de 0.2 significa que el objeto tiene un ancho que es el 20% del ancho total de la imagen. Figura 5: Imagen etiquetada con cajas delimitadoras en formato YOLO (21) 9 De tal forma que, por cada objeto de la imagen que se desee señalar, se tendrá una línea en el archivo correspondiente. En el caso de la imagen anterior, el archivo de anotación sería el siguiente: Figura 6: Formato de etiquetas de cajas delimitadoras en formato YOLO (21) El primer parámetro indica la clase del objeto. En este caso, los primeros dos objetos, señalados en la imagen de color naranja, son de la misma clase mientras que el tercero, señalado de verde, pertenece a otra clase diferente Si además se desea obtener a la salida de la red neuronal máscaras de segmentación, se deben de añadir las anotaciones de estas al etiquetado. Para ello se utiliza el archivo descrito anteriormente y por cada línea se añaden al final de esta las coordenadas normalizadas de los puntos que forman la máscara de segmentación. Estas coordenadas definen la forma del objeto dentro de la imagen con valores entre 0 y 1. Un ejemplo, de una línea de anotación incluyendo las cajas delimitadoras y las máscaras de segmentación es: class_id x_center y_center width height x1, y1, x2, y2, x3,y3, ..., xn,yn Además de esto, para llevar a cabo un proceso de entrenamiento, se deben de ordenar las imágenes en tres grupos: entrenamiento (train), validación (validation, val) y prueba (test). El subconjunto de train se utiliza para entrenar el modelo, es decir, para ajustar los pesos y parámetros del modelo con los datos disponibles. El modelo aprende las relaciones entre las características de entrenamiento y las etiquetas de salida en este conjunto. Durante el proceso de entrenamiento, el conjunto de validación se usa para ajustar hiperparámetros y tomar decisiones sobre el modelo. Evalúa el rendimiento del modelo en datos que no ha visto todavía, ayudando a afinarlo. El subconjunto de prueba se utiliza para evaluar el rendimiento final del modelo después de que todo el entrenamiento y ajuste se haya completado. Proporciona una estimación imparcial de cómo el modelo generaliza a nuevos datos. De esta forma, los datos originales se quedarían divididos en subconjuntos. Como regla general, se usan el 70% de las imágenes totales para el conjunto de entrenamiento, el 20% para el conjunto de validación y el 10% para el conjunto de pruebas. Por último, para entrenar el modelo de YOLOv7 necesitamos un último fichero de tipo YAML que debe de contener la siguiente información:  Train, val, test: campos separados que indican donde se encuentran las imágenes y las etiquetas utilizadas para cada sección durante el entrenamiento.  Nc: número de clases que contiene el dataset.  Names: nombre en orden de las clases del dataset. De esta forma, se terminan de relacionar todos los datos. Por ejemplo, cuando el modelo se encuentra en proceso de entrenamiento y analice la imagen anterior, sabe que tiene 2 objetos del tipo 0, que según la lista de nombre serán de tipo person y un último objeto que será de tipo tie y, además, sabrá las posiciones de cada objeto. 10 YOLOv7, como sus versiones anteriores, viene preentrenado con pesos derivados del conjunto de datos COCO (18). Esto significa que antes de usarlo para tareas específicas, el modelo ya ha aprendido a detectar y clasificar 80 tipos diferentes de objetos, desde personas y animales hasta vehículos y electrodomésticos. Estos pesos preentrenados permiten que el modelo funcione bien en una amplia variedad de escenarios sin necesidad de entrenamiento adicional, aunque pueden ser ajustados más específicamente si se tienen datos y necesidades particulares. Dentro del modelo YOLOv7 (22) nos encontramos con diferentes subtipos que son desarrollados para abordar diferentes requisitos de precisión y eficiencia, adaptándose a diversas aplicaciones y limitaciones de hardware. Entre esos subtipos se encuentran YOLOv7-tiny y YOLOv7-x, cada uno adaptado para equilibrar la precisión y la eficiencia computacional. El primero de ellos está diseñado para funcionar en entornos con recursos físicos limitados, como dispositivos móviles o sistemas embebidos, ofreciendo una reducción significativa en el tamaño del modelo y en los requerimientos computacionales, a expensas de una ligera disminución en la precisión. Por otro lado, YOLOv7-x está optimizado para alcanzar la máxima precisión posible, siendo ideal para situaciones donde los recursos computacionales son abundantes y la precisión es prioritaria. Otras variaciones de YOLOv7, como YOLOv7-X, YOLOv7-E6 y YOLOv7-D6, se obtienen mediante un método de escalado compuesto. Este método ajusta tanto la profundidad (cantidad de capas) como el ancho (número de canales) del modelo para mejorar su capacidad. Al escalar estos aspectos, se incrementa la complejidad del modelo, permitiendo obtener una mayor precisión en la detección de objetos en escenarios más difíciles. En esencia, estas versiones ampliadas son versiones más robustas de YOLOv7 que ofrecen mejor rendimiento al aumentar sus capacidades. Las redes de la familia YOLO son de código abierto. Cada una de ellas dispone de un repositorio de GitHub que contienen el código para entrenar, utilizar y exportar los diferentes modelos. La integración de YOLOv7 en sistemas de visión por computadora permite una mejora notable en la eficiencia y efectividad de la detección y análisis de objetos, contribuyendo significativamente a aplicaciones en tiempo real que requieren procesamiento rápido y preciso de imágenes. El modelo YOLOv7 es la base de este proyecto, utilizando el formato de etiquetas de cajas delimitadoras y los modelos proporcionados y el código disponible en el repositorio oficial de GitHub se podrán realizar entrenamientos. 2.5 Common Objects in Context COCO (Common Objects in Context) (23) es un amplio conjunto de datos utilizado en la detección y segmentación de objetos. Se usa comúnmente como punto de referencia en los modelos de visión por ordenador. Contiene un total de 330k de imágenes, de las cuales 200k tienen anotaciones de un total de 80 categorías de objetos comunes como personas, paraguas, coches y más. Dichas anotaciones contienen información de la caja delimitadora y la máscara de segmentación del objeto a detectar. Se divide en los subconjuntos de entrenamiento, validación y test. Este último no dispone de anotaciones públicas, si se desea que el modelo sea evaluado deben de entregarse los resultados al servidor de evaluación para obtener valores reales y no modificados. Las anotaciones de las imágenes se organizan en lo que se conoce como el formato de anotación de COCO (23). Estas se almacenan en un archivo JSON que contiene diferentes campos. El campo de images almacena información sobre las imágenes en el conjunto de datos. Cada imagen tiene un identificador único (id) y un nombre de archivo (file_name), el tamaño de ancho (width), y la altura (height) en pixeles. Un ejemplo de este campo es: 11 { "id": 1, "file_name": "000000000001.jpg", "width": 640, "height": 480 } El campo annotations incluye las anotaciones de los objetos presentes en las imágenes. Cada anotación está vinculada a una imagen a través del image_id. Cada una incluye la clase del objeto (category_id), el formato de la caja delimitadora (bbox), la segmentación del objeto (segmentation) y otros parámetros relevantes que se puedan usar. Un ejemplo de cómo se guarda una anotación de una imagen sería: { "id": 1, "image_id": 1, "category_id": 3, "bbox": [x, y, width, height], "segmentation": [segmentation_points] } El campo categories define las clases de objetos que el modelo debe de detectar. Cada categoría tiene un identificador (id), un nombre de la clase (name) y una supercategoría (supercategory) general a la que puede pertenecer. Un ejemplo de la implementación de este campo sería: { "id": 3, "name": "car", "supercategory": "vehicle" } Adicionalmente, se puede incluir un campo de licencias(licenses) y otro de información (info) para detallar más aspectos generales del conjunto de datos. Este formato es comúnmente usado para almacenar las anotaciones de diferentes conjuntos de datos por su simplicidad y efectividad. Además, existen diversas librerías de código que ayudan a trabajar con formato JSON, ya que ayuda al desarrollador. En este proyecto, es posible que el usuario visualice y realice operaciones sobre datasets en formato COCO. Así mismo, el usuario podría subir el conjunto de datos de COCO. 2.6 CUDA Toolkit El Nvidia CUDA (24) Toolkit proporciona un entorno de desarrollo para crear aplicaciones de alto rendimiento aceleradas por GPU. Con esta herramienta es posible desarrollar, optimizar y desplegar aplicaciones en sistemas embebidos acelerados por GPU, puestos de escritorio, centros de datos empresariales, etc. Es esencial para entrenar modelos de visión por computadora, como YOLO, aprovechando al máximo la potencia de las tarjetas gráficas NVIDIA. Facilita la implementación de cálculos intensivos en paralelo, mejorando significativamente la eficiencia y velocidad del entrenamiento de modelos complejos. La herramienta CUDA nos permite conectarnos a tarjetas gráficas NVIDIA locales, optimizando y mejorando los tiempos empleados en el entrenamiento de un modelo de inteligencia artificial. 12 2.7 TensorBoard TensorBoard (25) es una herramienta de visualización desarrollada para TensorFlow, un marco de trabajo popular en el campo del aprendizaje automático. Permite a los usuarios visualizar y analizar diferentes aspectos del proceso de entrenamiento de modelos de machine learning. Ofrece una interfaz gráfica donde se pueden observar métricas de rendimiento, como la pérdida y la precisión, así como visualizar la estructura del modelo y las distribuciones de los pesos y gradientes. Esto ayuda a comprender cómo está aprendiendo el modelo y facilita la depuración y la optimización. TensorFlow (26), por su parte, es la biblioteca de código abierto que TensorBoard complementa, proporcionando las funcionalidades necesarias para construir, entrenar y desplegar modelos de aprendizaje automático de manera eficiente. Este software nos permite comparar diferentes gráficas de entrenamiento, facilitando la evaluación de distintos modelos y conjuntos de datos para encontrar el óptimo. 2.8 React React (27) es una librería de JavaScript (28) para construir interfaces de usuario interactivas y dinámicas, especialmente en aplicaciones web. En React, una interfaz de usuario se construye a partir de componentes, que son bloques de código que encapsulan la lógica y el diseño de una parte específica. Estos componentes se pueden combinar y reutilizar en diferentes partes de la aplicación, lo que promueve el desarrollo escalable y modular. Además, con React se puede renderizar en el lado del servidor usando Node.js (29) y construir aplicaciones móviles usando React Native (30). Es la base sobre la que se desarrolla el lado del cliente de la aplicación web, implementando una interfaz diseñada para facilitar los entrenamientos de visión artificial y la visualización de conjuntos de datos. 2.9 PostgreSQL PostgreSQL (31) es un sistema de gestión de bases de datos relacional avanzado, de código abierto y altamente extensible. Reconocido por su fiabilidad, robustez y rendimiento, ha sido desarrollado y mejorado continuamente durante más de 30 años por una comunidad activa y global. Ofrece un amplio conjunto de características, incluyendo soporte para consultas complejas, integridad de datos, concurrencia y extensibilidad. Las empresas de diversos sectores confían en este proyecto para gestionar sus datos críticos debido a su capacidad para manejar grandes volúmenes de información y su compatibilidad con diferentes tipos de datos. Además, la comunidad de PostgreSQL proporciona soporte continuo y actualizaciones regulares, asegurando que la base de datos permanezca segura y eficiente. En este proyecto, se ha utilizado PostgreSQL para crear la base de datos relacional que gestiona los usuarios, conjuntos de datos y entrenamientos. 2.10 NPM NPM (Node Package Manager) (32) es una herramienta de gestión de paquetes para el entorno de desarrollo de JavaScript, especialmente utilizada en el ecosistema de Node.js. Permite instalar, actualizar y gestionar bibliotecas y dependencias necesarias para proyectos de software. Facilita el acceso a una amplia gama de paquetes y módulos disponibles en el registro de NPM, que incluye herramientas y bibliotecas. En el contexto de React, NPM juega un papel crucial al manejar las dependencias de un proyecto. Cuando se inicia un nuevo proyecto de React, se utilizan comandos de NPM para instalar React y otras bibliotecas 13 necesarias. NPM facilita la instalación y el manejo de las herramientas necesarias para el desarrollo del lado del cliente de manera sencilla. 2.11 Docker Docker (33) es una plataforma para desplegar software de forma rápida y sencilla, permitiendo separar la aplicación de la infraestructura local mediante el uso de contenedores. Estas unidades estandarizadas agrupan todo el código, las bibliotecas y las dependencias necesarias para ejecutar una aplicación, asegurando un funcionamiento consistente en diferentes entornos. Utiliza una arquitectura cliente-servidor. El cliente se comunica con el demonio de Docker, que se encarga de desplegar las unidades indicadas por el cliente. Estos contenedores pueden ejecutarse en distintos ordenadores, ya que se comunican a través de una REST API (34), utilizando canales de UNIX o una interfaz de red. Otro cliente de Docker es Docker Compose (35), que permite gestionar aplicaciones compuestas por múltiples unidades. En la Figura 7 se puede observar la arquitectura de Docker y sus diferentes componentes Figura 7: Arquitectura de Docker El demonio de Docker escucha peticiones en la API y maneja los objetos generados. Un demonio se puede comunicar con otros demonios para gestionar diversos servicios, proporcionando flexibilidad y escalabilidad. El cliente actúa como intermediario entre el usuario y el demonio. Un cliente puede interactuar con varios demonios de forma simultánea. El registro almacena imágenes públicas y privadas que están disponibles para los usuarios. El registro por defecto es Docker Hub (36), aunque es posible configurar un registro privado. Los objetos de Docker pueden ser imágenes, contenedores, redes, volúmenes, entre otros. Una imagen es una serie de instrucciones para crear un contenedor, puede basarse en otras imágenes o crearse desde cero. Un contenedor es una instancia ejecutable de una imagen que, por defecto, está aislada de otras unidades y de la máquina local. La configuración de parámetros de red y almacenamiento se realiza mediante opciones específicas. Docker permite crear unidades para desplegar los diferentes módulos de la aplicación de forma local en diversos entornos. Para orquestar estos módulos de manera sincronizada, se utiliza Docker Compose. 14 2.12 REST REST (Representational State Transfer) (34) es una arquitectura de software diseñada para crear servicios web escalables y eficientes. Este paradigma se centra en el uso de recursos, que son entidades identificables mediante URIs (Uniform Resource Identifiers) (37), y en la manipulación de estos recursos a través de un conjunto de métodos HTTP (38) estándar: GET, POST, PUT, DELETE, entre otros. Cada interacción con un recurso RESTful se realiza de manera stateless, es decir, sin que el servidor mantenga el estado de la comunicación entre peticiones consecutivas. Esto permite una mayor escalabilidad y simplicidad en el diseño de sistemas distribuidos. Gracias a su estructura clara y su adherencia a los principios del protocolo HTTP, REST se ha convertido en un enfoque predominante para el desarrollo de APIs (39) en la web moderna, ofreciendo una base sólida para la integración y la interoperabilidad de sistemas diversos. Esta arquitectura facilita el desarrollo de la página web de forma simple y modular. 2.13 Nginx Nginx (40) es un servidor HTTP reconocido a nivel mundial por su estabilidad, variedad de características y eficiente uso de recursos. Ofrece capacidades de proxy inverso, caché y balanceo de carga entre otras muchas. Como proxy inverso, actúa como intermediario entre el servidor y el cliente, interceptando las peticiones de este último y dirigiéndolas al servidor necesario. En este proyecto, se utilizará Nginx para gestionar las conexiones entre el servicio de React y el servicio de Django. Esta elección se debe a que Django requiere un intermediario para la correcta entrega de archivos estáticos y multimedia en entornos de producción. 2.14 JavaScript Object Notation JavaScript Object Notation (JSON) (41) es un estándar abierto basado en texto que se utiliza para representar datos usando la sintaxis de JavaScript. Lo caracteriza su formato ligero y su facilidad de escritura y lectura, tanto para humanos como para máquinas. Los datos se guardan en pares nombre/valor, separados por una coma donde cada llave almacena un objeto y los corchetes almacenan listas. Un ejemplo de datos en formato JSON es: { "nombre": "Juan", "edad": 30, "casado": false, "hijos": ["Ana", "Luis"], "direccion": { "calle": "123 Calle Principal", "ciudad": "Ciudad Ejemplo" } } Este formato de datos tiene infinidad de usos dentro de la informática. En este proyecto, las peticiones que se realicen utilizando HTTP entre los diferentes microservicios, transportan los datos en formato JSON. Además, el formato COCO utiliza archivos JSON para almacenar los datos de las anotaciones de las imágenes. 15 2.15 JSON web tokens JSON Web Token (JWT) (42) es un estándar abierto que define una manera compacta de transmitir información entre diferentes servidores de manera segura utilizando objetos JSON. Esta información es de confianza ya que ha sido firmada digitalmente. La estructura de un JWT contiene tres partes separadas por un punto:  Encabezado o Header: Información indicando el tipo del token (JWT) y el algoritmo usado para su firma.  Carga útil o payload: Información de la entidad (típicamente del usuario).  Firma o signature: Garantiza que el token no ha sido alterado. Se crea concatenando el encabezado, la carga útil y una clave secreta. Se cifra utilizando el algoritmo especificado. Se pueden utilizar algoritmos de cifrado que usen una clave compartida, o que usen un par de claves pública/privada, realizando la firma con la clave privada y la verificación con la clave pública. Cuando el servidor recibe un JWT, verifica la firma para asegurarse de que el token no ha sido modificado En este proyecto, se utilizan los JWT para la autenticación del usuario. Cuando el usuario realiza un acceso correcto, se le devuelve un token. En las siguientes peticiones se debe de incluir dicho valor para garantizar las credenciales. 2.16 Git Git (43) es un sistema de control de versiones de código abierto que permite a los desarrolladores crear y gestionar cambios en el código fuente de un proyecto a lo largo del tiempo. Diseñado para permitir a varios desarrolladores trabajar en un mismo código sin sobrescribir el trabajo de los demás. En este proyecto se ha utilizado Git para llevar un control del código, además el código fuente de YOLO se desarrolla usando esta tecnología. 2.17 GitHub GitHub (44) es una plataforma de desarrollo de software que permite a los desarrolladores crear, almacenar, administrar y compartir su código. Utiliza el software de Git, que proporciona un control de versiones. Se utiliza comúnmente para alojar código abierto, creando repositorios públicos, aunque también es usado de forma privada por organizaciones y particulares. En esta plataforma se encuentra el código de YOLOv7 que permite entrenar, probar y exportar los modelos de esta versión. 16 3 ARQUITECTURA DE LA SOLUCIÓN En este apartado se expone la arquitectura general de los microservicios y las relaciones entre ellos, así como la arquitectura de la base de datos y los requisitos funcionales que necesita el sistema para ser desplegado. 3.1 Estructura de los módulos En una arquitectura de microservicios el software está compuesto por módulos independientes, pequeños y autónomos, que se comunican entre sí a través de APIs bien definidas. A diferencia de una arquitectura monolítica, donde todos los servicios están estrechamente asociados y se ejecutan como un solo bloque, la arquitectura de microservicios permite que las aplicaciones sean más escalables, flexibles y ágiles. En esta aplicación se han implementado los siguientes microservicios:  Gestor web: Encargado de recibir las solicitudes web de los usuarios y procesarlas adecuadamente. Además, se comunica con el motor de entrenamiento para enviar solicitudes y recibir actualizaciones sobre el estado de los entrenamientos. Está desarrollado en Python utilizando la librería de Django. Se divide en tres aplicaciones internas: datasets, projects y authentication, encargadas del manejo de conjuntos de datos, el manejo de proyectos y la autenticación respectivamente.  Motor de entrenamiento: Es responsable de recibir peticiones HTTP desde el gestor web, las cuales contienen los datos necesarios para realizar un entrenamiento. Este motor se encarga de conectarse con el proyecto YOLOv7 y utilizar la GPU del sistema para llevar a cabo las operaciones de entrenamiento del modelo. Por otro lado, se ha desarrollado el módulo de Future Vision que es responsable de desplegar la interfaz web con la que interactúan los usuarios. Además, se integran tres componentes desarrollados por terceros que aplican la funcionalidad de la aplicación en conjunto:  Gestor de base de datos PostgreSQL: Almacena relaciones relevantes para el gestor web como los usuarios, los proyectos entrenados y los conjuntos de datos guardados.  TensorBoard: Módulo que lee los datos proporcionados por los entrenamientos y los presenta en una interfaz web.  Nginx: Actúa como proxy inverso, interceptando las solicitudes del cliente dirigidas al gestor web, redireccionando las necesarias y sirviendo archivos de medios a la interfaz web. Cada uno de estos componentes se construye utilizando imágenes de Docker. La base de datos PostgreSQL, TensorBoard y el proxy inverso Nginx utilizan imágenes predefinidas obtenidas de Docker Hub, configuradas para funcionar en conjunto con el resto del proyecto. Los demás servicios utilizan imágenes construidas localmente a partir del código de la aplicación, utilizando la línea de comandos de Docker. Todos los microservicios se despliegan de manera conjunta mediante Docker Compose. Además, se han definido los siguientes recursos compartidos entre los servicios:  Red: se ha creado una red de Docker para garantizar la comunicación entre los servicios.  Volumen de base de datos: proporciona persistencia para la base de datos.  Volumen multimedia: Una estructura de carpetas compartida donde se almacenan los conjuntos de datos que los usuarios suben a la infraestructura. El gestor web gestiona este volumen para operaciones como la subida de datos, descompresión, reestructuración, eliminación y cambios en la visualización. El proxy inverso asegura el acceso seguro a estos datos por parte del usuario, mientras que el motor de entrenamiento utiliza el volumen para recolectar imágenes, realizar entrenamientos y guardar los modelos entrenados. TensorBoard accede a los datos generados por el motor de entrenamiento para su 17 visualización. Esta arquitectura, representada en la Figura 8, proporciona modularidad a los servicios, mientras que mantiene los recursos compartidos necesarios para su funcionamiento. Figura 8: Esquema de componentes 3.2 Estructura relacional Dentro del proyecto, es necesario mantener una base de datos para asegurar la persistencia de los datos pertenecientes al gestor web. En la Figura 9 se presentan las distintas tablas de la base de datos y las relaciones entre ellas. 24 4 SOLUCIÓN DISEÑADA En este apartado se presentan de forma granulada cada uno de los componentes diseñados o configurados para alcanzar la solución final. 4.1 Gestor web Este microservicio es el núcleo central de la solución, funcionando como servidor en la comunicación con la interfaz web, Future Vision. Su responsabilidad es recibir peticiones, procesarlas y devolver los datos requeridos. Desarrollado en Python, utiliza el módulo Django para gestionar de manera eficiente el lado del servidor web, aprovechando sus potentes herramientas y funcionalidades. La filosofía para programar y organizar la arquitectura en Django se basa en crear bloques de aplicaciones separadas. Cada aplicación tiene un propósito concreto e individual y se organizan en un directorio separado dentro de la carpeta del proyecto. Para este Trabajo de Fin de Grado, se han creado 3 aplicaciones: authentication, datasets y projects. Además, se cuenta con una carpeta principal de nombre src que contiene las configuraciones generales. En los siguientes subapartados, se presentan cada una de las aplicaciones desarrolladas dentro del gestor web. Para cada aplicación, se detalla su propósito general, incluyendo una descripción de los modelos, URLs y vistas implementadas. Además, en este primer apartado, se realiza un repaso de los parámetros de configuración de Django. 4.1.1 Configuración general del Sistema La configuración general utilizada por Django para desplegar la aplicación se gestiona en el archivo settings.py, ubicado dentro de la carpeta src. Este archivo incluye información esencial, como el nombre del servicio, las aplicaciones instaladas, y las configuraciones relacionadas con JWT, entre otros aspectos clave. En este apartado, se revisan detalladamente todos los campos incluidos en esta configuración. La clave secreta, cuyo valor se muestra en la Figura 15, es esencial para la criptografía y la seguridad de la aplicación, por lo que es vital que se mantenga en confidencialidad. Debe generarse individualmente y almacenarse en un archivo de entorno, desde el cual será extraída por el programa. Los detalles de su configuración se especifican en la sección de instalación. Figura 15: Clave secreta de la configuración de Django Es importante y recomendable que, al desplegar la aplicación, el parámetro DEGUB este configurado a valor falso, para proteger la aplicación y mostrar las páginas de errores predeterminadas. El parámetro ALLOWED_HOST, ilustrado en la Figura 16, define los nombres de dominio o direcciones IP a las que la aplicación responderá. Figura 16: Parámetro ALLOWED_HOST de la configuración de Django En la sección INSTALLED_APPS, con valores indicados en la Figura 17, se define una lista de aplicaciones internas y externas que esta instancia de Django debe cargar. 25 Figura 17: Parámetro INSTALLED_APPS de la configuración de Django En esta lista encontramos aplicaciones proporcionadas por el módulo de Django, además de las aplicaciones creadas para este proyecto. Las aplicaciones datasets, projects y authentication han sido específicamente programadas para este proyecto y serán explicadas en más extensión en los apartados 4.1.3, 4.1.4 y 4.1.5 respectivamente. A continuación, se realizará un repaso por las aplicaciones django.contrib, rest_framework y corsheaders. Se explicará el propósito de cada una de ellas y, en el caso de ser necesario, se destallará la configuración adicional que requieren. El módulo django.contrib proporciona una colección de aplicaciones que vienen preinstaladas con Django. Estas contienen funcionalidades comunes a casi todos los proyectos web. Las aplicaciones individuales fueron explicadas más a fondo en el apartado 3.2 Estructura Relacional, debido a que se utilizan las bases de datos proporcionadas por estas aplicaciones para el manejo de usuarios. La aplicación rest_framework facilita un conjunto de herramientas y funcionalidades para construir APIs RESTful de manera sencilla y rápida. Extiende las funcionalidades básicas de Django para crear aplicaciones modernas. Permite la serialización de datos complejos, la autenticación y autorización mediante JWT y la simplificación del proceso de enrutamientos. Los parámetros configurados por esta aplicación se ilustran en la Figura 18. Figura 18: Parámetro REST_FRAMEWORK de la configuración de Django Como se muestra en la Figura 18, se configura la aplicación SIMPLE_JWT como gestora de los JWT, que utiliza los valores indicados en la Figura 19. 26 Figura 19: Parámetro SIMPLE_JWT de la configuración de Django Para manejar la política de CORS (Cross-Origin Resource Sharing) se utiliza la aplicación corsheaders. Esta política es un mecanismo de seguridad que controla cómo los recursos de una página web pueden ser solicitados desde un dominio diferente a la propia página. En la Figura 20 se muestra la configuración de los hosts permitidos, especificando qué dominios pueden interactuar con la aplicación. 27 Figura 20: Parámetro CORS_ALLOWED_ORIGINS de la configuración de Django Como se observa, se permiten las peticiones del motor de entrenamiento y del gestor web. En la Figura 21 se indican los verbos HTTP permitidos en las peticiones. Figura 21: Parámetro CORS_ALLOW_METHODS de la configuración de Django Con esto, se han explicado las tres aplicaciones principales importadas en Django. En futuros apartados, se detallarán las aplicaciones programadas específicamente para este proyecto. Ahora, se continuará con el resto de las configuraciones del archivo. Los middlewares, ilustrados en la Figura 22, son componentes que se ejecutan durante el procesamiento de las solicitudes y respuestas que permiten modificar, procesar o actuar sobre estas. Estos se ejecutan en el orden especificado y son esenciales para la seguridad de la aplicación. Figura 22: Parámetro MIDDLEWARE de la configuración de Django El parámetro ROOT_URLCONF indica el archivo de configuración de las URL del proyecto. Dicha configuración se encuentra en el archivo src/urls.py. El contenido principal de este archivo se presenta en la Figura 23. 28 Figura 23: Archivo de configuración de URLs Como se puede observar deriva a cada aplicación sus peticiones. Dentro de estos módulos se observarán las rutas específicas. Esta configuración nos permite mantener modularidad en el proyecto. Para la configuración de las bases de datos conectadas al gestor web se utiliza el parámetro DATABASES, en la Figura 24 se muestra la configuración específica para este trabajo. Figura 24: Parámetro DATABASES de la configuración de Django Se configuran el motor de base de datos PostgreSQL y el resto de los parámetros se obtienen del sistema. Esto evita añadir configuraciones predeterminadas, ni información sensible. Es importante que los parámetros de conexión coincidan con los especificados en el archivo Docker Compose que se utilice para ejecutar el sistema. Para definir las carpetas donde se encuentran los archivos multimedia se definen en los parámetros indicados en la Figura 25. Figura 25: Parámetros de archivos multimedia de la configuración de Django Estos concuerdan con la estructura de directorios general vista en apartados anteriores. Para permitir al usuario que lo desee visualizar Logs de la aplicación desde Docker se realiza una configuración ilustrada en la Figura 26. 29 Figura 26: Parámetro LOGGING de la configuración de Django 30 4.1.2 Aplicación para la gestión de la autenticación La aplicación Authentication es responsable de gestionar los usuarios y grupos del sistema, incluyendo la creación, visualización y eliminación de cuentas. Para ello se apoya en diferentes aplicaciones, vistas, modelos y URLs. Dentro de esta aplicación, se pueden distinguir dos funcionalidades principales: la gestión de usuarios y la gestión de tokens. En los apartados 4.1.2.1 y 4.1.2.2, se ofrecerá una explicación detallada de los modelos utilizados para cada una de estas funcionalidades, respectivamente. 4.1.2.1 Modelos utilizados por la aplicación de autenticación Esta operación se realiza utilizando modelos de datos proporcionados por django.contrib y rest_framework como se observó en secciones anteriores. A continuación, se explicará en más detalles qué campos y relaciones de estos paquetes se utilizan. 4.1.2.1.1 Modelos para almacenar informacion de usuarios, grupos y permisos El proyecto está diseñado para ser utilizado tanto por usuarios individuales como por empresas, requiriendo una gestión de usuarios adecuada para este último caso. Cada usuario almacena datos como nombre, contraseña, grupo y correo electrónico. Además, se asigna automáticamente un identificador numérico único al ser registrado en la base de datos. Este proceso se gestiona mediante la tabla auth_user de la aplicación django.contrib.auth, cuyos campos están detallados en la Figura 27. Figura 27: Campos de la tabla auth_user Los usuarios pueden pertenecer a dos grupos admin o user, y dependiendo de esto tendrán una serie de propiedades u otras. Para gestionar estos roles se utiliza la tabla auth_groups, ilustrada en la Figura 28, que pertenece a la aplicación django.contrib.auth. Figura 28: Valores insertados en la tabla auth_group 31 La relación entre usuario y grupo se asigna mediante una tabla intermedia de nombre auth_user_groups que pertenece al mismo paquete que las anteriores. Los campos de esta se visualizan en la Figura 29. Figura 29: Campos de la tabla auth_user_groups Los usuarios que pertenecen al grupo de administradores pueden crear, eliminar o cambiar el grupo de otros usuarios. Aquellos, que no pertenezcan a este grupo, solo podrán modificar su nombre, email o contraseña. Para poder asignar permisos contamos con las tablas auth_permisions, auth_group_permisions y auth_user_user_permisions que se muestran en las figuras 30, 31 y 32 respectivamente. En auth_permisions se almacenan todos los permisos relacionados con la tabla content_type revisada en apartados anteriores. Estos permisos están relacionados con las acciones que un usuario o grupo puede realizar con una tabla determinada como, por ejemplo, “can add training”, que se correspondería con el permiso para realizar un nuevo entrenamiento y añadirlo a esta tabla. Para los permisos relacionados con la creación, modificación y eliminación de usuarios se pueden utilizar las siguientes filas de la tabla de permisos ilustradas en la Figura 30. Figura 30: Campos de permisos sobre usuarios en la tabla auth_permisions La primera columna mostrada se corresponde con el identificador único del permiso, la segunda es la descripción del permiso y la tercera se corresponde con su relación con la tabla content_type que para esta situación se relacionan la aplicación auth y el modelo user. La última columna muestra un código utilizado en código para referenciar estos permisos. Para asignar estos permisos determinados a un grupo se utiliza la tabla auth_group_permisions que asigna a cada grupo (admin o user) un permiso específico para esta tabla. El contenido de esta se presenta en la Figura 31. Figura 31: Permisos insertados en la tabla auth_group_permisions De esta forma se consiguen los permisos esperados. La tabla auth_user_user_permisions que asigna autorización por usuario no se utiliza. Asimismo, el resto de los permisos sobre otras tablas se dejan abiertos, ya que todos los usuarios del sistema pueden crear, cambiar y eliminar conjuntos de datos, proyectos y entrenamientos. 32 Es importante recalcar que solo un usuario administrador puede añadir usuarios al sistema, por ello, el primer cliente que se registre debe de hacerlo mediante un flujo especial en el que se le asigne el rol de administrador. El resto de los clientes se asignan a partir de este. En resumen, a cada usuario se le asigna un identificador único, un nombre, un correo electrónico y una contraseña. Además, los usuarios pertenecen a uno de dos grupos: admin o user. Dependiendo del grupo al que pertenezcan, tendrán distintos permisos: los administradores pueden crear nuevos usuarios y modificar o eliminar a los existentes, mientras que los usuarios normales solo pueden modificar sus propios campos básicos. Estas operaciones y permisos se registran en diversas tablas de la base de datos que forman parte del módulo django.contrib. En el siguiente apartado se hará una explicación sobre los modelos utilizados para almacenar los datos relativos a los JWT. 4.1.2.1.2 Modelos para almacenar la informacion relacionada con JWT La aplicación django-rest-framework-simplejw se utiliza para manejar la autenticación basada en JWT en las aplicaciones de Django. Para ello se utilizan las tablas token_blacklist_outstandingtoken y token_blacklist_blacklistedtoken ilustradas en la Figura 32 y la Figura 33. La tabla token_blacklist_outstandingtoken almacena todos los tokens JWT que han sido emitidos y aún no han expirado, es decir, están vigentes. Los campos de esta tabla se muestran en la Figura 32. Figura 32: Campos de la tabla token_blacklist_outstandingtoken Como se observa está relacionada también con la tabla usuario mediante el Id. El modelo token_blacklist_blacklistedtoken almacena información sobre los tokens que han sido específicamente revocados. Un token revocado deja de ser válido, incluso si no ha alcanzado su fecha de expiración. Los campos de esta tabla se indican en la Figura 33. Figura 33: Campos de la tabla token_blacklist_blacklistedtoken 4.1.2.2 Endpoints de la aplicación de autenticación Las funciones principales de esta aplicación es la gestión de usuarios, la creación de tokens y la revocación de estos. En el apartado anterior se han estudiado los campos de las tablas que permiten almacenar la información necesaria de forma persistente. En este apartado se estudiará específicamente los Endpoints desarrollados para esta aplicación. Estos se ilustran en la Figura 34. 33 Figura 34: Endpoints de la aplicación de autenticación Es importante mencionar que las rutas completas incluyen por delante /auth por la configuración de URLs mencionadas anteriormente. Django al recibir una petición que comienza por auth la redirigirá automáticamente al archivo de definición de rutas de la aplicación determinada, en este caso authentication. Las vistas relacionadas con la obtención, refresco y revocación de tokens se heredan directamente del paquete djangorestframework-simplejwt (45). El endpoint de registro de nuevos usuarios (signup) acepta el método HTTP POST y está pensado para enviar el formulario para registrar al primer usuario del sistema. Solo sirve para el registro de este primer usuario, ya que crea las relaciones de grupos y asigna permisos. Adicionalmente, obliga a que este usuario tenga asignado el rol de administrador. No se necesita autorización para realizar peticiones sobre esta vista. La ruta user acepta los métodos POST y GET, cuando se ejecuta una acción con el primero de ellos, se espera que un usuario administrador esté intentando añadir un nuevo usuario al sistema. Mientras que, cuando se realiza la acción GET, se obtienen los datos del usuario que realiza la petición. Para realizar modificaciones sobre un usuario en concreto, que puede o no ser el mismo que realiza la petición, se utiliza el endpoint user seguido por el ID del usuario sobre el cual se quiere realizar la modificación. Acepta los métodos PUT y DELETE. El primero de ellos permite modificar los campos del usuario, para poder ejecutar esta acción se debe de ser administrador o ser el mismo usuario que se desea modificar. El verbo DELETE se utiliza para eliminar un usuario del sistema, para ello debe de realizar la acción un administrador. Para asegurar que estas vistas solo son accedidas por usuarios con un token JWT válido se utiliza el decorador: @permission_classes([IsAuthenticated]. Este pertenece a la aplicación rest_framework y verifica mediante el método configurado, en este caso JWT, que el usuario es válido antes de que se permita realizar una operación sobre cualquiera de las vistas que lo incluyan. 4.1.3 Aplicación para la gestión de conjunto de datos La aplicación Datasets se encarga de gestionar la creación, modificación y eliminación de las agrupaciones de datos. Estas agrupaciones consisten en imágenes etiquetadas bajo un criterio específico, que se utilizan posteriormente para el entrenamiento de modelos de visión por computadora. Son el núcleo principal de la aplicación, ya que nos permiten avanzar a las siguientes acciones. Para trabajar con los conjuntos de datos, es necesario definir el formato en el que los usuarios deben ingresar estos datos en el sistema. Además, se explicará el módulo desarrollado para la persistencia de estos datos, así como las vistas principales utilizadas en la aplicación para su gestión y visualización. 4.1.3.1 Formato de subida de los conjuntos de datos Un conjunto de datos o dataset se trata de un archivo zip subido a la plataforma por el usuario, con una determinada organización de directorios y datos. Si se recuerda la información presentada en apartados anteriores, para que un dataset pueda ser entrenado por el modelo YOLOv7 tiene que estar divido en tres subcategorías (train, val y test) y además debe tener las imágenes etiquetadas en el formato definido por Yolo, en este caso para las cajas delimitadoras. También se permite la subida de un conjunto de datos con etiquetas en formato Yolo, pero sin las subcategorías creadas. Adicionalmente, se permite al usuario subir y visualizar datasets en formato COCO que deben de estar 40 Figura 45: Clase CocoData Esto permite que las imágenes se vayan procesando conforme el usuario las vaya requiriendo, es decir, si se solicita visualizar un dataset en la página 1 del subconjunto train solo se extraen las imágenes pertenecientes a esa página. Para visualizar las imágenes con las etiquetas superpuestas se crea específicamente una carpeta dentro de la carpeta temporal en la que se está trabajando, en ella se almacenan las imágenes etiquetadas. Para obtener las imágenes etiquetadas, primero se obtienen las imágenes que se están requiriendo, después se obtienen las etiquetas de dichas imágenes, y por último se combinan ambas en una nueva imagen usando OpenCV. El proceso que añade las etiquetas a la imagen para el formato Yolo se presenta en la Figura 46. 41 Figura 46: Etiquetado de imágenes en formato Yolo Este proceso puede ser lento la primera vez que se obtienen las imágenes de una página debido a que se deben procesar una gran cantidad de datos. El tiempo de vida de esta carpeta temporal y de los datos que contiene, así como del objeto creado llega a su fin cuando el usuario sale de la página de visualización del conjunto de datos o cierra sesión. Al realizar cualquiera de estas acciones, se envía una petición al endpoint datasets/<int:dataset_id>/tmp utilizando el verbo DELETE, que elimina el objeto y la carpeta temporal. Partiendo de estos conocimientos, se pueden explicar el resto de endpoints del sistema. La ruta /datasets/ int:dataset_id/ se utiliza para visualizar, eliminar y modificar un conjunto de datos, con los verbos GET, DETELE y PATCH respectivamente. La visualización de un dataset se realiza mediante la extracción de los datos en la carpeta temporal, como se ha 42 comentado anteriormente. La eliminación de un dataset borra toda la información que haya de este en el sistema, incluyendo las carpetas y los registros de la base de datos. Dentro de un dataset almacenado se pueden modificar los campos de descripción para añadir o modificar datos, de privacidad para hacerlo público o privado y de tipo para crear subcategorías en un dataset que no las contiene. El cuerpo de esta petición debe contener de uno a dos campos. El primer campo obligatorio de nombre fields es una lista que puede contener los valores description, privacy, y splits indicando el valor que se desea modificar. El segundo campo opcional de nombre values solo es necesario en caso de modificar la descripción y o la privacidad y se utiliza para mandar el nuevo valor. La modificación de los dos primeros valores comentados se realiza cambiando valores en la base de datos, que automáticamente actualizan el comportamiento del sistema. La modificación que crea subcategorías es un proceso más complejo. Para poder crear subcategorías o splits en un conjunto de datos que no las tiene, se debe seguir un proceso de dos pasos. El primero de ellos es realizar una petición a la ruta datasets/<int:dataset_id>/splits, utilizando el método PATCH. El cuerpo de la petición se muestra en la Figura 47. Figura 47: Cuerpo de petición de creación de subcategorías Donde cada valor indica el porcentaje de las imágenes que se deben añadir en cada subcategoría. Con estos datos se realiza una modificación temporal de la base de datos, para almacenar en los campos necesarios los datos de la cantidad de imágenes. A continuación, se utilizan estos valores para asignar aleatoriamente a cada subcategoría las imágenes y las etiquetas que va a almacenar, esta información se almacena temporalmente en listas. El dataset pasará ahora a tener el valor modify como verdadero, indicando que se ha realizado una modificación, que no está guardada. Si esta operación se realiza de forma exitosa se devuelve el código 200 y el usuario podrá interaccionar con el conjunto como si originalmente tuviese las carpetas de subconjuntos creadas. Esto se debe a que cada vez que realice una petición, se va a identificar que se está pidiendo datos sobre un dataset modificado y se van a extraer temporalmente en las carpetas de subconjuntos las imágenes y datos necesarios. A partir de este punto, se pueden tomar dos acciones, guardar o eliminar los cambios. Para eliminar los cambios se realiza una petición al mismo endpoint utilizando el verbo DELETE, que revierte todas las peticiones. También se eliminarán los cambios haciendo una petición a la ruta que elimina las carpetas temporales. Para guardar estos cambios, se puede realizar una petición utilizando el verbo PATCH a la ruta /datasets/ int:dataset_id/, conteniendo en el campo fields del cuerpo de la petición el valor splits. De esta forma, las carpetas se crearán de forma permanente dentro del archivo zip subido por el usuario. Esta operación no se puede deshacer. En resumen, la aplicación datasets se encarga de gestionar las operaciones relacionadas con los conjuntos de datos. Los datos pueden estar en uno de cuatro formatos posibles: COCO sin subconjuntos, COCO con subconjuntos, YOLO sin subconjuntos y YOLO con subconjuntos. Para asegurar que los datos necesarios para cada formato sean correctamente cargados por el usuario, se diseñan una serie de estructuras que se utilizan para verificar estos datos de manera automática. Las relaciones más importantes se almacenan en el modelo datasets, que se exporta a la base de datos para mantener la persistencia. Con el fin de visualizar, modificar y eliminar los conjuntos de datos, se crean una serie de rutas y vistas específicas. 43 4.1.4 Aplicación para la gestión de proyectos Se define un proyecto como una asociación entre conjunto de datos y entrenamientos en los que se ha usado. Un mismo conjunto se puede utilizar en varios proyectos, así como un proyecto puede almacenar múltiples entrenamientos. La aplicación de projects es la encargada de gestionar las relaciones entre estos datos, así como de la creación de entrenamientos. 4.1.4.1 Modelos de la aplicación de proyectos En esta aplicación se cuenta con dos modelos, el primero de ellos se utiliza para almacenar la información relativa a las características de un proyecto. El segundo, se utiliza para almacenar las características relativas a los entrenamientos realizados por la aplicación. 4.1.4.1.1 Modelo para almacenar los datos relativos a un proyecto Un proyecto cuenta con una serie de características recogidas en el modelo projects cuyos campos están ilustrados en la Figura 48. Figura 48: Modelo Projects Como se observa, es similar al modelo presentado anteriormente para Datasets. El campo user lo relaciona con el usuario que ha creado el proyecto. El campo dataset lo relaciona con el conjunto de datos que se utilizará para realizar el entrenamiento. Es importante recalcar que para que un proyecto sea público el conjunto de datos asociado también debe de serlo. En caso contrario, devolverá un error en su creación. Además, se crea un serializador, mostrado en la Figura 49, que facilita la devolución de los campos del modelo de manera sencilla y estructurada. Este serializador convierte los datos del modelo en un formato adecuado para su transmisión y presentación. Figura 49: Serializador de datos del modelo Projects 4.1.4.1.2 Modelo para almacenar los datos de un entrenamiento Un entrenamiento está siempre asociado a un proyecto, que a su vez se vincula con un conjunto de datos. El modelo ilustrado en la Figura 50 se utiliza para almacenar de manera persistente las características más relevantes de los entrenamientos. 44 Figura 50: Modelo Training El campo input se utiliza para almacenar el comando que se envía al motor del entrenamiento para iniciar el proceso. El campo data almacena en formato simple el archivo YAML que contiene los nombres de las clases y las rutas de las carpetas utilizadas para el entrenamiento. Este archivo es creado a partir de los datos subidos por el usuario en el fichero de datos y mediante la construcción de las rutas de las subcarpetas necesarias para entrenar. Se almacena también la ruta de la carpeta que se ha utilizado para realizar el entrenamiento en el parámetro data_folder. Por último, el campo status almacena el estado del entrenamiento. Este puede tomar el valor de pending si se ha enviado el comando de entrenamiento, pero el motor no ha respondido a la petición, running si el entrenamiento se está llevando a cabo, completed si ha finalizado o stopped en caso de error. Además, se crea un serializador para la devolución de datos de este modelo ilustrado en la Figura 51. Figura 51: Serializador de datos del modelo Training 4.1.4.2 Endpoints de la aplicación de proyectos Los objetivos que se pretende alcanzar con esta aplicación son los siguientes: - Asociar conjuntos de datos con entrenamientos. - Crear las rutas necesarias para comunicar con el motor de entrenamiento. - Permitir la descarga de los datos del entrenamiento, como logs y pesos. Para ello, se han creado las rutas, indicadas en la Figura 52 que parten de projects/. 45 Figura 52: Endpoints de la aplicación de proyectos La vista principal es similar a la utilizada en la aplicación Datasets, acepta los métodos GET y POST. El primero de ellos sirve para visualizar de forma paginada los proyectos creados. El segundo acepta un formulario que debe contener los datos necesarios para la creación de un nuevo proyecto. La Figura 53 muestra el código que crea un nuevo proyecto realizando las comprobaciones necesarias. Figura 53: Vista para la creación de proyectos La URL /projects/<int:Project_id> puede ser accedido con dos verbos GET y DELETE. El primero se utiliza para obtener una vista de los datos asociados a un proyecto, concretamente de los entrenamientos. El segundo se utiliza para eliminar los datos asociados al proyecto. Para poner un entrenamiento en la cola a la espera de que el motor de entrenamiento lo realice, se utiliza la ruta /projects/<int:Project_id>/queue, usando el verbo POST. Esta vista realiza una serie de operaciones para llevar a cabo el proceso de entrenamiento. Recoge del cuerpo de la petición información que se utiliza para entrenar, mostrado en la Figura 54. Esta se trata de parámetros variables de la configuración de YOLOv7. El significado de estos datos será estudiado a fondo en el apartado del motor de entrenamiento. 46 Figura 54: Datos obtenidos del cuerpo de una petición de entrenamiento Se debe crear también el archivo YAML que YOLOv7 necesita para ser entrenado. Este debe especificar la cantidad de clases de objetos que existen, el nombre de esas clases y las rutas de dónde se encuentran las imágenes y las etiquetas que necesita para entrenar. Este archivo se construye partiendo de los datos añadidos por el usuario en el fichero zip. En base a estos, se añaden las rutas de dónde se almacenan los archivos de entrenamiento. Las imágenes y las etiquetas que el modelo va a utilizar para entrenar no pueden estar comprimidas, por ello, temporalmente durante el entrenamiento se descomprimen en la carpeta dedicada para ello. Al finalizar estos datos serán eliminados, para no ocupar espacio en el sistema. Una vez realizado esto, se guardan los datos en la tabla creada por el modelo projects. Finalmente, se envía una petición a través de HTTP a la ruta del motor de entrenamiento. Allí se procesarán los datos y se devuelve un valor HTTP 200 en el caso de que haya tenido éxito el inicio del entrenamiento, entonces el estado pasa de pending a running. En el caso de que se reciba otro código como respuesta o de que el temporizador de la petición termine, el estado pasará de pending a stopped. La manera que tiene el motor de entrenamiento de indicar al gestor web que ha terminado la tarea con la que se encontraba, es enviando una petición HTTP con el verbo POST a la ruta /projects/notify, ilustrada en la Figura 55. Esta actualiza el estado de la tarea en la base de datos. Es relevante mencionar que mientras el resto de las vistas están protegidas por JWT, esta se encuentra exenta de esa protección para que el motor de entrenamiento pueda acceder a ella. Figura 55: Vista notify del gestor web 47 La URL /projects/log/<int:trainig_id> está diseñada para descargar un archivo en formato txt que contenga el log del entrenamiento realizado. Mientras que la vista /projects/weights/<int:training_id> descarga los archivos de pesos generados por el modelo al entrenar. En la Figura 56 se muestra el código relativo a las vistas que reciben las peticiones de estas URLs. Figura 56: Vistas para descargar el log y los pesos de un entrenamiento 4.1.5 Creación de la imagen del gestor web Una imagen de Docker es un paquete liviano, autónomo y ejecutable que incluye todo lo necesario para poder ejecutar un software. El proyecto, al estar diseñado para ser desplegado utilizando la herramienta Docker Compose, es necesario que todas las piezas de software estén disponibles como una imagen. Para construir estas se necesita un archivo con nombre dockerfile que indica a la herramienta que pasos que hay que seguir para construir la imagen. En la Ilus.54 se presenta el archivo necesario para construir el gestor web. 48 Figura 57: Archivo dockerfile utilizado para construir la imagen del gestor web Esta imagen parte de Ubuntu en su versión 22.04 (48) como base, esto significa que se debe de poder instalar el mismo software que se utilizaría en su versión de escritorio. Después se realiza la configuración de fecha y hora y se instalan las herramientas necesarias como Python o Git para descargar las dependencias y ejecutar el proyecto. Se establece el directorio de trabajo de la aplicación y se copia el archivo de requerimientos, que contiene las dependencias del proyecto de Python que necesita la aplicación para ejecutarse. En la siguiente línea se instalan dichas dependencias. Finalmente, se copia el código de la aplicación en la carpeta de trabajo y se establecen los permisos de los archivos que se necesitan para ejecutarse. Este archivo contiene las instrucciones de la receta que crean la imagen de Docker. Para conseguir la imagen se debe ejecutar el siguiente comando sobre la carpeta de trabajo en la que se encuentra el archivo: docker build -t nombre-imagen:tag . El ejecutable obtenido de la salida de este comando podrá ser usado en local o almacenado en Docker Hub de forma pública o privada. 49 En el apartado de Despliegue se hará un repaso de cómo se ejecutan las imágenes de forma coordinada para lograr la funcionalidad de la aplicación. El servicio del gestor web se encarga de una variedad de tareas y contiene tres aplicaciones distintas: datasets, projects y authentication. Cada una de estas aplicaciones incluye módulos y vistas específicas que facilitan la gestión de diferentes aspectos de la aplicación. El servicio del gestor web se comunica tanto con la interfaz web Future Vision, como con el motor de entrenamiento para intercambiar y recibir datos variados. La configuración general de este módulo abarca la instalación de aplicaciones, la conexión con la base de datos y los ajustes de JWT, entre otros aspectos esenciales. 56 Figura 63: Fichero de configuración de Nginx 57 5 DESPLIEGUE En este apartado se explicarán los pasos a seguir para desplegar la aplicación utilizando la línea de comandos de Docker y la herramienta Docker Compose. Se utiliza un entorno de trabajo con el sistema operativo Debian en la versión 12, aunque con la configuración correcta, estos pasos se pueden seguir en cualquier sistema. Es importante recordar que para poder entrenar una red de inteligencia artificial es prácticamente necesario contar con una tarjeta gráfica de la marca NVIDIA. Esto se debe a que esta marca proporciona el software para sacar el máximo provecho al hardware durante el entrenamiento. Se pueden entrenar modelos utilizando algunos modelos de CPU, pero no es recomendable ya que el tiempo empleado en el entrenamiento sería mucho mayor. En el Anexo A se explica la base de como instalar las herramientas de Docker, Docker Compose y los drivers necesarios para utilizar la tarjeta gráfica en Debian. 5.1 Fichero de entorno En varias ocasiones durante el texto se ha mencionado la necesidad de mantener un fichero de entorno para almacenar aquellos datos configurables y personales de la aplicación que no deben de ser expuestos. Este es típicamente un archivo oculto de nombre env. En él se configuran los parámetros especificados en la Tabla 2. Tabla 2: Parámetros del archivo de entorno Parámetro Funcionalidad Valor por defecto DB_NAME Nombre de la base de datos que se crea para almacenar los datos de la aplicación de Django. A elección del usuario. DB_USER Nombre del usuario de la base de datos que tienen permisos y privilegios para manejar los datos. A elección del usuario. DB_PASSWORD Contraseña él usuario de la base de datos. A elección del usuario. DB_HOST Nombre del servicio que mantiene la base de datos. db DB_PORT Puerto que utiliza el servicio de la base de datos. 5432 SECRET_KEY Clave secreta utilizada por el archivo de configuración de Django. Creada por el usuario. Los valores de los tres primeros parámetros se dejan a elección del usuario, solo es necesario que concuerden con los especificados en el archivo Docker Compose. El nombre del host y el puerto de la base de datos se puede modificar, aunque se recomienda mantener los valores por defecto. La clave secreta utilizada por Django la debe de crear cada administrador, este es un proceso sencillo que se puede realizar mediante la solución proporcionada por la propia herramienta (55) o utilizando generadores online como Djecrety (56). 58 5.2 Archivo Docker Compose En los apartados anteriores se han estudiado los microservicios y se ha establecido que cada uno de ellos se construye utilizando una imagen de Docker. Esta puede ser obtenida directamente de Docker Hub si los servicios son de terceros o fabricada manualmente. Estas imágenes necesitan colaborar entre sí para lograr el desarrollo final de la aplicación, para ello se utiliza un fichero Docker Compose que levanta todas al mismo tiempo y crea los recursos compartidos. En los apartados siguientes se van a estudiar las definiciones de cada servicio por separado para proporcionar claridad sobre los campos declarados en cada uno de ellos. 5.2.1 Gestor web El gestor web presenta la composición ilustrada en la Figura 64. Figura 64: Apartado del gestor web en el fichero Docker Compose Es importante destacar la importación del fichero de entorno configurado con anterioridad para que la imagen cuente con las variables necesarias para iniciar el servicio. Al iniciar el proceso se ejecuta el fichero de nombre entrypoint, mostrado en la Figura 65, que contiene un bucle que espera a la base de datos. Esto es necesario ya que si el gestor web se inicia antes que el servicio de PostgreSQL se produce un error de conexión. Adicionalmente, este fichero ejecuta las migraciones a dicha base de datos y creará los directorios necesarios en los volúmenes. 59 Figura 65: Fichero de inicio del gestor web 5.2.2 Motor de entrenamiento Este microservicio presenta la configuración más compleja, ya que necesita conectarse con la tarjeta gráfica de NVIDIA para permitir el entrenamiento. Dicha configuración se muestra en la Figura 66. Figura 66: Apartado del motor de entrenamiento en el fichero Docker Compose 60 Los parámetros relativos a la memoria deben de ser adaptados por el usuario dependiendo del hardware de su sistema. Se puede observar que esta configuración no exporta el puerto utilizado por el motor al exterior, esto es para impedir que un usuario pueda realizar las peticiones a este microservicio sin utilizar la interfaz web. Los servicios que exportan los puertos son los únicos con los que el usuario exterior puede y debe interactuar. El fichero de entrada, ilustrado en la Figura 75, ejecuta el comando de Python que inicia el servicio web para recibir peticiones de entrenamiento. Figura 67: Fichero de inicio del motor de entrenamiento 5.2.3 Future Vision La interfaz web presenta una configuración sencilla. No cuenta con un fichero de entrada, ya que en la misma configuración de la imagen se indica el comando a ejecutar. Los parámetros utilizados se muestran en la Fiura 68. Figura 68: Apartado de Future Vision en el fichero Docker Compose 61 5.2.4 TensorBoard La configuración del microservicio TensorBoard en el fichero Docker Compose está representada en la Figura 69. Figura 69: Apartado de TensorBoard en el fichero Docker Compose 5.2.5 Base de datos En la configuración de la base de datos PostgreSQL es importante que el usuario rellene los parámetros de entorno con los mismos valores indicados en el fichero de entorno utilizado para el microservicio de Django. La configuración utilizada se representa en la Figura 70. Figura 70: Apartado de la base de datos en el fichero Docker Compose 62 5.2.6 Nginx En la configuración del microservicio de Nginx es importante importar los archivos utilizados por este con los permisos adecuados y exportar los puertos. La configuración se muestra en la Figura 71. Figura 71: Apartado de Nginx en el fichero Docker Compose 63 6 MANUAL DE INTERFAZ DE USUARIO En esta sección se realiza una guía de uso de la interfaz de usuario. Al iniciar el proyecto, se redirige a la página de inicio de sesión, ilustrada en la Figura 72, donde se podrán introducir las credenciales de un usuario ya registrado. Figura 72: Página de inicio de sesión Si no hay ningún usuario registrado en el sistema, se deberá crear uno nuevo con permisos de administrador. Para ello se puede utilizar el enlace de debajo el botón de login que llevará directamente a la página de registro de usuarios, mostrada en la Figura 73. 64 Figura 73: Página de registro de usuarios Una vez creado el usuario administrador y realizado el inicio de sesión, se accede a la página de conjunto de datos, que cuando no contiene datos muestra la vista de la Figura 64. 65 Figura 74: Página datasets sin datos guardados Para poder navegar por la aplicación se cuenta con una barra superior que irá mostrando la información relevante para cada página. También se encuentran en ella dos botones fijos, a la derecha se muestra el panel de navegación desplegable y a la izquierda se encuentra el botón de cierre de sesión. Dichos botones se encuentran ilustrados en las Figuras 75 y 76, respectivamente. Figura 75: Panel navegación desplegable de la barra superior 72 Figura 89: Página projects con datos creados Al acceder a la página del proyecto determinado se obtiene la información de los entrenamientos realizados. En la Figura 90 se ilustra dicha página sin datos de entrenamiento. Figura 90: Página trainings sin datos creados Desde esta página se pueden realizar dos acciones, borrar el proyecto eliminando los datos de entrenamiento asociados a este y crear un nuevo entrenamiento. En las Figuras 91 y 92 se presentan los cuadros que se obtienen para cada uno de estos casos. 73 Figura 91: Cuadro de eliminación de un proyecto Figura 92: Cuadro de creación de un nuevo entrenamiento 74 En el cuadro de creación del entrenamiento se presentan todas las opciones, estudiadas en apartados anteriores, que se pueden modificar para probar diferentes parámetros de entrenamiento, incluyendo la arquitectura del modelo. En la Figura 93 se muestra la página trainings mientras que un entrenamiento está en proceso. Por cada entrenamiento se presenta una caja diferente. Figura 93: Pagina trainings con datos de un entrenamiento en proceso El botón de TensorBoard abre en una pestaña nueva esta herramienta que permite seguir en tiempo real los datos de todos los entrenamientos. Una vez terminados, los datos siguen siendo visibles. En la Figura 94 se ilustra el contenido de esa página al inicio de un entrenamiento. Figura 94: Datos de entrenamiento en tiempo real de TensorBoard Cuando el entrenamiento finaliza, el cuadro de este cambia a la vista mostrada en la Figura 95. 75 Figura 95: Página trainings con datos de un entrenamiento finalizado Desde esta nueva caja se presentan los botones de descarga del log y de los pesos. El segundo de ellos descarga un archivo de tipo zip que contiene todos los datos obtenidos del entrenamiento. En las Figuras 96 y 97 se muestran datos reales descargados. Figura 96: Fichero de log descargado de un entrenamiento 76 Figura 97: Contenido del fichero zip de pesos descargado de un entrenamiento Por último, se presenta, en las Figuras 98 y 99, la vista profile desde la cual el usuario podrá ver sus datos y modificarlos. Adicionalmente, un usuario del grupo administrador podrá crear nuevos usuarios y modificar otros. Figura 98: Vista de la página profile de un usuario administrador 77 Figura 99: Vista de la página profile de un usuario no administrador Cualquier usuario puede editar sus datos básicos usando los botones de la derecha, mostrados en la Figura 100. Figura 100: Edición de datos del propio usuario Los usuarios pertenecientes al grupo administrador cuentan con dos botones extras, el primero para crear un nuevo usuario y el segundo para ver todos los usuarios existentes. En las Figuras 101 y 102 se ilustran las páginas a las que puede acceder el administrador para realizar dichas acciones. 78 Figura 101: Página de agregación de un nuevo usuario Figura 102: Página de vista de la lista de usuarios 79 7 CONCLUSIONES Y LÍNEAS FUTURAS En este Trabajo de Fin de Grado, tal y como se expuso en los objetivos, se ha logrado desarrollar una aplicación que permite el entrenamiento de los modelos de la red de visión de computadora YOLOv7 a través de una interfaz gráfica. El desarrollo de esta aplicación ha supuesto diversos retos, tanto en el ámbito personal como en lo técnico. En cuanto a lo personal, tenía conocimiento previo sobre la red de YOLOv7 y la había utilizado en numerosas ocasiones en mi anterior trabajo. Sin embargo, nunca había desarrollado un proyecto tan grande utilizando Python y no conocía previamente el paquete de Django, así que tenía mucho que aprender en ese ámbito. El desarrollo de interfaces web era nuevo para mí, sobre todo teniendo que utilizar el framework de React, del cual tenía pocos conocimientos previos. En el aspecto más técnico el trabajo presenta un reto en muchos sentidos, al contar con tantas tecnologías en diferentes niveles, supone un esfuerzo la coordinación entre ellas. El despliegue de la aplicación presentó grandes dificultades en la conexión, tanto entre los sistemas como con el hardware del dispositivo. En general, el trabajo ha sido un reto de organización y programación aplicando nuevas tecnologías y logrando la coordinación entre ellas. Se dejan abiertas las siguientes líneas de desarrollo: - Visualización de conjuntos de datos en otros formatos estandarizados y con otros tipos de etiquetas, como, por ejemplo, las máscaras de segmentación. - Entrenamientos con otros modelos de visión artificial fuera y dentro de la familia de Yolo. - Dejar la creación de grupos de usuarios en manos del administrador, para que se puedan organizar diferentes grupos de trabajo. 80 ANEXO A: INSTALACIÓN DE DOCKER Y DRIVERS DE NVIDIA En este apartado se presentan los pasos a seguir para realizar una instalación de los drivers de Nvidia, la herramienta Docker con Docker Compose y como conectar ambos entre sí. La instalación se realiza en un ordenador con sistema operativo Debian en la versión 12 y una tarjeta gráfica NVIDIA de la serie 3060. Primeramente, se procede a la instalación de los drivers de la tarjeta gráfica de Nvidia (57). Se debe modificar el archivo de configuración de APT del sistema operativo. Este indica desde donde se deben obtener los paquetes a descargar. A la primera línea se le deben de añadir los valores non-free y non-free-firmware. En la Figura 103 se ilustra el archivo de configuración APT después de realizar las modificaciones. Figura 103: Modificación del fichero de configuración de APT Después se deben actualizar la lista de paquetes disponibles con el comando: apt update. Finalmente, de estos índices se pueden descargar los paquetes necesarios con el comando: apt install nvidia-driver firmware-misc-nonfree. Después de esto es necesario reiniciar el sistema. La correcta instalación debe proporcionar una salida similar a la presentada en la Figura 104 cuando se ejecuta el comando nvidia-smi. 81 Figura 104: Versión del driver de Nvidia y Cuda instaladas en el sistema A continuación, se instalan los paquetes de Docker y Docker Compose (58). Primero, se actualizan los repositorios y se instalan las herramientas necesarias. Luego, se crea un directorio para almacenar la clave CPG de Docker, se descargan y se ajustan los permisos. Estas operaciones se realizan con los siguientes comandos: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc Después, se agrega el repositorio oficial de Docker a las fuentes de APT, especificando que los paquetes deben ser verificados con la clave GPG. Finalmente, se actualizan los repositorios para incluir los paquetes de Docker. Esto prepara el sistema para instalar Docker de manera segura. echo \ "deb [arch=$(dpkg --print-architecture) signedby=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update Después el sistema está preparado para instalar Docker y sus herramientas con el siguiente comando: sudo apt-get install docker-ce docker-ce-cli containerd.io dockerbuildx-plugin Docker Compose-plugin La instalación correcta de Docker se puede probar utilizando el comando sudo docker run hello-world que proporciona la salida que se muestra en la Figura 105.