Full text
Equation Chapter 1 Section 1 Trabajo Fin de Grado en Ingeniería de las Tecnologías de Telecomunicación Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Autor: Guadalupe Martín Moruno Tutor: Alejandro del Real Torres Dpto. Sistemas y Automática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024
iii Trabajo Fin de Grado en Ingeniería de las Tecnologías de Telecomunicación Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Autor: Guadalupe Martín Moruno Tutor: Alejandro del Real Torres Profesor Contratado Doctor Dpto. de Sistemas y Automática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024
v Trabajo Fin de Grado: Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Autor: Guadalupe Martín Moruno Tutor: Alejandro del Real Torres 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 mi familia A mis maestros
ix Agradecimientos Me gustaría agradecer a mi familia y amigos por acompañarme en este viaje, largo pero fructífero, de aprendizaje. Gracias por apoyarme y nunca dejar que me rinda. También me gustaría agradecer a mi compañero de vida, Pablo, sin tus ánimos diarios y tu paciencia nada de esto hubiera sido posible. Por último, me gustaría agradecer a mis tutores, Alejandro y Daniel por darme la oportunidad de adentrarme en el mundo de Deep Learning. Gracias de corazón. Guadalupe Martín Moruno
ÍNDICE DE TABLAS Tabla 51. Modelos YOLOv8 19 Tabla 71. Clases dataset 25 Tabla 72. Distribución dataset 26 Tabla 73. Resultados validación dataset original 30 Tabla 74. Resultados validación dataset aumentado 35 Tabla 75. Comparación resultados de validación 43
xvii ÍNDICE DE FIGURAS Figura 31. Artificial Intelligence, Machine Learning and Deep Learning 5 Figura 32. Arquitectura neurona 6 Figura 33. Arquitectura Red Neuronal Multicapa 7 Figura 34. Arquitectura Red Estándar 8 Figura 35. Arquitectura Red Convolucional 8 Figura 36. Arquitectura Red Recurrente 9 Figura 37. Gráfica Función de Costo 11 Figura 38. Proceso descenso de gradiente 11 Figura 39. Impacto tasa de aprendizaje en función de coste 12 Figura 310. Ejemplos de aumentos 13 Figura 311. Proceso de detección temprana 14 Figura 312. Desvanecimiento de gradientes 15 Figura 313. Explosión de gradientes 15 Figura 314. Transfer Learning 16 Figura 41. Arquitectura Red Convolucional 11 Figura 42. Operación de convolución 12 Figura 43. Padding 12 Figura 44. Aplicación Max. Pooling, Av. Pooling 13 Figura 45. Aplicación Flattening 13 Figura 46. Función ReLU 14 Figura 47. Función Leaky ReLU 15 Figura 48. Función Sigmoidea 15 Figura 51. Bounding Box 16 Figura 52. Bloques principales YOLO 17 Figura 53. Timeline versiones de YOLO 18 Figura 54. Arquitectura YOLOv8 20 Figura 71. Dataset Roboflow 25 Figura 72. Estructura de directorios 26 Figura 73. Diagrama circular distribución dataset 27 Figura 74. Distribución de clases en el directorio train 27 Figura 75. Distribución de clases en el directorio valid 28 Figura 76. Distribución de clases en el directorio test 28
Figura 77. Precisión en dataset original 29 Figura 78. Pérdida de clases en dataset original 30 Figura 79. Clases existentes 31 Figura 710. Clases detectadas 31 Figura 711. F1 Score con dataset original 31 Figura 712. Distribución de clases únicas en el directorio train 32 Figura 713. Co-ocurrencias de clases en el directorio train 32 Figura 714. Distribución del directorio train aumentado 33 Figura 715. Comparación de precisiones tras el aumento 34 Figura 716. Comparación de pérdida de clasificación tras el aumento 34 Figura 717. F1 Score tras el aumento 35 Figura 718. Imagen real 36 Figura 719. Imagen validada 36 Figura 720. Comparación precisiones con distintos optimizadores 37 Figura 721. Comparación pérdidas de clasificación con distintos optimizadores 37 Figura 722. F1 Score optimizador Adam 38 Figura 723. F1 Score optimizador AdamW 38 Figura 724. F1 Score optimizador RMSProp 38 Figura 725. Comparación precisiones con diferentes tamaños de batch 39 Figura 726. Comparación pérdidas de clasificación con diferentes tamaños de batch 39 Figura 727. F1 Score con batch 16 40 Figura 728. F1 Score con batch 32 40 Figura 729. F1 Score con batch 64 40 Figura 730. Comparación precisiones con diferentes tasas de aprendizaje 41 Figura 731. Comparación pérdidas de clasificación con diferentes tasas de aprendizaje 41 Figura 732. F1 Score con tasa 0.001 42 Figura 733. F1 Score con tasa 0.01 42 Figura 734. F1 Score con tasa 0.1 42 Figura 735. Imagen para detectar 43 Figura 736. Salida del detector 43
xix
Notación IA Inteligencia Artificial DL Deep Learning (Aprendizaje profundo) ML Machine Learning (Aprendizaje automático) NN Neural Network (Red neuronal)
1 1 INTRODUCCIÓN a inteligencia artificial (IA) está cada vez más presente en nuestras vidas. Ha revolucionado las industrias, la tecnología y está influyendo en nuestra vida cotidiana. Aunque presenta soluciones bastante eficaces y tiene un gran potencial, existe un rechazo por parte de la mayoría de la población. Este rechazo se debe a ciertas preocupaciones respecto a varias áreas: • Privacidad: la IA utiliza grandes conjuntos de datos, lo que hace que existan problemas sobre la seguridad y la privacidad de la información. • Empleo: la automatización de tareas genera el temor sobre la sustitución de los trabajadores por máquinas. • Pérdida de control: esta es, junto con la preocupación de la pérdida de empleo, la más extendida. Existe mucho miedo a que las máquinas desarrollen una inteligencia superior a la humana y se vuelva en nuetra contra. Aunque estos temores existan, no podemos negar que la IA ofrece numerosos beneficios que nos ayudan a resolver problemas y nos mejoran la calidad de vida. Contamos con asistententes virtuales como Alexa que nos simplifican tareas cotidianas, robots que realizan tareas repetitivas y laboriosas, aplicaciones que nos ayudan a analizar el clima para prever desastres naturales y, una de las más revolucionarias, aplicaciones para el diagnóstico y tratamiento para enfermedades, así como numerosas aplicaciones médicas que han supuesto grandes avances en medicina. 1.1 Motivación de la aplicación Aplicar IA a la medicina ha supuesto una gran revolución y un cambio positivo en esta. Antes todo el peso del diagnóstico recaía exclusivamente sobre los médicos, quienes debían analizar y evaluar los informes de los pacientes. Ahora estos cuentan con herramientas basadas en IA que analizan características específicas y los ayudan a tomar decisiones. Las intervenciones quirúrgicas son unas de las áreas médicas donde más errores se pueden cometer. Las cirugías son pocesos complejos en los que los errores derivan en consecuencias graves. Nuestra aplicación ha sido pensada para poder evitar estos problemas, desarrollando un modelo basado en una red neuronal que detecte objetos quirúrgicos en tiempo real durante una intervención. De esta forma, conseguimos quitar presión al cirujano permitiendo que esta se realice de manera más eficiente, reduciendo el número de complicaciones que se pueden dar durante la intervención. Esta aplicación podría ser utilizado en robots equipados con cámaras instalados en los quirófanos. A los datos capturados se procesan mediante el modelo de IA y se muestran al cirujano a través de una pantalla. L
Introducción 2
3 2 CONOCIMIENTOS ADQUIRIDOS ara el desarrollo de esta aplicación, he adquiridos los conocimientos necesarios en el curso Deep Learning Specialization de la plataforma Coursera. El curso consta de cinco apartados, en los cuáles se aprenden diferentes funcionalidades básicas y necesarias para enterder el Aprendizaje Profundo (Deep Learning). Estos cinco apartados son los siguientes: • Redes neurales y aprendizaje profundo. • Mejora de las redes neuronales profundas: Ajuste de hiperparámetros, regularización y optimización. • Estructuración de proyectos de aprendizaje automático. • Redes neuronales convolucionales. • Modelos de secuencia. Este curso es bastante útil para iniciarte en el mundo del Aprendizaje Profundo. Además, debes superar algunos exámenes y tareas de programación que te ayudan a aplicar lo aprendido. P
5 3 REDES NEURONALES uestra aplicación está basada en Aprendizaje Profundo, que utiliza métodos de Aprendizaje Automático basado en Redes Neuronales. Como estos términos pueden resultar un poco confusos, realizaremos una breve descripción de los mismos. 3.1 Inteligencia Artificial, Aprendizaje Automático y Aprendizaje profundo Los términos Inteligencia Artificial (Artificial Intelligence), Aprendizaje Automático (Machine Learning) y Aprendizaje Profundo (Deep Learning) se han convertido en palabras que utilizamos en nuestro día a día. Aunque suenan similares, existen diferencias entre ellos. En 1956, John McCarthy definió el concepto principal de la Inteligencia Artificial (IA). Esta se define como un estudio dedicado a la creación de sistemas que pueden realizar tareas que requieren inteligencia humana. Machine Learning (ML) es una subcategoría de la IA que permite a las máquinas aprender sin programación explícita, identificando patrones en los datos para hacer predicciones. Deep Learning (DL) es una subcategoría de ML que utiliza redes neuronales artificiales profundas para modelar y entender patrones complejos en grandes volúmenes de datos. Las redes neuronales profundas están inspiradas en la estructura del cerebro humano. Normalmente, DL requiere más poder de procesamiento y datos en comparación con ML. N Figura 31. Artificial Intelligence, Machine Learning and Deep Learning
REDES NEURONALES 12 Como observamos aparece el hiperparámetro ∝ (Alpha), este representa la tasa de aprendizaje (learning rate). La tasa de aprendizaje es el determinante de cuán grandes son los pasos que toma el descenso del gradiente en la dirección del mínimo local. Determina la velocidad con la que el algoritmo se mueve hacia los valores óptimos de la función de coste. Debido a esto, la elección de la tasa de aprendizaje es muy importante, puesto que tiene un impacto significativo en la efectividad del algoritmo. Una tasa de aprendizaje pequeña necesita muchas actualizaciones antes de alcanzar el mínimo de la función de costo. Por el contrario, una tasa de aprendizaje muy alta causa actualizaciones erróneas. Por tanto, debemos elegir un valor que alcance el mínimo rápidamente. Figura 39. Impacto tasa de aprendizaje en función de coste
13 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 3.4.3 Problemas comunes en el entrenamiento y cómo solucionarlos Al entrenar la red neuronal por primera vez, lo más probable es que no funcione como esperábamos. Nos encontraremos con modelos poco precisos, o muy precisos pero que al hacer test no lo hagan muy bien. El objetivo de este apartado es entender cómo podemos enfrentarnos a estos problemas, describiendo técnicas que los solventan. 3.4.3.1 Sobreajuste (Overfitting) El sobreajuste, conocido como overfitting, es un comportamiento del aprendizaje automático que se produce cuando el modelo de aprendizaje automático proporciona predicciones precisas para los datos de entrenamiento, pero no para los datos nuevos que nunca ha visto. El sobreajuste ocurre cuando el modelo no puede generalizarse y, en cambio, se ajusta demasiado al conjunto de datos de entrenamiento. Algunas razones por las que ocurre son las siguientes: • El tamaño de los datos de entrenamiento es demasiado pequeño y no contiene suficientes muestras de datos para representar con precisión todos los valores de datos de entrada posibles. • Los datos de entrenamiento contienen grandes cantidades de información irrelevante, denominada datos ruidosos (noisy data). • El modelo se entrena durante demasiado tiempo con un único conjunto de datos de muestra. 3.4.3.1.1. Medidas para aliviar el overfitting Existen muchas técnicas para abordar el overfitting, entre ellas se encuentran. Aumento de datos (Data Augmentation) El aumento de imágenes es un proceso de creación de nuevos ejemplos de entrenamiento a partir de los existentes. Para hacer una nueva muestra, cambia ligeramente la imagen original. Por ejemplo, cambiar el brillo, recortar la imagen o rotarla entre muchas otras técnicas. A continuación, se muestran algunos ejemplos de transformaciones aplicadas a una imagen que crearán nuevas muestras de entrenamiento. Figura 310. Ejemplos de aumentos
REDES NEURONALES 14 Para mi aplicación, este paso es crucial, dado que como veremos más adelante, mi conjunto de datos presenta un desbalance importante de clases. El aumento de datos lo realizaremos a través de la biblioteca Albumentations. Albumentations es una biblioteca de Python creada por un grupo de investigadores en 2018 de código abierto que se utiliza para el aumento de datos. A diferencia de otras bibliotecas como Augmentor o Torchvision diseñadas para el mismo propósito, Albumentations es rápida, flexible y fácil de integrar. En las tareas de localización de objetos, como nuestra aplicación, realiza transformaciones consistentes para imágenes y sus anotaciones. Esto es crucial para nuesta aplicación, puesto que cualquier transformación aplicada a la imagen también se debe aplicar de manera consistente a las coordenadas de los cuadros delimitadores. Además, cuenta con una amplia gama de transformaciones con probabilidades específicas de aplicación. Debido a esto, en nuestra aplicación realizamos el aumento de datos con esta biblioteca. Regularización La regularización es la técnica más popular para evitar el sobreajuste. Es un grupo de métodos que obliga a los algoritmos de aprendizaje a simplificar un modelo. En esta técnica, modificamos la función objetivo agregando el término penalizador, que tiene un valor más alto con un modelo más complejo. Las dos técnicas de regularización comúnmente utilizadas son la regularización L1 y la regularización L2. Detección temprana La detención temprana es una técnica de regularización utilizada para evitar el sobreajuste. Detiene la fase de entrenamiento antes de que el modelo comience a aprender en exceso el conjunto de datos de entrenamiento. Por lo general, esto se hace evaluando continuamente el rendimiento del modelo con respecto a un conjunto de datos de validación después de cada época de entrenamiento. Al observar que el rendimiento se deteriora, el proceso de entrenamiento se detiene. La detención temprana impide que el modelo memorice los patrones específicos de los datos de entrenamiento, preservando así su capacidad de generalizar a datos nuevos e invisibles. Figura 311. Proceso de detección temprana
15 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 3.4.3.2 Desvanecimiento y Explosión de Gradientes Desvanecimiento de gradientes A medida que el algoritmo de Backpropagation avanza hacia atrás desde la capa de salida hacia la capa de entrada, los gradientes a menudo se vuelven cada vez más pequeños y se acercan a cero, lo que eventualmente deja los pesos de las capas iniciales o inferiores casi sin cambios. Como resultado, el descenso del gradiente nunca converge al óptimo. Explosión de gradientes Por el contrario, en algunos casos, los gradientes siguen aumentando cada vez más a medida que avanza el algoritmo de backpropagation. Esto, a su vez, provoca actualizaciones de peso muy grandes y hace que el descenso del gradiente diverja. La solución a este problema es la elección cuidadosa de cómo se inicializan los pesos. Figura 312. Desvanecimiento de gradientes Figura 313. Explosión de gradientes
REDES NEURONALES 16 3.4.3.3 Transfer Learning Transfer Learning es una de las herramientas más poderosas en Deep Learning. Se basa en la idea de que algunas veces se puede tomar conocimiento que la red neuronal ha aprendido de una tarea para aplicar ese conocimiento a una tarea diferente. Esto es muy útil puesto que la mayoría de los problemas normalmente no tienen suficientes conjuntos de datos etiquetados para entrenar modelos tan complejos o el entrenamiento de redes neuronales con arquitecturas complejas requiere mucha carga computacional. ¿Cómo funciona? Debemos partir del modelo previamente entrenado y realizar los siguientes dos pasos: • Usar dicho modelo como extractor de características fijas. Esto se consigue congelando las capas previamente entrenadas para que sus parámetros no se actualicen. De esta forma nos aseguramos de que las características aprendidas en la tarea original se conservan y no se ajustan a la nueva tarea. Las nuevas capas clasificadoras aprenden a asignar estas características a la salida correcta para la nueva tarea. • Al entrenar el nuevo clasificador sobre las capas fijas previamente entrenadas, transferimos de manera efectiva el conocimiento aprendido de la tarea original a la nueva tarea. En nuestra aplicación aplicar esta técnica es un paso fundamental, puesto que contamos con un conjunto de datos reducido y tenemos recursos computacionales limitados. Figura 314. Transfer Learning
11 4 REDES CONVOLUCIONALES n este apartado nos centraremos en explicar con detalles las redes convolucionales, puesto que, como hemos visto antes estas utilizan datos tridimensionales para tareas de clasificación de imágenes y reconocimientos de objetos. Nuestra aplicación, al basarse en reconocimiento de objetos, utiliza este tipo de red. 4.1 Arquitectura de una Red Convolucional Las redes convolucionales están compuestas por tres tipos principales de capas: • Capa convolucional • Capa de agrupación • Capa aplanadora • Capa totalmente conectada E Figura 41. Arquitectura Red Convolucional
Redes convolucionales 12 12 4.1.1 Capa convolucional Son los componentes básicos de las redes neuronales convolucionales. Estas capas realizan una operación matemática fundamental conocida como convolución. Este proceso implica la aplicación de filtros especializados que recorren la imagen de entrada para aprender patrones visuales complejos. Los filtros son pequeñas matrices de números. Estos filtros se desplazan por la imagen y realizan una multiplicación elemento por elemento con la parte de la imagen que cubren, extrayendo características como bordes, texturas y formas. La matriz de salida de este proceso se conoce como mapa de características. Además, aplica técnicas de Padding. Este término hace referencia a la adición de píxeles adicionales alrededor de los bordes de la imagen de entrada para garantizar que la información de los bordes se trate igual que la información del centro y no se pierdan características. El objetivo principal de las capas convolucionales es la extracción de características. Figura 42. Operación de convolución Figura 43. Padding
13 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 4.1.2 Capa de agrupación (Pooling) La capa de Pooling es una operación que por lo general se aplica entre dos capas de convolución. Esta recibe en la entrada el mapa de características formado en la salida de la capa de convolución y su papel es reducir el tamaño de las imágenes y, a la vez, preservar sus características más esenciales. Entre las más utilizadas, encontramos el Max-pooling que conserva en cada paso el valor máximo de la ventana de filtro o el Average pooling que conserva el valor medio de la ventana de filtro. En el agrupamiento, no aplicamos ningún filtro a los datos de entrada, simplemente simplificamos la información con una operación matemática (Máx. o Promedio). 4.1.3 Capa de aplanadora (Flattening) Esta capa toma todo el mapa de características y lo reorganiza en un único vector largo. Las capas totalmente conectadas están diseñadas para operar con datos unidimensionales, por lo tanto, el aplanamiento es un paso necesario para la transición de los tensores multidimensionales producidos por capas convolucionales al formato requerido para capas densas. Figura 44. Aplicación Max. Pooling, Av. Pooling Figura 45. Aplicación Flattening
Redes convolucionales 14 14 4.1.4 Capa totalmente conectada (Fully-connected) Las capas totalmente conectadas son esenciales para integrar las características aprendidas en las capas de convolución a las predicciones. Sin estas capas, las CNN no podrían realizar las tareas de alto nivel que a menudo se requieren, como clasificar imágenes, detectar objetos o hacer predicciones basadas en entradas visuales. 4.2 Funciones de activación Las funciones de activación son indispensables, de lo contrario estaríamos creando un modelo lineal muy grande. Al igual que en las redes neuronales simples, también necesitamos estos términos no lineales en las redes convolucionales. Sin embargo, de todas las capas vistas, sólo las capas de convolución, las capas totalmente conectadas y las capas de salida tienen función de activación. Después de cada operación de convolución, se multiplica el resultado por una función de activación para extraer características complejas. En las capas totalmente conectadas y de salida también necesitamos una función de activación porque estamos usando las características extraídas para hacer una clasificación o una predicción, y el algoritmo tiene que aprender interacciones complejas. 4.2.1 Función de activación en capas convolucionales y totalmente conectadas Las dos funciones de activación más comunes en estas capas son ReLU y Leaky ReLU. ReLU Es la función de activación más común. Muestra la entrada directamente si es positiva, de lo contrario, muestra cero. Tiene el beneficio de reducir el tiempo de entrenamiento y mitigar el problema del desvanecimiento de gradientes. Figura 46. Función ReLU
15 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Leaky ReLU Es una variación de ReLU que permite un gradiente pequeño y distinto de cero cuando la unidad está inactiva, lo que puede ayudar a prevenir neuronas muertas durante el entrenamiento. 4.2.2 Función de activación en la capa de salida Las dos funciones de activación más comunes en esta capa son Sigmoide y Softmax. Sigmoide Produce una salida en el rango (0, 1). Ya no se utiliza comúnmente en capas ocultas debido al problema del desvanecimiento de gradientes, pero aún se utiliza para la clasificación binaria en la capa de salida. Softmax Es una función de activación que escala números en probabilidades. La salida de esta función es un vector con probabilidades de cada clase posible. Las probabilidades en el vector suman uno para todas las clases posibles. Se utiliza principalmente en problemas de clasificación de múltiples clases. Figura 47. Función Leaky ReLU Figura 48. Función Sigmoidea
YOLO 22 22 - F1 Score: es una métrica que combina precisión y recall. Esto nos permite evaluar el balance entre las dos métricas, puesto que con Precision y Recall es difícil decidir entre dos modelos cuál es el mejor. La fórmula es la siguiente: 𝐹1 𝑆𝑐𝑜𝑟𝑒= 2∗𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛∗𝑟𝑒𝑐𝑎𝑙𝑙 𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛+𝑟𝑒𝑐𝑎𝑙𝑙 Mientras más alto es su valor, mejor rendimiento tiene nuestro modelo. MÉTRICAS DE ENTRENAMIENTO - Pérdidas de Clasificación: mide cómo de correcto el modelo clasifica los objetos en las clases correctas. Un valor más bajo indica que el modelo está clasificando correctamente los objetos. - Precisión: muestra la precisión máxima alcanzada por el modelo durante el proceso de entrenamiento. Un valor más alto indica que el modelo está clasificando y detectando correctamente los objetos encontrados. 5.2.2.3 Hiperparámetros ajustables En YOLOv8, hay varios hiperparámetros configurables para conseguir mejorar la precisión y el rendimiento del modelo. En mi aplicación, los hiperparámetros que voy a configurar son los siguientes: OPTIMIZADOR (Optimizer) Los optimizadores son métodos que se utilizan para minimizar la función de pérdida. Existen varios tipos de optimizadores, pero los que vamos a probar en nuestra aplicación son los siguientes: - Adam: se encarga de ajustar cómo aprende el modelo teniendo en cuenta lo que ha aprendido en el pasado. Es el más utilizado y el más adecuado para problemas generales. - AdamW: Similar a Adam, pero también aplica técnicas que controlan el crecimiento de los parámetros y que estos no se disparen. - RMSprop: se encarga de ajustar el aprendizaje del modelo en función de los cambios recientes en los datos. Es útil si los datos cambian constantemente. TAMAÑO DEL BATCH (Batch Size) Define el número de imáges que se procesan en cada iteración durante el entrenamiento. Debemos tener en cuenta que mientras mayor sea este tamaño, el entrenamiento irá más rápido, pero la memoria requerida será mayor.
23 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador TASA DE APRENDIZAJE (Learning rate) Controla cuánto se actualizan los pesos de una red neuronal cada vez que se entrena un modelo. Este hiperparámetro debe ajustarse con cuidado, puesto que un valor alto puede hacer que el modelo se sobreajuste, mientras que un valor bajo hace que el modelo no aprenda correctamente.
Tecnologías utilizadas 24 24 6 TECNOLOGÍAS UTILIZADAS 6.1 Entorno de Desarrollo El entrenamiento de la red se ha realizado en la plataforma Google Colab. Debido a que el entrenamiento de redes neuronales es una tarea que require de muchos recursos computacionales, con Colab podemos realizarlos en tiempos razonables y de manera óptima. Esta herramienta ofrece acceso gratuito a GPUs y TPUs y además, el entorno de desarrollo incluye bibliotecas preinstaladas que ahorran bastante tiempo de instalación y configuración de dependencias. Además, tiene tarifas premium que dan acceso a mejores GPUs y tiempos de ejecución mayores. En mi caso, tuve que optar por la opción premium para poder desarrollar la aplicación de manera eficiente, pues la versión gratuita reparte las GPUs disponibles entre todos los usuarios conectados, por tanto la disponibilidad de recursos era muy limitada. Al ser un entorno en la nube y permitirte trabajar desde cualquier lugar con integración de Google Drive, hace que sea muy útil. Para realizar el estudio del dataset y las gráficas de análisis de los entrenamientos se ha utilizado Visual Studio Code. Se ha elegido este editor debido a la familiaridad con él y por su sencillez. 6.2 Lenguaje de programación. El lenguaje de programación elegido es Python. Este lenguaje se ha convertido en uno de los más utilizados para el desarrollo de Deep Learning. Permite el uso de datasets de forma sencilla, tiene bibliotecas para el procesamiento y análisis de datos como Pandas o Matplotlib y una gran variedad de frameworks especializados para implementar rede neuronales como Pytorch o TensorFlow. Debido a que implementa las bibliotecas y los frameworks necesarios para nuestra aplicación, nos hemos decidido por él. 6.3 Framework. Pytorch es una Plataforma sencilla que nos permite integrarlo fácilmente con Python. Proporciona todas las herramientas necesarias para enfrentarnos a los problemas de Deep Learning y funciones específicas para realizar el entramiento y test de las redes neuronales.
25 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 7 DESARROLLO DE LA APLICACIÓN En este apartado vamos a explicar los diferentes pasos que hemos seguido para la implementación de la aplicación, así como las técnicas aplicadas y la discusión de valores para la optimización de la misma. 7.1 Estudio del conjunto de datos (dataset) Como he comentado anteriormente, el conjunto de datos lo hemos descargado de Roboflow, una plataforma que contiene muchos datasets de acceso público. Este dataset contiene cinco clases, las cuales en las anotaciones vienen representadas con un número. La siguiente tabla muestra dicha relación. CLASE NÚMERO ASIGNADO CLAMP (PINZA) 0 GRIPPED FORCEPS (PINZAS DE AGARRE) 1 HOOK (GANCHO) 2 SURGICAL-TOOL (HERRAMIENTA QUIRÚRGICA) 3 TUBING (TUBO) 4 Tabla 71. Clases dataset Figura 71. Dataset Roboflow
Desarrollo de la aplicación 26 26 La distribución de directorios de este conjunto de datos es la siguiente: En el directorio ‘train’ se encuentran los datos que se utilizan en el entrenamiento, contiene la mayor parte de los datos de nuestro conjunto de datos. Dentro de cada directorio hay dos directorios: images, con las imágenes en formato jpg que se utilizarán y labels que contiene archivos txt con las anotaciones en formato YOLO de cada imagen. En ‘valid’ se encuentran los datos que permiten evaluar el modelo mientras se entrena para ajustar los hiperparámetros. Finalmente, el directorio ‘test’ contiene los datos que se utilizarán para evaluar el rendimiento del modelo una vez que este ha sido entrenado Ahora vamos a contar las imágenes que hay en cada directorio de nuestro dataset para ver si su distribución es equilibrada. TOTAL IMÁGENES 435 IMÁGENES EN TRAIN 381 IMÁGENES EN VALID 36 IMÁGENES EN TEST 18 Tabla 72. Distribución dataset Figura 72. Estructura de directorios
27 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Esta distribución es correcta para nuestro problema, puesto que el dataset es pequeño y no necesitamos muchas imágenes de pruebas para evaluar el rendimiento de nuestra red. Ahora, dentro de cada directorio, voy a analizar cuántas imágenes hay de cada clase para comprobar si hay desbalance. Como se observa en las siguientes gráficas, existe un gran desbalance entre las diferentes clases, existiendo muchas más imágenes de la clase Gripped Forceps que de las demás. El desbalance es crucial en la carpeta train cuando entrenamos nuestra red neuronal, pues como ya hemos mencionado anteriormente, aquí es donde nuestra red aprende a distinguir las diferentes clases, por lo tanto, verá más ejemplos de Gripped Forceps y esto puede suponer un problema. Figura 73. Diagrama circular distribución dataset Figura 74. Distribución de clases en el directorio train
Desarrollo de la aplicación 28 28 Debido al desbalance, vamos a estudiar cómo se comporta nuestra red ante este dataset, analizaremos si existe overfitting y si debemos aplicar técnicas de aumento de datos. Figura 75. Distribución de clases en el directorio valid Figura 76. Distribución de clases en el directorio test
29 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 7.2 Comportamiento de modelo con el dataset En YOLOv8 el entrenamiento se realiza de la siguiente forma: !yolo task=detect mode=train model=yolov8n.pt data=Surgical-Tool-Detection-5/data.yaml epochs=40 imgsz=640 freeze=9 plots=True batch=16 optimizer= Adam lr0=0.01 El comando anterior entrena la red neuronal con el modelo YOLOv8n empleando Transfer Learning. Transfer Learning se aplica congelando las capas del backbone para utilizar los pesos preentrenamos yolov8n.pt, que contienen los pesos al entrenar la red COCO con este modelo, como ya comentamos anteriormente. De esta forma, al contar con recursos limitados, nos beneficiamos de lo que ya ha aprendido y nuestra carga computacional es menor. Además, utiliza como optimizador Adam, tamaño del batch de 16 y una tasa de aprendizaje de 0,01. El resultado de este entrenamiento es el siguiente: Resultado del entrenamiento Como se observa en las siguientes gráficas la precisión del entrenamiento es bastante mejorable, pues sólo se obtiene un 73,27%. Figura 77. Precisión en dataset original
Desarrollo de la aplicación 30 30 Resultado de validación En la siguiente tabla se evalúa el porcentaje de precisión y recall diferenciados por clase que se ha obtenido durante la validación del entrenamiento. Como podemos observar, los resultados en las clases Surgical Tool, y sobre todo Tubing son bastantes mejorables respecto al recall, esto se debe a que está detectanto un número muy alto de falsos negativos. Clase Precisión (%) Recall (%) Clamp 80 100 Gripped-Forceps 78,5 77,3 Hook 34,1 66,7 Surgical Tool 73,6 25 Tubing 100 0 Tabla 73. Resultados validación dataset original Figura 78. Pérdida de clases en dataset original
31 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Las siguientes imágenes afirman la detección de falsos negativos, puesto que como se observa en la imagen de la izquierda la imagen que se ha utilizado en el entrenamiento muestra tres clases, pero al validarlas no detecta ninguna. Además, podemos comprobar en la gráica de F1 Score, que el rendimiento es bastante mejorable, pues su valor es bajo. Nos encontramos con un problema de overfitting, puesto que la precisión del entrenamiento mejora con las épocas, pero los resultados de valdación son bastante malos. Para solventar este problema aplicaremos aumento de datos. Figura 79. Clases existentes Figura 710. Clases detectadas Figura 711. F1 Score con dataset original
Desarrollo de la aplicación 38 38 Resultado de validación Analizando los resultados obtenidos, tenemos una mejor precisión y menor pérdida en AdamW, y aunque el valor más alto de F1 Score es más bajo que en Adam, lo obtiene de manera más constante y con mayor tasa de confianza en AdamW. Por lo tanto, el optimizador elegido será AdamW y continnuaremos nuestros entrenamientos con él. Figura 722. F1 Score optimizador Adam Figura 723. F1 Score optimizador AdamW Figura 724. F1 Score optimizador RMSProp
39 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 7.5 Discusión del tamaño del batch Los tamaños del batch a probar serán 16, 32 y 64. Resultado del entrenamiento Figura 725. Comparación precisiones con diferentes tamaños de batch Figura 726. Comparación pérdidas de clasificación con diferentes tamaños de batch
Desarrollo de la aplicación 40 40 Resultado de validación A la vista de los resultados con tamaño del batch 16 obtenemos una mejor precisión en entrenamiento, aunque la pérdida es un poco más alta, esto es insignificante. El valor de F1 Score aunque es más bajo, llega a su máximo en una tasa de confianza mucho mayor que en las otras dos. Esto tiene sentido porque como nuestro dataset es pequeño, tener un número de batch pequeño proporciona más actualizaciones de gradiente por época, permitiendo tener una convergencia controlada. Figura 727. F1 Score con batch 16 Figura 728. F1 Score con batch 32 Figura 729. F1 Score con batch 64
41 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador 7.6 Discusión de la tasa de aprendizaje Finalmente, para continuar con la optimización de nuestro modelo, probaremos distintos valores de la tasa de aprendizaje. Estos valores son 0.1, 0.01 y 0.001. Resultado del entrenamiento Figura 730. Comparación precisiones con diferentes tasas de aprendizaje Figura 731. Comparación pérdidas de clasificación con diferentes tasas de aprendizaje
Desarrollo de la aplicación 42 42 Resultado de validación Analizando los resultados llegamos a la conclusión clara de que la tasa de aprendizaje óptima es 0.001. Observamos que con esta tasa nuestro modelo es más preciso en el entrenamiento del modelo y en las pruebas de validación obtiene un mayor valor de F1 Score en un mayor grado de confianza. Figura 732. F1 Score con tasa 0.001 Figura 733. F1 Score con tasa 0.01 Figura 734. F1 Score con tasa 0.1
43 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Mediante esta tabla comparativa podemos apreciar la evolución de las métricas de nuestro modelo tras las modificaciones realizadas. Clase MODELO INICIAL MODELO FINAL Precisión (%) Recall (%) Precisión (%) Recall (%) Clamp 80 100 77,3 100 Gripped-Forceps 78,5 77,3 84,3 73 Hook 34,1 66,7 57,3 100 Surgical Tool 73,6 25 100 0 Tubing 100 0 95,2 50 Tabla 75. Comparación resultados de validación 7.7 Test de rendimiento Para comprobar la efectividad del modelo, vamos a pasarle a nuestro modelo una imagen y este nos devolverá las imágenes con los objetos localizados y la clase. Para predecir utilizamos el siguiente commando: !yolo task=detect mode=predict model=../best.pt source=Surgical-Tool-Detection-5/test/images/ La imagen de la izquierda se corresponda con la imagen que le hemos proporcionado a nuestro modelo para que detecte lo que aparezca, y la imagen de la derecha es lo que nuestra aplicación nos devuelve una vez analizada. Figura 735. Imagen para detectar Figura 736. Salida del detector
Conclusiones 44 44 8 CONCLUSIONES La mayor dificultad para afrontar este proyecto ha sido la escasez de datos médicos que existen. Esto es debido a que este tipo de datos son muy delicados por la privacidad de los pacientes. Al tener un dataset tan escaso, no hemos podido ajustar el modelo más de lo deseado. También nos hemos encontrado con un gran problema de recursos computacionales, pues todo lo hemos tenido que hacer a través de Google Colab, con las consecuencias que eso conlleva: entornos que se desconectan y asignación limitada de GPU. A pesar de estas limitaciones hemos podido alcanzar una precisión del 95% durante el entrenamiento y un balance entre recall y precisión de validación, como se observa en la gráfica de F1 Score final. Llegar a este resultado ha sido posible gracias a la aplicación de la técnica del aumento de datos para solventar el problema de overfitting inicial y el ajuste de hiperparámetros. A través de los resultados, hemos podido llegar a las siguientes conclusiones: • YOLOv8n es un modelo bastante eficaz en tareas de detección en situaciones de limitaciones computacionales, reduciendo el tiempo de entrenamiento y validación. • La técnica del aumento de datos es fundamental para mejorar el rendimiento del modelo, aunque al aumentar debemos ser ciudaddosos, puesto que incrementa bastante el tiempo de entrenamiento. • La calidad del conjunto de datos y dedicar tiempo a analizar estos, es crucial para que nuestro modelo funcione correctamente. • Debido a la gran cantidad de hiperparámetros y la variedad de capas existentes, encontrar la solución óptima de un problema de Deep Learning es un desafío que requiere mucho tiempo y la disposición de muchos recursos computacionales. Finalmente, me gustaría aclarar que, aunque en este trabajo se ha logrado entrenar un modelo específico para la tarea de detección de objetos quirúrquicos, en la práctica, estos pesos entrenados estarían destinados a ser implementados en un robot para cirugía asistida por ordenador y se convertiría en una herramienta fundamental para el cirujano.
45 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador ANEXO Instalar YOLOv8 !pip install ultralytics==8.0.196 from IPython import display display.clear_output() import ultralytics ultralytics.checks() Descargar dataset !pip install roboflow from roboflow import Roboflow rf = Roboflow(api_key="YTfTuf0WA2uEp3LCIHvO") project = rf.workspace("dd-xsqu0").project("surgical-tool-detection-tsfnl") version = project.version(5) dataset = version.download("yolov8") Filtrado de clases import os import shutil #directorios base_dir = os.getcwd() train_image_dir = os.path.join(base_dir, 'Surgical-Tool-Detection-5', 'train', 'images') train_labels_dir = os.path.join(base_dir, 'Surgical-Tool-Detection-5', 'train', 'labels') #directorios que creo para guardar las imagenes filtradas filt_image_train_dir = os.path.join(base_dir, 'filtrar', 'train', 'images') filt_labels_train_dir = os.path.join(base_dir, 'filtrar', 'train', 'labels') os.makedirs(filt_image_train_dir, exist_ok=True) os.makedirs(filt_labels_train_dir, exist_ok=True)
Anexo 46 46 #función que verifica si un archivo contiene las clases deseadas def contiene_clases(archivo_label, clases_incluidas, clase_1, clase_4): contiene_clase_1 = False contiene_clase_4 = False contiene_clases_incluidas = False with open(archivo_label, 'r') as file: clases_encontradas = set(int(line.strip().split()[0]) for line in file) contiene_clase_1 = clase_1 in clases_encontradas contiene_clase_4 = clase_4 in clases_encontradas contiene_clases_incluidas = all(clase in clases_incluidas for clase in clases_encontradas) return (contiene_clases_incluidas or (contiene_clase_1 and contiene_clase_4)) and not (contiene_clase_1 and not contiene_clase_4) #función para filtrar las imágenes y etiquetas def filtrar(image_dir, label_dir, filt_image_dir, filt_label_dir, clases_incluidas, clase_1, clase_4): for archivo_label in os.listdir(label_dir): label_path = os.path.join(label_dir, archivo_label) if contiene_clases(label_path, clases_incluidas, clase_1, clase_4): archivo_imagen = archivo_label.replace('.txt', '.jpg') image_path = os.path.join(image_dir, archivo_imagen) if os.path.exists(image_path): shutil.copy(image_path, os.path.join(filt_image_dir, archivo_imagen)) shutil.copy(label_path, os.path.join(filt_label_dir, archivo_label)) print("Imágenes filtradas correctamente.") clases_incluidas = [0, 2, 3, 4] clase_1 = 1 clase_4 = 4 filtrar(train_image_dir, train_labels_dir, filt_image_train_dir, filt_labels_train_dir, clases_incluidas, clase_1, clase_4)
47 Detección de objetos quirúrgicos en imágenes médicas para cirugía asistida por ordenador Aumento de datos #librerías necesarias import albumentations as A import cv2 import os #aplico transformaciones transform = A.Compose([ A.GaussNoise(var_limit=(10.0, 50.0), p=0.5), A.GaussianBlur(blur_limit=(3, 7), p=0.5), A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.5), A.RandomGamma(gamma_limit=(80, 120), p=0.5), A.ISONoise(color_shift=(0.01, 0.05), intensity=(0.1, 0.5), p=0.5), A.ToGray(p=0.5), A.HueSaturationValue(hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=20, p=0.5) ]) def read_yolo_labels(label_path): #leo el archivo con el formato de etiquetas yolov8 with open(label_path, 'r') as f: labels = [line.strip() for line in f.readlines()] return labels def write_yolo_labels(label_path, labels): #defino formato de etiquetas yolov8 with open(label_path, 'w') as f: for label in labels: f.write(f"{label}\n") def main(image_path, label_path, output_image_dir, output_label_dir, augmented_num): #leo imagenes image = cv2.imread(image_path) #leo etiquetas labels = read_yolo_labels(label_path) base_name = os.path.splitext(os.path.basename(image_path))[0] for i in range(augmented_num): #aplico transformaciones transformed = transform(image=image) transformed_image = transformed['image']