scieee AI-readable full text Open interactive document viewer

Detección de instrumentos quirúrgicos en imágenes para cirugía laparoscópica robotizada

Sanz Gobernado, Daniel

Abstract

Departamento de Ingeniería de Sistemas y Automática

Full text

UNIVERSIDAD DE VALLADOLID ESCUELA DE INGENIERIAS INDUSTRIALES Grado en Ingeniería en Electrónica Industrial y Automática Detección de instrumentos quirúrgicos en imágenes para cirugía laparoscópica robotizada Autor: Sanz Gobernado, Daniel Valladolid, mayo 2021. Tutor(es): De la Fuente López, Eusebio Departamento de Ingeniería de sistemas y automática P á g i n a 2 | 106 P á g i n a 3 | 106 Resumen El objetivo del actual proyecto es el desarrollar un algoritmo de inteligencia artificial que, a partir del procesamiento de imágenes, sea capaz del seguimiento y detección de instrumental quirúrgico y gasas en operaciones laparoscópicas. Dicho algoritmo será integrado en un robot quirúrgico que le permitirá colaborar con el cirujano con una mayor autonomía. La detección y seguimiento del material quirúrgico evitará adicionalmente que se den situaciones de gasas accidentalmente retenidas en el interior del cuerpo, evitando así este error que puede tener consecuencias fatales para el paciente. En los algoritmos de seguimiento implementados en este TFG, se ha intentado comparar distintos tipos de redes neuronales convolucionales, buscando unos resultados lo más precisos posibles junto con velocidades de procesamiento altas y/o en tiempo real Palabras clave Cirugía laparoscópica; Redes Neuronales Convolucionales; YOLO; MATLAB; Detección de objetos en imágenes; Gasa; Instrumental quirúrgico. Abstract The aim of the current proyect is to develop an artificial intelligence algorithm that, from image processing, could be able to detect and automatic monitor gauzes and surgical instruments on laparoscopic surgeries. This algorithm will be integrated into surgical robot which will allow to collaborate with the surgeon with greater autonomy. The detection and automatic monitor of surgical material will additionally avoid situations of accidental retained surgical material inside the patient´s body, avoiding this way this error that could bring fatal consequences for the patient. On the monitoring algorithms implemented on this Final Proyect, it was tried to compare different types of convolutional neural networks, looking for the most accurate possible results along with high and/or real-time processing speeds. Keywords Laparoscopic surgery; Convolutional Neural Networks; YOLO; MATLAB; Object detection in images; Gauze; Surgical instruments. P á g i n a 4 | 106 Agradecimientos A mi familia y amigos por siempre apoyarme y ayudarme cuando lo necesitaba, a Guillermo Sánchez Brizuela por proporcionar el dataset de gasas quirúrgicas y, por último, y no menos importante, a mi tutor Eusebio por toda la ayuda brindada durante estos meses. P á g i n a 5 | 106 P á g i n a 6 | 106 Índice general 1. Introducción ......................................................................................................... 13 1.1. Cirugía laparoscópica .............................................................................. 14 1.2. Cirugía robótica ........................................................................................ 14 1.2.1. AESOP ....................................................................................... 16 1.2.2. ZEUS .......................................................................................... 17 1.2.3. Da Vinci ..................................................................................... 18 1.3. Telemedicina ............................................................................................ 21 1.4. Material quirúrgico retenido .................................................................... 22 1.5. Objetivos del TFG ..................................................................................... 23 2. Redes neuronales artificiales ............................................................................. 25 2.1. CNN (Convolutional Neural Network) ...................................................... 26 2.1.1. Arquitectura de las CNN .......................................................... 27 2.1.2. AlexNet ...................................................................................... 33 2.1.3. GoogLeNet ................................................................................ 33 2.1.4. ResNet-50 ................................................................................. 35 2.1.5. DarkNet-53 ............................................................................... 36 2.1.6. YOLO .......................................................................................... 37 2.2. Conclusiones ............................................................................................ 39 3. Desarrollo del sistema de detección ................................................................. 40 3.1. Software .................................................................................................... 41 3.1.1. MATLAB ..................................................................................... 41 3.1.2. CUDA ......................................................................................... 43 3.2. Hardware .................................................................................................. 43 3.3. Procedimiento .......................................................................................... 43 3.3.1. Dataset ...................................................................................... 44 3.3.2. Entrenamiento .......................................................................... 46 3.3.2.1. YOLOv2 ..................................................................... 48 3.3.2.2. YOLOv3 ..................................................................... 49 4. Resultados ........................................................................................................... 52 4.1. Seguimiento de gasas quirúrgicas .......................................................... 53 4.2. Seguimiento de pinzas quirúrgicas ......................................................... 59 4.3. Conclusiones ............................................................................................ 62 P á g i n a 7 | 106 5. Conclusiones y líneas futuras ............................................................................. 64 6. Estudio económico y temporal del proyecto ...................................................... 66 7. Bibliografía ........................................................................................................... 68 8. Anexos .................................................................................................................. 71 8.1. Dataset de gasas quirúrgicas .................................................................. 71 8.2. Dataset de pinzas quirúrgicas ................................................................. 72 8.3. YOLOv2 ...................................................................................................... 72 8.3.1. AlexNet ...................................................................................... 72 8.3.2. GoogLeNet ................................................................................ 73 8.3.3. ResNet-50 ................................................................................. 75 8.3.4. DarkNet-53 ............................................................................... 76 8.4. YOLOv3 ...................................................................................................... 77 8.4.1. MATLAB 2020b ......................................................................... 77 8.4.1.1. AddFirstDetectionHead ............................................ 77 8.4.1.2. AddFirstDetectionHeadAlexnet ................................ 78 8.4.1.3. AddSecondDetectionHead ....................................... 78 8.4.1.5. AlexnetFeatureExtractor ........................................... 79 8.4.1.6. GooglenetFeatureExtractor ...................................... 79 8.4.1.7. Resnet50FeatureExtractor ...................................... 80 8.4.1.8. DarknetFeatureExtractor ......................................... 80 8.4.1.9. AlexNet ...................................................................... 80 8.4.1.10. GoogLeNet .............................................................. 84 8.4.1.11. ResNet-50 ............................................................... 87 8.4.1.12. DarkNet-53 ............................................................. 90 8.4.2. MATLAB 2021a ......................................................................... 93 8.4.2.1. AlexNet ...................................................................... 93 8.4.2.2. GoogLeNet ................................................................ 95 8.4.2.3. ResNet-50 ................................................................. 98 8.4.2.4. DarkNet-53 ............................................................. 100 8.5. Detección de video ................................................................................. 103 8.5.1. YOLOv2 .................................................................................... 103 8.5.2. YOLOv3 .................................................................................... 104 8.5.2.1. MATLAB 2020b ....................................................... 104 P á g i n a 8 | 106 8.5.2.2. MATLAB 2021a ...................................................... 105 8.5.3. CalculaMediaFps .................................................................... 106 P á g i n a 9 | 106 Índice de tablas Tabla 1 - Ejemplos de filtros utilizados por capas de convolución .................................... 31 Tabla 2 - Dimensiones de entrada de las CNN implementadas ........................................ 41 Tabla 3. Última capa de extracción de propiedades ......................................................... 47 Tabla 4 Capas creadas por cada cabeza de detección ...................................................... 49 Tabla 5. Conexión entre los cabezales de detección y la red de extracción de propiedades ........................................................................................................................................... 50 Tabla 6 - Parámetros de entrenamiento para el seguimiento de Gasas. YOLOv2 ............ 53 Tabla 7 - Resultados de YOLOv2 para el seguimiento de gasas quirúrgicas ..................... 54 Tabla 8 - Parámetros de entrenamiento para el seguimiento de Gasas. YOLOv3 ............ 55 Tabla 9 - Resultados de YOLOv3 para el seguimiento de gasas quirúrgicas ..................... 55 Tabla 10 - Parámetros de entrenamiento para el seguimiento de pinzas quirúrgicas. YOLOv2 .............................................................................................................................. 59 Tabla 11 - Resultados de YOLOv2 para el seguimiento de pinzas quirúrgicas .................. 59 Tabla 12 - Parámetros de entrenamiento para el seguimiento de pinzas. YOLOv3 ......... 61 Tabla 13 - Resultados de YOLOv3 para el seguimiento de pinzas quirúrgicas .................. 61 P á g i n a 16 | 106 • Visión tridimensional a diferencia de la visión bidimensional de la cirugía laparoscópica. • Se mejora el postoperatorio, consiguiendo que los pacientes regresen a sus actividades cotidianas en un tiempo menor a 7 días • Permite la realización de operaciones por telemedicina. Inconvenientes: • Menor sensación táctil del tejido. • Movimiento limitado debido a que el cirujano debe controlar todos los brazos robóticos, siendo imposible que ayudantes le ayuden durante la cirugía. • Tiempos de operación más largos que en laparoscopia u operaciones convencionales, lo que supone un tiempo bajo anestesia mayor para el paciente, conduciendo a un mayor riesgo para este. 1.2.1. AESOP El robot AESOP o sistema endoscópico automatizado para posicionamiento óptimo, fue el primer robot utilizado en una cirugía laparoscópica, tras ser aprobado por la FDA (Food and Drug Administration) en 1994. El AESOP fue diseñado por la empresa Computer Motion estadounidense, aunque no fue la primera versión, ya que esta empresa fue fundada por una concesión con la NASA para fabricar un brazo robótico para su programa espacial. Posteriormente, este brazo fue modificado, con el objetivo de remplazar al camarógrafo laparoscópico, para sostener un laparoscopio, ya que, este robot no puede distraerse o cansarse como lo podría hacer una persona tras largas horas de cirugía, consiguiendo que la imagen de video no tiemble o se salga del campo de operación. P á g i n a 17 | 106 Ilustración 3 - Robot AESOP [9] Las primeras versiones del AESOP eran controladas por el cirujano mediante un pedal o control manual, mientras que versiones más recientes permitían un control por voz. Este control de voz es único para cada cirujano, ya que este graba los comandos de voz en una tarjeta de sonido, teniendo que ser remplazada esta tarjeta si se cambia de cirujano durante la operación. Estos comandos de voz guardan tres posiciones distintas del robot, siendo bastante útil para maniobras repetitivas como suturas. Además, AESOP cuenta con ciertas protecciones para no dañar al paciente. Al principio de la cirugía, el cirujano fija un límite al brazo del robot, consiguiendo que se evite que el brazo lo sobrepase y dañe al paciente. [10] 1.2.2. ZEUS El sistema robótico ZEUS fue desarrollado por la empresa Computer Motion con el fin de poder realizar teleoperaciones desde lugares remotos como el espacio o zonas de guerra, para esto, se basaron en un sistema maestro/esclavo, utilizando como base su robot AESOP, utilizado, en un principio, en operaciones cardíacas, aunque posteriormente se empezó a utilizar en otro tipo de especialidades como urología, ginecología, cirugía general… En octubre de 2001, la FDA concedió permiso limitado para realizar operaciones abdominales en los Estados Unidos. En la actualizad, los sistemas robóticos ZEUS y Da Vinci son los más utilizados en cuanto a cirugías cardíacas y abdominales. P á g i n a 18 | 106 Zeus consiste en dos subsistemas robóticos llamados lado-paciente y ladocirujano. Ilustración 4 - Lado-paciente (Izquierda) y lado-cirujano (Derecha) [11] El lado-paciente consiste en tres brazos robóticos independientes y acopladas a la mesa de operaciones, siendo uno de ellos el sistema robótico, comandado por voz, AESOP, mientras que los otros dos brazos has sido adaptados para sostener el instrumental quirúrgico, convirtiendo las entradas introducidas por el cirujano en movimientos quirúrgicos. Entre el instrumental quirúrgico disponible para conectar a los brazos robóticos se puede encontrar pinzas, tijeras, ganchos… Por otro lado, el lado-cirujano consiste en una consola, la cual es la encargada de transmitir los movimientos realizados por el cirujano sobre los mangos a los brazos robóticos y un monitor donde se proyecta la imagen en tres dimensiones por el brazo camarógrafo, resultando en una cirugía no tan inmersiva como se obtiene mediante el sistema robótico Da Vinci. [10] [12] 1.2.3. Da Vinci El sistema robótico Da Vinci fue desarrollado por Intuitive Surgical Inc, incorporándose este al mercado en 1999 pero no fue hasta el 4 de junio del 2000 cuando la FDA autorizo su utilización en cirugías abdominales. Esta primera versión contaba con tres brazos robóticos similares al sistema robótico ZEUS, siendo uno de ellos un brazo que sujeta la cámara, mientras que los dos brazos complementarios sostienen los instrumentos. Estos brazos cuentan a mayores con una especie de muñeca, consiguiendo así seis grados de libertad y dos grados de rotación axial. En 2003, aparece la segunda versión, implementando un cuarto brazo robótico además de un mejor control de retracción. P á g i n a 19 | 106 Ilustración 5 - Carro del paciente. Da Vinci (2003) [13] En 2006, sale al mercado el Da Vinci S consiguiendo una imagen de alta definición y una visualización de múltiples imágenes. En 2009, aparece la versión Da Vinci Si donde se introducen las llamadas nuevas tecnologías o recursos técnicos: • Capacidad para operar desde una única entrada al paciente, reduciendo las complicaciones postoperatorias. • Sellador de vasos, permite sellar y cortar vasos sanguíneos de un máximo de 7mm de diámetro. • Endograpadora, este instrumento no estaba disponible en versiones anteriores teniendo que realizarlo un asistente del cirujano. • Simulador, permitiendo a los cirujanos practicar cirugías sin necesidad de operar en animales o humanos. • Red Da Vinci En 2014, se aprueba la versión más utilizada en todo el mundo. Aunque esta versión no sería la última, si la más importante, contando como mejoras la utilización de un sistema de brazos robóticos suspendidos sobre una plataforma móvil, además de conseguir una imagen real de la zona donde está operando el cirujano debido a la incorporación de doble monitor en la consola, doble procesamiento de imagen, zoom digital de alta definición con posibilidad de 10 aumentos, consiguiendo que el cirujano obtenga movimientos intuitivos y la posibilidad de la alineación del eje visual y motor. P á g i n a 20 | 106 Ilustración 6 - Carro del paciente (Izquierda) y Consola quirúrgica (Derecha). Da Vinci Xi [13] La consola quirúrgica permite al cirujano controlar el carro del paciente mediante los pedales y los manipuladores a partir de una visión tridimensional y ampliada, además gracias a los manipuladores especiales del sistema Da Vinci se consigue reproducir en el carro del paciente todos los movimientos de la mano, muñeca y dedos del cirujano en tiempo real. Por último, Da Vinci cuenta con un componente a mayores que el sistema robótico ZEUS, este componente es la torre de visión, siendo la unidad encargada del procesamiento y elaboración de imágenes, además de portar un monitor de 24 pulgadas y todo el instrumental quirúrgico necesario para la operación. [10] [13] Ilustración 7 - Torre de visión. Da Vinci Xi [13] P á g i n a 21 | 106 1.3. Telemedicina La telemedicina, o como se está llamando actualmente eSalud, es la prestación de servicios médicos a distancia, aunque comúnmente se piensa que la telemedicina solo comprende la misma operación o cirugía de un paciente, también abarca tanto el diagnostico como el seguimiento de un paciente tras el operatorio, esto es posible gracias al desarrollo de las tecnologías de la información y las comunicaciones. [14] Una de las primeras intervenciones quirúrgicas telemáticas fue realizada por el doctor Jacques Marescaux en 2001 desde Nueva York, cuando extrajo la vesícula biliar de un paciente de 68 años a más de 14000 km de distancia, operando un brazo robótico situado en un quirófano de Estrasburgo. La telemedicina permite brindar ayuda a médicos en situaciones de emergencia o desastres, aunque la mayor ventaja es la capacidad de brindar cuidados a domicilio a ancianos o enfermos crónicos, además de empezar a ser posible una hospitalización a domicilio, esto supone un gran avance en tiempos actuales de pandemia mundial. Según como se trate los datos, se pueden distinguir tres modos de aplicación [15]: • Modo real-time: permite la comunicación en tiempo real, garantizando la interacción directa entre médico y paciente como en una consulta convencional, haciendo que la toma de decisiones sea inmediata. Además, este modo de aplicación se puede realizar mediante médicos interactuando de forma telemática y un médico presencial que se encarga de tratar las molestias del paciente, un ejemplo de esto se daba ya en 1995 entre la clínica Mayo estadounidense y el Hospital Real de Ammán en Jordania. • Modo store-and-forward: se centra en almacenar datos médicos de los pacientes para una posterior transmisión para diagnóstico. Estos datos médicos pueden ser imágenes, grabaciones de audio y video o cualquier prueba realizada al paciente como radiografía o resonancias. Es una variante de la consulta clásica en la que, en lugar de estar el médico y el paciente en el mismo lugar y tiempo, se toman las pruebas oportunas y el consultante realizará un diagnostico en el momento que esté disponible, por lo que la desventaja es no tener una respuesta inmediata. Un ejemplo de este modo en nuestro país es el “Preguntas a Expertos”, servicio proporcionado por INFOMED. • Modo híbrido: es una fusión entre los modos anteriores, en los que se envían los datos previamente al consultor y se realiza un examen en tiempo real al paciente si se considera oportuno. P á g i n a 22 | 106 1.4. Material quirúrgico retenido El material quirúrgico olvidado o retenido, describe una masa dentro del cuerpo del paciente y la consiguiente respuesta del organismo ante un cuerpo extraño, supone una grave complicación para el postoperatorio del paciente. Aunque los hospitales cuentan con sistemas para evitar este tipo de errores humanos, siempre existe un riesgo de que se produzcan. La recomendación de la AORN (Association of periOperative Registered Nurses) es seguir las siguientes medidas: • Explorar la cavidad antes del cierre. • Recuento de todo el material quirúrgico antes y después de la operación, se deben tener en cuenta compresas, gasas e instrumental quirúrgico, siendo obligatorio dejar registrado la ausencia del recuento si se produce una emergencia vital del paciente. • Los objetos punzantes deben ser contados en todos los procedimientos, además de no permitirse cortar gasas o compresas. • Todos los procedimientos se deben revisar anualmente, además de estar disponible a todo el personal del quirófano. La tasa de material quirúrgico retenido en operaciones quirúrgicas oscila entre 1:1000 y 1:5000 operaciones, debido a que algunos pacientes son asintomáticos y nunca llega a detectarse, siendo el 69% de los materiales retenidos gasas y el 31% restante instrumental quirúrgico. En un estudio presentado en el VII Congreso Europeo de Cirugía [16], donde se estudiaba los síntomas debido a gossypibomas o retención involuntaria de gasas de una serie de 10 pacientes, se obtuvieron los siguientes resultados: • El 10% de los pacientes son asintomáticos. • El 30% de los pacientes tenían la sospecha de una lesión ocupativa intraabdominal o dolor abdominal crónico secundario a íleo y/o adherencias. • El 30% se presentó con síndrome febril e íleo postoperatorio. • El 10% con síndrome febril en inmediato postoperatorio. • El 10% con síndrome febril y orificio fistuloso en sitio de herida quirúrgica. • El 10% con síndrome febril y sospecha de masa intra-abdominal. Para la eliminación del material retenido es necesario de una nueva cirugía, aunque el paciente sea asintomático, debido a los problemas que pueden causar posteriormente. Esta nueva cirugía suele ser una operación P á g i n a 23 | 106 convencional, aunque también es posible una cirugía laparoscópica, reduciendo así las complicaciones. [16] Ilustración 8 - Ejemplo de gasa retenida extraída del abdomen [17] 1.5. Objetivos del TFG En este Proyecto de Fin de Grado se pretende desarrollar un sistema de seguimiento de gasas y pinzas quirúrgicas mediante redes neuronales artificiales con el fin de que un sistema robótico sea capaz de determinar de forma autónoma los movimientos realizados por el cirujano y conseguir de esta forma poder asistirle. Gracias al seguimiento de instrumental quirúrgico se podría conseguir, en un futuro, reconocer en qué fase de la operación se encuentra el paciente y operar en consecuencia de forma autónoma. El seguimiento del material quirúrgico se realizará a través de las imágenes tomadas del laparoscopio, ubicado en la Escuela de Ingenierías Industriales, que se utilizaran para entrenar una serie de redes neuronales que permitan el seguimiento de gasas o pinzas independientemente. Para realizar esto, se debe localizar el material quirúrgico para incluir esas coordenadas con cada imagen, consiguiendo así un aprendizaje supervisado de cada una de las redes. Finalmente, se procederá a aplicar las redes entrenadas en videos laparoscópicos. P á g i n a 24 | 106 Ilustración 9 - Ejemplo de fotograma del seguimiento de gasas detectado por Resnet-50 Cada una de las redes se ha implementado mediante diferentes algoritmos, con el fin de realizar una comparativa sobre las mejores opciones a la hora de una detección eficaz para una posible futura implementación en el quirófano. En el siguiente capítulo será una introducción al marco teórico del proyecto, explicando los fundamentos de las redes neuronales artificiales, así como de varios algoritmos y del funcionamiento de las redes entrenadas utilizadas en el mismo. P á g i n a 25 | 106 2. Redes neuronales artificiales Las redes neuronales parten de la idea de imitar el funcionamiento del cerebro humano o bien de las redes neuronales de los seres humanos, es decir, el funcionamiento de neuronas conectadas que transmiten señales entre sí, consiguiendo unas salidas, inspiradas en el sistema nervioso, a partir de ciertas entradas. Estas neuronas están formadas por: dendritas, el cuerpo de la célula o soma y el axón, en términos computacionales tendríamos que el axón es el encargado de transmitir la información entre neuronas, la dendrita es la receptora de la red y el soma se encarga de sumar los valores recibidos en las dendritas. Estas neuronas conectadas entre sí formando una red de comunicaciones que pueden resolver problemas muy complejos, es a lo que llamamos red neuronal. La extrapolación de esta conexión de neuronas a las redes neuronales artificiales sería como una serie de neuronas conectadas entre sí que se encuentran organizadas en capas: una capa de entrada, capas intermedias denominadas capas ocultas y una capa de salida. Además, cada una de estas capas está formada por pesos o parámetros, los cuales se van formando y reajustando durante el entrenamiento. [13] Ilustración 10 - Capas de una red neuronal artificial Se pueden distinguir tres tipos o paradigmas diferentes de entrenamiento en las redes neuronales: • Entrenamiento no supervisado: no requiere proveer a la red con la respuesta correcta para cada entrada del almacén de entrenamiento. La red se encarga de decidir qué características utilizará para agrupar las entradas en clases según las características elegidas. • Entrenamiento supervisado: se provee a la red de un almacén de datos de entrada junto con sus correspondientes salidas deseadas. La red se encarga de producir las respuestas deseadas, en caso de no producirse, el error es propagado hacia atrás, causando que la red reajuste los P á g i n a 32 | 106 Ilustración 16 - Ejemplo de aplicar una ReLU a una matrix 4x4 • Capa de pooling: las capas de pooling o agrupación simplifican la salida llevando a cabo una disminución no lineal de la tasa de muestreo, haciendo que se necesiten menos parámetros de aprendizaje de la red, puesto que prevalecen las características más importantes que detectó cada filtro de la capa de convolución, consiguiendo también una reducción en la carga computacional. Aunque hay diferentes tipos de agrupaciones, el más utilizado, y el que ha sido usado en este proyecto, es el “max-Pooling”. El max-Pooling se encarga de recorrer las salidas de la capa anterior de izquierda a derecha y de arriba abajo, para reducir dichas salidas a la mitad. Para ello, se preserva el valor más alto de los pixeles vecinos. Ilustración 17 - Ejemplo de aplicar max-Pooling a una matriz 4x4 En la ilustración 17, se muestra el funcionamiento de dicho filtro, donde pasamos de una matriz 4x4 a una 2x2, en la submatriz verde tenemos como valores 0 y 0,6 pasando este último a la siguiente matriz por ser el más alto, se realizó el mismo procedimiento para cada una de las submatrices. • Fully-connected layer: estas capas totalmente conectadas realizan las mismas funciones que las usadas en redes neuronales artificiales habituales, ubicando y etiquetando la imagen de entrada en su respectiva clase según las activaciones recibidas de las capas anteriores. Estas capas están formadas por tantas neuronas como clases, en este caso al haber solo una clase, ya sea gasas o pinzas quirúrgicas, solo tendrán una neurona, conectada a todos los elementos de la capa anterior. Aunque la capa anterior suele ser una capa de pooling, también es necesario aplicar una capa de ReLU entre ellas para mejorar el rendimiento de la red. [20] P á g i n a 33 | 106 2.1.2. AlexNet Es un tipo de CNN, diseñada por Alex Krizhevsky junto con Ilya Sutskever y Geoffrey Hinton, fue la red ganadora del ImageNet Large-Scale Visual Recognition Challenge (ILSVRC) de 2012 consiguiendo un error del 10% menor que el segundo puesto en cuanto a la tasa de error del Top-5, tasa de tasa de no clasificar correctamente el objeto dentro de las 5 mejores predicciones. La arquitectura de AlexNet consiste en 8 capas, siendo cinco de estas 8 capas convolucionales y tres capas totalmente conectadas, además de añadir las siguientes características [21]: • Utilización de unidades lineales rectificadas o ReLU (Rectified Linear Units) en lugar de la función tanh, la cual era la función más utilizada en ese momento. • Capacidad de trabajar con múltiples GPUs. • Normalización de la respuesta local. • Capas agrupadas superpuestas, funcionan como una combinación de capas que ayuda a reducir la dimensionalidad de las imágenes, pero con la diferencia de que el filtro que realiza la agrupación se superpone entre sí. Esta red ha sido entrenada con aproximadamente 1,2 millones de imágenes de entrenamiento, 50000 imágenes de validación y 150000 imágenes de prueba, consiguiendo que sea capaz de clasificar imágenes en 1000 clases diferentes. 2.1.3. GoogLeNet GoogLeNet, también conocida como Inception V1, es la CNN presentada por Google, junto con la colaboración de varias universidades, ganadora del ILSVRC de 2014, consiguiendo un error del Top-5 de 6,67%. GoogLeNet está compuesto de 22 capas o 27 contando las capas de pooling, siendo 9 de estas capas, inception modules o módulos de comienzo. Estos módulos de comienzo se encargan de realizar convoluciones 1x1, 3x3 y 5x5 junto con max pooling de 3x3 de forma paralela, juntándose las salidas de estos para generar la salida final. P á g i n a 34 | 106 Ilustración 18 - Módulo de comienzo [22] Estas operaciones tienen la ventaja de permitir arquitecturas más profundas reduciendo el número de parámetros. Por ejemplo, si realizamos una convolución de 5x5 con 48 filtros, como se muestra en la ilustración 19, se obtienen 112,9 millones de operaciones. Ilustración 19 - Convolución 5x5 [22] Por otro lado, si antes de aplicar la misma convolución, se utiliza una convolución 1x1 con 16 filtros, resulta en 1,5 millones de operaciones de la primera convolución y 3,8 millones de la segunda, consiguiendo un total de 5,3 millones de operaciones, un valor mucho menor al obtenido sin la convolución 1x1, lo que reduce significativamente los tiempos de entrenamiento. P á g i n a 35 | 106 Ilustración 20 - Convolución de 1x1 con la posterior convolución de 5x5 [22] Como novedad, GoogLeNet sustituye las capas totalmente conectadas al final de su arquitectura, que aumentan la carga computacional, por capas de global average pooling, esta capa recibe un mapa de características de 7x7 y lo promedia a una salida de 1x1, aumentando la precisión del top-1 un 0,6% debido a reducir el número de parámetros entrenables a 0. Ilustración 21 - Ejemplo de aplicar global average pooling a una matriz 4x4 Por último, para conseguir que los gradientes se propaguen hacia atrás para reajustarse de una forma efectiva, GoogLeNet implementa unas “redes” auxiliares de clasificación, que solo actúan en el entrenamiento, conectadas a capas intermedias lo que acelera el entrenamiento, reduce el error de gradiente y añade una normalización adicional. [17] 2.1.4. ResNet-50 ResNet o Residual Network fue una CNN introducida por Microsoft, que en el año 2015 ganó la competición ILSVRC (ImageNet Large Scale Visual Recognition Challenge). Para entender porque fue una gran novedad esta red, debemos saber que a medida que se aumenta el número de capas de una red, se disminuye el nivel de error de esta, hasta cierto punto, ya que, al superar cierto número de capas aparece el llamado error de gradiente, este error consiste en que el gradiente P á g i n a 36 | 106 utilizado para calcular la tasa de error, vaya disminuyendo hasta llegar a cero tras un número de iteraciones, consiguiendo así que la red deje de aprender en el entrenamiento. Ilustración 22 - Comparativa entre una red de 56 capas y una de 20. Observándose que la tasa de error tanto en el entrenamiento como en la prueba aumente al aumentar el número de capas [23] Para evitar este error, se crea ResNet que introduce el concepto de salto de conexiones o skip connections, el cual consiste en saltarse el entrenamiento de una o un par de capas, conectando directamente con la salida de estas. Ilustración 23 - Bloque residual de ResNet Con este salto de entrenamiento de capas conseguimos que los pesos se reajusten sustituyendo las capas evitadas, consiguiendo así que se utilicen menos capas en el entrenamiento, pudiéndose implementar redes más profundas. 2.1.5. DarkNet-53 DarkNet-53 es una red neuronal convolucional que se utiliza como red base para el algoritmo para la detección de objetos, que introduciremos a continuación, YOLOv3, contiene 53 capas de convolución, las cuales se agrupan en bloques residuales, formados por una capa de convolución de 1x1 seguida de una capa de 3x3 y un salto de conexión que actúa de la misma forma que en ResNet, para ayudar a las activaciones que se propaguen a capas más profundas disminuyendo el error de gradiente. P á g i n a 37 | 106 Ilustración 24 - Arquitectura de DarkNet-53 [24] En la ilustración 24, se muestran los bloques residuales como rectángulos, teniendo entre ellos capas convolucionales para reducir el número de parámetros que se pasan al siguiente bloque residual. DarkNet-53 ha sido entrenado con más de un millón de imágenes de la base de datos ImageNet, consiguiendo clasificar objetos en 1000 clases diferentes. 2.1.6. YOLO El algoritmo YOLO (You Only Look Once) es un sistema de código abierto usado para la detección de objetos en tiempo real propuesto por Redmon et al. [25] en 2016. Este algoritmo está basado en la regresión, es decir, que a partir de dividir la imagen en regiones predice clases y bounding boxes, rectángulos imaginarios determinados por las coordenadas superiores izquierda de x e y, además, de por el ancho y altura de este rectángulo, en una sola ejecución del algoritmo, sin necesidad de back-propagation como en las redes mencionadas anteriormente. [26] La primera versión de este algoritmo se inspiró en la red GoogLeNet para clasificación de imágenes, con 24 capas convolucionales seguidas de 2 capas totalmente conectadas. La gran diferencia es la sustitución del módulo de comienzo por una capa de reducción 1x1 y una capa de convolución de 3x3. Posteriormente, se implementó una segunda versión, menos profunda y más P á g i n a 38 | 106 rápida, llamada Fast YOLO o YOLOv2, con 19 capas convolucionales en lugar de 24 y con menos filtros en dichas capas. Ilustración 25 - Arquitectura de YOLO [25] La red divide la imagen en cuadrículas, siendo la cuadrícula donde se encuentre el centro del objeto la que se encarga de detectar dicho objeto. Posteriormente, cada cuadrícula predice la probabilidad de cada clase de estar contenida en la cuadricula mediante el IoU (Intersection over Union), que indica la precisión entre la bounding box incluida en el entrenamiento y la predicha por la red mediante la siguiente fórmula: 𝐼𝑜𝑈=⁡𝐴𝑟𝑒𝑎⁡𝑑𝑒⁡𝑠𝑢𝑝𝑒𝑟𝑝𝑜𝑠𝑖𝑐𝑖ó𝑛 𝐴𝑟𝑒𝑎⁡𝑑𝑒⁡𝑢𝑛𝑖ó𝑛 Siendo el área de superposición el área que tienen ambas en común y el área de unión el área total que ocupan ambas bounding boxes. YOLO predice múltiples bounding boxes por cada cuadricula, asignando un “predictor” que se encarga de predecir un objeto basado en el mayor IoU perteneciente a la clase dada en el almacén de entrada, lo que lleva a que cada predictor se especialice siendo algunos mejores en predecir ciertos tamaños o distintas clases, lo que conlleva a una mejora en la sensibilidad total. [26] Posteriormente, Redmon et al. publica la versión 3 de YOLO en 2017. YOLOv3 tiene como red de extracción de características la misma red que su anterior versión, DarkNet, pero con la diferencia de contar con 53 capas convoluciones en lugar de 19. Con el objetivo de mejorar la sensibilidad de YOLO en esta tercera versión se utiliza una predicción en múltiples escalas lo que mejora la detección de objetos pequeños, debido al inconveniente que esto suponía en anteriores versiones. P á g i n a 39 | 106 Lo que convierte a Yolo en un algoritmo más que apropiado es su velocidad detectando objetos, aunque esta mejora en la velocidad es debido a una disminución en la precisión, pero la mejor opción cuando se requiere detección en tiempo real. Esta pérdida de precisión se resuelve con YOLOv3, a costa de una disminución en la velocidad de procesamiento debido a utilizar redes más profundas, aun así, se obtienen mejores resultados que con otros sistemas de detección. [24] [27] 2.2. Conclusiones En este capítulo se ha realizado una introducción a las redes neuronales artificiales, así como un tipo de estas, las redes neuronales convolucionales. La inteligencia artificial es una tecnología que cada vez está siendo más utilizada en muy diversos ámbitos, en el presente TFG se ha dispuesto el uso de esta tecnología en el ámbito médico, en concreto, en el de las operaciones laparoscópicas. Aunque existen diferentes softwares para entrenar e implementar redes neuronales, se ha optado por utilizar MATLAB por su gran variedad de documentación y librerías propias, además de poder realizar su uso de forma gratuito con la licencia de la Universidad de Valladolid. P á g i n a 40 | 106 3. Desarrollo del sistema de detección Para la detección de instrumental quirúrgico se ha empleado el entorno de programación MATLAB, donde se han elaborado distintos programas para el entrenamiento y su posterior despliegue en videos de cada una de las redes neuronales y algoritmos utilizados. El despliegue de los algoritmos de detección en los videos laparoscópicos sigue el siguiente diagrama: Ilustración 26 - Diagrama del sistema de detección de instrumental quirúrgico Los algoritmos de detección son capaces de detectar instrumental quirúrgico en imágenes, por lo que el video de entrada se debe dividir en fotogramas para que se pueda implementar el algoritmo. Los videos suelen tener una tasa de fotogramas por segundo de entre 24 y 30, siendo en nuestro caso de 25 fps, es decir, por cada segundo de video se encuentran 25 imágenes distintas. Cada fotograma debe redimensionarse a las dimensiones de entrada de cada CNN utilizado, P á g i n a 41 | 106 Red Dimensiones de entrada AlexNet 224x224 GoogLeNet 224x224 ResNet-50 224x224 DarkNet-53 256x256 Tabla 2 - Dimensiones de entrada de las CNN implementadas Una vez redimensionados los fotogramas, se aplica la red neuronal sobre cada uno de ellos. En cada fotograma, la red otorga una puntuación entre 0 y 1 a los objetos que detecta, si esta puntuación es menor del 0,5 interpreta que no se ha detectado el objeto. Por otro lado, si es mayor, se inserta la bounding box en las coordenadas correspondientes. Tras haber realizado lo anterior sobre todos los fotogramas, se unen las imágenes formando el nuevo video de salida, manteniendo las propiedades que tenía el video de entrada. 3.1. Software El entrenamiento de cada red neuronal profunda y su posterior implementación en los videos laparoscópicos supone una gran carga computacional, por lo que es necesario utilizar un software con gran capacidad de cómputo numérico. Debido a esto se utilizó el sistema de programación MATLAB, el cual provee un lenguaje de programación propio, además de contar con librerías propias que permiten el uso de visión artificial y entrenamiento profundo. Todas estas librerías tienen una fácil y rápida implementación desde el propio software, además, MATLAB cuenta con una serie de documentos y manuales de forma pública que facilitan también el trabajar con redes neuronales. Por otro lado, MATLAB es compatible con la tecnología CUDA de las gráficas de Nvidia, que permite el entrenamiento de las distintas redes mediante GPU (Graphics processing unit), lo que reduce la carga de trabajo en la unidad central de procesamiento o CPU, y el computo paralelo, lo que permite preparar los distintos mini lotes de entrenamiento mientras se está entrenando. Esto permite reducir drásticamente los tiempos de entrenamiento y detección de objetos. 3.1.1. MATLAB MATLAB es la abreviatura de MATrix LABoratory o laboratorio de matrices, es un sistema de cómputo numérico que ofrece un entorno de desarrollo integrado (IDE) con un lenguaje de programación propio. Entre sus posibilidades podemos encontrar la creación de interfaces de usuario, la representación de datos y funciones, la comunicación con otros lenguajes y P á g i n a 48 | 106 𝑆𝑒𝑛𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑=⁡ 𝑇𝑃 𝑇𝑃+𝐹𝑁 Además, se tiene una métrica que relaciona la precisión y la sensibilidad, F1 score, la cual mide la capacidad del modelo de identificar las muestras correctamente con su clase y de no equivocarse con cualquier otra. 𝐹1⁡𝑠𝑐𝑜𝑟𝑒=⁡ 2 1 𝑝𝑟𝑒𝑐𝑖𝑠𝑖ó𝑛+1 𝑠𝑒𝑛𝑠𝑖𝑏𝑖𝑙𝑖𝑑𝑎𝑑 Por último, AP siendo la precisión media, mide el área bajo la curva de la gráfica si representamos como x la sensibilidad y como y la precisión. 𝐴𝑃=∫𝑝(𝑟)𝑑𝑟 1 0 Siendo p(r) la curva de la gráfica precisión-sensibilidad. Por otro lado, se define mAP como la media de las precisiones medias de cada una de las clases, siendo mAP igual que AP si se tiene una sola clase como es este caso. Ilustración 31 - Ejemplo de gráfica precisión - sensibilidad para el seguimiento de pinzas quirúrgicas mediante DarkNet-53 y ResNet-50, respectivamente 3.3.2.1. YOLOv2 Para la implementación del algoritmo YOLOv2 a partir de las CNN preentrenadas se eliminan las capas de clasificación, es decir, las capas a partir de las indicadas en la tabla 3, para ello se utiliza la función de MATLAB yolov2Layers, que además de eliminar las capas de clasificación añaden las capas de detección propias de YOLOv2. Esta función pide como parámetros: el tamaño de imagen de entrada de la red, el número de clases, los anchor boxes, la red neuronal preentrenada y la última capa de extracción de propiedades. P á g i n a 49 | 106 Una vez modificada la red neuronal al algoritmo de YOLOv2, se eligen los parámetros de entrenamiento mediante la función trainingOptions que recibe como entrada: el optimizador para el cálculo del mínimo de la función de coste, se utilizará sgdm (descenso de gradiente estocástico con momento) en cada una de las redes neuronales, el ratio inicial de entrenamiento, el número máximo de épocas, el tamaño del mini lote de entrenamiento y además, se ha elegido que se mezcle todo el conjunto de entrenamiento en cada época. Por último, se entrena la red mediante la función trainYOLOv2ObjectDetector. Esta función trae como entradas: el dataset de las imágenes de entrenamiento, la red neuronal modificada y las opciones de entrenamiento. 3.3.2.2. YOLOv3 Para la implementación del algoritmo YOLOv3 a partir de las CNN preentrenadas se han añadido dos cabezas o cabezales de detección a partir de las redes anteriores. La primera cabeza incluye una capa convolucional, una capa ReLU y otra capa convolucional adicional. Por otro lado, la segunda cabeza incluye las mismas capas que la primera pero precedidas de una capa de upsample y otra capa de depth concatenation. Cabe destacar que la segunda cabeza es el doble de grande que la primera con el objetivo de mejorar la detección de elementos más pequeños. Tabla 4 Capas creadas por cada cabeza de detección Primera cabeza de detección Segunda cabeza de detección Convolutional Layer (conv1Detection1) Upsample Layer (upsample1Detection2) ReLU Layer (relu1Detection1) Depth Concatenation Layer (depthConcat1Detection2) Convolutional Layer (conv2Detection1) Convolutional Layer (conv1Detection2) ReLU Layer (relu1Detection2) Convolutional Layer (conv2Detection2) La conexión entre estas dos cabezas con cada una de las redes preentrenadas se ha realizado como se muestra en la tabla 2. La última capa de extracción de propiedades se conecta al primer cabezal de detección, mientras que la salida de este cabezal se une con la primera capa del segundo cabezal. La capa de depth concatenation se conecta a una capa intermedia de la red con el objetivo de conseguir más información relevante en el segundo cabezal. Por otro lado, en AlexNet las conexiones son algo diferentes debido a los distintos tamaños de las salidas de las capas de extracción de propiedades. P á g i n a 50 | 106 Tabla 5. Conexión entre los cabezales de detección y la red de extracción de propiedades AlexNet Source Layer Destination Layer conv5 conv1Detection1 relu1Detection1 upsample1Detection2 conv4 depthConcat1Detection2/in2 GoogLeNet Source Layer Destination Layer inception_4c-output depthConcat1Detection2/in2 inception_5b-output conv1Detection1 relu1Detection1 upsample1Detection2 ResNet50 Source Layer Destination Layer add_8 depthConcat1Detection2/in2 add_16 conv1Detection1 relu1Detection1 upsample1Detection2 P á g i n a 51 | 106 DarkNet-53 Source Layer Destination Layer res12 depthConcat1Detection2/in2 res23 conv1Detection1 relu1Detection1 upsample1Detection2 Aunque en un principio se crearon varias funciones para modificar las anteriores redes, cabe destacar que con la versión MATLAB 2021a se incorpora la función yolov3ObjectDetector, la cual realiza el mismo procedimiento que las funciones creadas en MATLAB 2020b por no existir estas mismas funciones que simplifican en gran medida el código. Esta función recibe como entradas: la red, el número de clases y las cajas de anclaje o anchor boxes estimadas y, por último, la opción ‘DetectionNetworkSource’ seguido de la última capa de extracción de propiedades (tabla 2) y de la capa de extracción de propiedades intermedia, en estas capas se añadirán los cabezales de detección. Tras modificar las redes, se entrenan las mismas mediante un custom loop o bucle customizado con la función minibatchqueue que crea y preprocesa mini lotes, posteriormente se entrena el bucle como se indica en la documentación de MATLAB. [34] P á g i n a 52 | 106 4. Resultados Se han desarrollado diferentes redes neuronales con el algoritmo YOLO tanto la versión 2 como la versión 3, a fin de realizar un estudio de varios parámetros con el fin de observar cual es la más adecuada para el seguimiento de instrumental quirúrgico. Se han obtenido los conceptos explicados en la sección 3.3.2: precisión, sensibilidad, recall, F1, mAP, además de los tiempos de procesamiento o fotogramas por segundo, debido a que estos últimos serán necesarios para comprobar una posible implementación del modelo para su utilización en tiempo real. En la detección de gasas quirúrgicas se debe tener en cuenta que la gasa no es un elemento sólido indeformable, es decir, la gasa varia su forma y tamaño a medida que el cirujano la utiliza para limpiar el interior del paciente, lo que supone también una desventaja a la hora de detectarlas. Por otro lado, en el momento que se introduce la gasa, esta se encuentra limpia o blanca, de forma que cambia su coloración según absorbe sangre, resultando en un amplio abanico de colores que pueden llegar a dificultar su detección sobre el fondo del cuerpo del paciente. Ilustración 32 - Ejemplo de distinta coloración de las gasas en el interior del paciente De la misma forma, también en la detección de pinzas quirúrgicas se debe tener en cuenta los distintos tipos o modelos que se pueden encontrar, en el dataset de gasas quirúrgicas aparece una pinza que los detectores de las redes no pueden detectar debido a no haber sido etiquetado durante el entrenamiento. Cabe destacar que también las distintas aberturas de las pinzas pueden traer problemas en la detección. P á g i n a 53 | 106 Ilustración 33 - Distintas pinzas quirúrgicas en los datasets 4.1. Seguimiento de gasas quirúrgicas Primeramente, se ha partido del entrenamiento de las CNN mediante el algoritmo YOLOv2 con el dataset de gasas quirúrgicas, para ello se ha entrenado cada una de las redes con los parámetros de la tabla 6. AlexNet GoogLeNet ResNet-50 DarkNet-50 Tasa de aprendizaje inicial 0,0001 0,0001 0,0001 0,0001 Número máximo de épocas 15 15 15 15 Tamaño de mini lotes 10 10 8 10 Tabla 6 - Parámetros de entrenamiento para el seguimiento de Gasas. YOLOv2 Aunque en un principio se quería entrenar las redes mediante los mismos parámetros de entrenamiento, en ResNet no fue posible escoger los mismos parámetros debido a no tener espacio suficiente en la GPU como consecuencia de ser una red muy profunda, esto se puede solucionar con un hardware más potente o, como en este caso, disminuyendo el tamaño del mini lote lo que supone un aumento en las iteraciones totales y en el tiempo total de entrenamiento, pero manteniendo los resultados. Estos parámetros se determinan mediante una serie de entrenamiento de prueba y error hasta adquirir buenos resultados. P á g i n a 54 | 106 Network Precision[%] Recall[%] F1 Score[%] mAP[%] FPS AlexNet 66,47 85,46 74,78 80,02 109,65 GoogLeNet 70,60 88,47 78,53 82,99 28,97 ResNet-50 81,01 88,72 84,69 85,01 13,38 DarkNet-53 88,52 92,73 90,57 90,00 22,01 Tabla 7 - Resultados de YOLOv2 para el seguimiento de gasas quirúrgicas Observando los resultados obtenidos, podemos comprobar que la mejor red para la detección de gasas con el algoritmo YOLOv2 es DarkNet-53 debido a que cuenta con los valores más altos de precisión y sensibilidad, gracias a estos también el valor de mAP es mayor, a la vez de contar con una velocidad de procesamiento de casi tiempo real. (a) (b) (c) (d) Ilustración 34 - Ejemplo del mismo fotograma detectado por AlexNet (a), GoogLeNet (b), ResNet-50 (c) y DarkNet-53 (d). YOLOv2 Observando la ilustración 34, vemos que, aunque ResNet obtiene buenos resultados, no consigue detectar completamente la gasa, además de ser la red con valores más bajos de procesamiento. Por otro lado, AlexNet y GoogLeNet P á g i n a 55 | 106 introducen demasiado fondo en la detección, siendo poco precisos a la hora de la detección. Esta baja precisión se solventa con la alta velocidad de procesamiento de estas dos redes siendo capaces de realizar detecciones en tiempo real. Posteriormente, se ha implementado el algoritmo YOLOv3 con el mismo dataset de entrenamiento. En este algoritmo, se añade un nuevo parámetro de entrenamiento, el periodo de calentamiento. Este nuevo parámetro indica el número de iteraciones para aumentar la tasa de aprendizaje exponencialmente, siguiendo la siguiente formula: 𝑡𝑎𝑠𝑎⁡𝑑𝑒⁡𝑎𝑝𝑟𝑒𝑛𝑑𝑖𝑧𝑎𝑗𝑒⁡𝑥⁡( 𝑖𝑡𝑒𝑟𝑎𝑐𝑖ó𝑛 𝑝𝑒𝑟𝑖𝑜𝑑𝑜⁡𝑑𝑒⁡𝑐𝑎𝑙𝑒𝑛𝑡𝑎𝑚𝑖𝑒𝑛𝑡𝑜)4 El periodo de calentamiento ayuda a estabilizar los gradientes en tasas de aprendizaje altas. AlexNet GoogLeNet ResNet-50 DarkNet-50 Tasa de aprendizaje inicial 0,001 0,001 0,0005 0,0005 Número máximo de épocas 15 15 15 15 Tamaño de mini lotes 10 10 10 12 Periodo de calentamiento 1000 1000 1500 2000 Tabla 8 - Parámetros de entrenamiento para el seguimiento de Gasas. YOLOv3 De forma análoga al algoritmo YOLOv2, se intentó elegir los mismos parámetros de entrenamiento en todas las redes neuronales, pero, debido a que ResNet y DarkNet son redes mucho más profundas que AlexNet y GoogLeNet, se debe aumentar el periodo de calentamiento y reducir la tasa de aprendizaje inicial para evitar un error en el gradiente durante el entrenamiento. Este error producía que el gradiente tuviera valores negativos o 0, consiguiendo que la red predijera valores no aptos de bounding boxes lo que paraba el entrenamiento. Network Precision[%] Recall[%] F1 Score[%] mAP[%] FPS AlexNet 92.11 43.86 59.42 42.92 28.15 GoogLeNet 93.95 66.17 77.65 65.08 8.95 ResNet-50 95.22 70.43 80.97 69.73 5.48 DarkNet-53 91.53 56.89 70.16 55.53 4.73 Tabla 9 - Resultados de YOLOv3 para el seguimiento de gasas quirúrgicas P á g i n a 56 | 106 Tras observar los resultados, se puede comprobar que las métricas de las redes son significativamente más elevadas, excepto en DarkNet que se reduce drásticamente la sensibilidad. Esta mejora de precisión se consigue a costa de reducir en aproximadamente un tercio la velocidad de procesamiento, resultando en que solo AlexNet es capaz de detectar gasas en tiempo real. A diferencia del algoritmo YOLOv2, las detecciones de YOLOv3 son más precisas, ajustándose a los bordes de la gasa. AlexNet y GoogLeNet siguen introduciendo demasiado fondo en la detección, mientras que ResNet y DarkNet son más eficientes. Aunque ResNet y Darknet son bastante precisas a la hora de detectar gasas, la primera es capaz de detectar más gasas con menos falsos positivos que Darknet, a la vez que es ligeramente más rápida. (a) (b) (c) (d) Ilustración 35 - Ejemplo del mismo fotograma detectado por AlexNet (a), GoogLeNet (b), ResNet-50 (c) y DarkNet-53 (d). YOLOv3 P á g i n a 57 | 106 Por otro lado, como se mencionaba en la introducción del capítulo, es necesario comprobar también la detección con distintas coloraciones de la gasa que podemos encontrar en una operación real. (a) (b) (c) (d) Ilustración 36 - Ejemplo de la detección de una gasa limpia por AlexNet (a), GoogLeNet (b), ResNet-50 (c) y DarkNet-53 (d). YOLOv2 Observando la ilustración 36, GoogLeNet detecta dos gasas diferentes, resultando en una detección errónea. Por otro lado, AlexNet consigue una detección prácticamente perfecta de la gasa, esto puede ser debido al alto contraste entre una gasa limpia el fondo lo que ayuda a una mejor detección a pesar de la baja precisión de esta red. ResNet consigue una detección aceptable, aunque introduzca fondo, mientras que DarkNet pierde una pequeña parte de la gasa. P á g i n a 64 | 106 5. Conclusiones y líneas futuras Hoy en día, la tecnología brinda una gran ayuda en las cirugías, desde el uso de sistemas robóticos que permiten realizar operaciones laparoscópicas, reduciendo así en gran medida las complicaciones postoperatorias del paciente, hasta el uso de inteligencia artificial para diagnosticar y tratar enfermedades. En este trabajo de fin de grado se ha partido de cuatro redes neuronales convolucionales distintas. En estas redes neuronales se ha implementado dos algoritmos distintos, YOLOv2 y YOLOv3, para el seguimiento y detección de instrumental quirúrgico con el fin de detectar material quirúrgico. El algoritmo resultante, aunque inicialmente está pensado para el guiado de un robot quirúrgico de forma que este pueda asistir al cirujano durante la operación, puede ser utilizado también para hacer un seguimiento de las gasas introducidas en el cuerpo del paciente y evitar la aprición de gossypibomas debido al riesgo que esto puede suponer para el paciente. Se han elaborado dos sistemas de detección independientes, uno para el seguimiento de gasas quirúrgicas y otro para el seguimiento de pinzas quirúrgicas. Para el seguimiento de gasas quirúrgicas la red que mejor elabora su función es ResNet, obteniendo buenos resultados con ambos algoritmos, seguido de cerca por Darknet, aunque este último introduce falsos positivos que no son óptimos para la detección. GoogLeNet y AlexNet obtienen resultados peores que las dos anteriores, cosa que suplen con sus mayores velocidades de procesamiento, lo que puede ser una buena opción si no se dispone de un hardware sofisticado. Por otro lado, se podría utilizar tanto YOLOv2 como YOLOv3 en una implementación en el quirófano, pero sugiero utilizar la tercera versión, debido a que detecta en mejor medida elementos más pequeños, aunque se pierda velocidad de procesamiento. Podemos concluir que se ha logrado el objetivo planteado al principio del proyecto de hacer un seguimiento de las gasas de forma fiable, pudiéndose conseguir una detección en tiempo real mejorando ligeramente el hardware utilizado. Por otro lado, para el seguimiento de pinzas quirúrgicas se obtuvieron peores resultados que su contraparte de gasas debido al reducido dataset de entrenamiento. A diferencia del seguimiento de gasas, AlexNet y GoogLeNet no son adecuadas para su utilización debido a detectar varias veces la misma pinza o no detectarla, lo que puede generar un daño en el interior del paciente si se implementaran en sistemas robóticos. DarkNet consigue detectar la pinza de forma correcta con el algoritmo YOLOv2, pero de forma no totalmente correcta en YOLOv3. Por último, aunque ResNet no obtiene las mejoras P á g i n a 65 | 106 métricas con YOLOv3 si consigue detectar la pinza quirúrgica de manera precisa y conteniéndola de manera casi perfecta, en YOLOv2 al contrario si obtiene los mejores resultados. Para finalizar, podemos concluir que aunque YOLOv2 obtiene buenos resultados en la detección, no es aceptable para su implementación en operaciones debido a su menor precisión, ya que esto puede suponer generar daños en el interior del paciente. Todo lo contrario ocurre con YOLOv3 donde la mejora en la precisión detectando las pinzas quirúrgicas consigue que su utilización sea óptima si se desea implementar en un sistema robótico, debido a reducir las probabilidades de dañar al paciente. Una vez finalizado el Trabajo Fin de grado se propone como continuación o líneas futuras para continuar el desarrollo del programa de detección de instrumental quirúrgico, se dispone lo siguiente: • Aumentar el almacén de imágenes de pinzas quirúrgicas: una mejora en el dataset supondría una mejora en los resultados, además de que GoogLeNet no detecte tantos falsos positivos, consiguiéndose una posible red óptima para su uso. • Implementar las nuevas versiones YOLOv4 y YOLOv5: estas nuevas versiones del algoritmo se presentan como más rápidas y precisas que las anteriores. • Implementar una red neuronal convolucional propia que reduzca el número de capas convolucionales, lo que resulta en una velocidad de procesamiento más alta, pero consiguiendo una especialización en la detección de instrumental quirúrgico únicamente. P á g i n a 66 | 106 6. Estudio económico y temporal del proyecto Se estima un coste económico del proyecto en 20638 euros, desglosado del siguiente modo: ➢ Ordenador (Gastos de amortización) ........................................... 375 € ➢ Material de oficina .......................................................................... 50 € ➢ Conexión de internet (*) ............................................................... 210 € ➢ Alquiler del lugar del trabajo (**) ............................................. 3150 € ➢ Licencia de MATLAB (***) ...........................................................467 € ➢ Mano de obra por el tiempo empleado (****) ...................... 16386 € ➢ TOTAL ........................................................................................ 20638 € (*) Según la consulta del precio de varias compañías del mercado en Valladolid se estima un precio medio de 30 € por mes. 30 € 𝑚𝑒𝑠∗7⁡𝑚𝑒𝑠𝑒𝑠=210⁡€ (**) Según la consulta del precio de locales en la zona de Valladolid, se estima un precio medio de 450 € mensuales. 450 € 𝑚𝑒𝑠∗7⁡𝑚𝑒𝑠𝑒𝑠=3150⁡€ (***) Según la consulta de la página de MathWorks se estima un precio de 800 € para una licencia anual del programa MATLAB. 800 € 𝑎ñ𝑜÷12⁡𝑚𝑒𝑠𝑒𝑠=66,667 € 𝑚𝑒𝑠∗7⁡𝑚𝑒𝑠𝑒𝑠=467⁡€ (****) Se estima el coste de mano de obra de un ingeniero licenciado entre 14,37 y 14,88 € por hora. 7⁡𝑚𝑒𝑠𝑒𝑠∗⁡20⁡𝑑í𝑎𝑠⁡𝑙𝑎𝑏𝑜𝑟𝑎𝑏𝑙𝑒𝑠 𝑚𝑒𝑠 ∗8 ℎ 𝑑í𝑎=1120⁡ℎ𝑜𝑟𝑎𝑠 1120⁡ℎ𝑜𝑟𝑎𝑠∗14,63 € ℎ𝑜𝑟𝑎=16386⁡€ P á g i n a 67 | 106 Por último, se muestra en el siguiente diagrama temporal del proyecto o diagrama Gantt, en el que se puede visualizar la proporción de tiempo empleado en el desarrollo de los principales apartados en los que se descompone la realización del presente proyecto. DIAGRAMA DE GANTT DEL PROYECTO Revisión bibliográfica Redacción de la parte teórica Modelado en MATLAB Redacción de la parte práctica y revisión del informe final DEDICACIÓN TOTAL 7 MESES DE TRABAJO TOTAL Línea temporal (Proporciones aproximadas del tiempo empleado) P á g i n a 68 | 106 7. Bibliografía [1] J. A. Sanz, «Breve historia de la cirugía. Hitos en el desarrollo de la cirugía moderna,» Revista española de podología, vol. 23, nº 5, pp. 176-182, 2012. [2] M. Cuesta, «Cirugía laparoscópica,» Elsevier, vol. 68, nº 4, pp. 420-423, 2000. [3] D. P. M. A. Ramos, «Apendicectomía Laparoscópica Vs Abierta,» 2 Mayo 2019. [En línea]. Available: http://drpabloalcazar.com/apendicectomia-laparoscopica-vs- abierta/. [Último acceso: Septiembre 2020]. [4] D. G. Wechter, «Laparoscopic surgery,» 15 6 2019. [En línea]. Available: https://medlineplus.gov/ency/presentations/100166_4.htm. [Último acceso: Octubre 2020]. [5] «Cirugía robótica: Historia e impacto en la enseñanza,» Actas Urológicas Españolas, vol. 35, nº 9, pp. 540-545, 2011. [6] J. G. P. Fraga, «Actualidad de la cirugía robótica,» Revista Cubana de Cirugía, vol. 56, nº 1, pp. 50-61, 2011. [7] C. M. Ramos, «Robótica y cirugía laparoscópica,» Elsevier, vol. 80, nº 4, pp. 189-194, 2004. [8] «Centro de cirugía robótica,» [En línea]. Available: http://cirugiaroboticaha.com/articulo.php?art=22. [Último acceso: Noviembre 2020]. [9] R. W. Holloway, «Emergence of robotic assisted surgery in gynecologic oncology: American perspective,» Gynecologic Oncology, vol. 114, nº 2 Suppl, pp. 24-31, 2009. [10] A. C. Dupeyral y G. H. Ballantyne, «Sistema quirúrgicos robóticos y telebóticos para cirugía abdominal,» Revista Gastroenterología Perú, vol. 23, nº 1, pp. 58-66, 2003. [11] S. Winata, «Wireless Teleoperation Control Interface of Articulated Forceps for Minimally Invasive Surgery,» Bachelors of Engineering, Nagoya, 2018. [12] J. Marescaux y F. Rubino, «The ZEUS robotic system: experimental and clinical applications,» Surgical Clinics, vol. 6, nº 83, pp. 1305-1315, 2003. [13] abex, «da Vinci Xi,» [En línea]. Available: https://www.abexsl.es/es/sistemarobotico-da-vinci/da-vinci-xi. [Último acceso: Noviembre 2020]. P á g i n a 69 | 106 [14] E. Y. P. Castaño, L. C. Carvajal, J. J. B. García y Y. S. P. Rengifo, «Estado actual de la telemedicina: una revisión de literatura,» Ingeniare, nº 20, pp. 105-120, 2016. [15] L. P. L. Cánovas, L. B. L. Cánovas y A. H. Forcelledo, «Telemedicina, impacto y perspectiva para la sociedad actual,» Universidad Médica Piñarena, vol. 14, nº 3, pp. 289-303, 2018. [16] V. H. R. Lauwers PR, «Intraperitoneal gossypibomas: the need to count sponges,» World J Surg, vol. 24, pp. 521-527, 24 Mayo 2000. [17] I. Lata, «Gossypiboma, a rare cause of acute abdomen: A case report and review of literature,» International Journal of Critical Illness & Injury Science, vol. 1, nº 2, pp. 157-160, 2011. [18] D. Anderson y G. McNeill, «Artificial Neuronal Networks Technology,» Utica, Nueva York, 1992. [19] MathWorks, «Redes neuronales convolucionales,» [En línea]. Available: https://es.mathworks.com/discovery/convolutional-neural-network-matlab.html. [Último acceso: Octubre 2020]. [20] C. &. L. W. &. J. Y. &. S. P. &. R. S. &. A. D. &. E. D. &. V. V. &. R. A. Szegedy, «Going Deeper with Convolutions,» Proceedings of the IEEE conference on computer vision and pattern recognition, pp. 1-9, 2015. [21] A. Krizhevsky, I. Sutskever y G. E. Hinton, «ImageNet Classification with Deep Convolutional Neural Networks,» Association for Computing Machinery, vol. 60, nº 6, pp. 84-90, 2017. [22] «Understanding GoogLeNet Model – CNN Architecture,» 2020 Mayo 3. [En línea]. Available: https://www.geeksforgeeks.org/understanding-googlenet-model-cnn- architecture/. [Último acceso: Enero 2021]. [23] V. Feng, «An Overview of Resnet and its variants,» towards data science, 15 Julio 2017. [En línea]. Available: https://towardsdatascience.com/an-overview-of- resnet-and-its-variants-5281e2f56035. [Último acceso: Octubre 2020]. [24] A. Kathuria, "What´s new in YOLOv3," April 2018. [Online]. Available: https://towardsdatascience.com/yolo-you-only-look-once-3dbdbb608ec4. [Accessed Octubre 2020]. [25] J. Redmon, S. Divvala, R. Girshick y A. Farhadi, «You Only Look Once: Unified, Real- Time Object Detection,» Proceedings of the IEEE conference on computer vision and pattern recognition, pp. 779-788, 2016. P á g i n a 70 | 106 [26] Manishgupta, "YOLO -You Only Look Once," 30 May 2020. [Online]. Available: https://towardsdatascience.com/yolo-you-only-look-once-3dbdbb608ec4. [Accessed Noviembre 2020]. [27] J. Redmon and A. Farhadi, "YOLOv3: An Incremental Improvement," Cornell University, Ithaca, 2018. [28] MathWorks Deep Learning Toolbox Team, «Deep Learning Toolbox Model for ResNet-50 Network,» 10 Marzo 2021. [En línea]. Available: https://es.mathworks.com/matlabcentral/fileexchange/64626-deep-learning- toolbox-model-for-resnet-50-network. [Último acceso: Marzo 2021]. [29] MathWorks Deep Learning Toolbox Team, «Deep Learning Toolbox Model for AlexNet Network,» 10 Marzo 2021. [En línea]. Available: https://es.mathworks.com/matlabcentral/fileexchange/59133-deep-learning- toolbox-model-for-alexnet-network. [Último acceso: Marzo 2021]. [30] MathWorks Deep Learning Toolbox Team, «Deep Learning Toolbox Model for GoogLeNet Network,» 10 Marzo 2021. [En línea]. Available: https://es.mathworks.com/matlabcentral/fileexchange/64456-deep-learning- toolbox-model-for-googlenet-network. [Último acceso: Marzo 2021]. [31] MathWorks Deep Learning Toolbox Team, «Deep Learning ToolboxTM Model for DarkNet-53 Network,» 10 Marzo 2021. [En línea]. Available: https://es.mathworks.com/matlabcentral/fileexchange/74600-deep-learning- toolboxtm-model-for-darknet-53-network. [Último acceso: Marzo 2021]. [32] MathWorks Deep Learning Toolbox Team, «Deep Learning Toolbox,» [En línea]. Available: https://es.mathworks.com/products/deep-learning.html. [Último acceso: Febrero 2021]. [33] «Parallel computing toolbox,» Marzo 2021. [En línea]. Available: https://es.mathworks.com/products/parallel-computing.html. [Último acceso: Marzo 2021]. [34] MathWorks Help Center, «Object Detection Using YOLOv3 Deep Learning,» Marzo 2021. [En línea]. Available: https://es.mathworks.com/help/vision/ug/objectdetection-using-yolo-v3-deep-learning.html. [Último acceso: Marzo 2021]. P á g i n a 71 | 106 8. Anexos En este anexo se presentan los códigos para entrenar y su posterior despliegue en video de las cuatro redes neuronales desarrolladas. Este código se divide en dos partes, una parte para el seguimiento y detección de gasas quirúrgicas, la segunda parte para el seguimiento y detección de instrumental quirúrgico. Cada parte se divide en tres tipos diferentes: • El primer tipo de código se encarga del entrenamiento de AlexNet, GoogLeNet, ResNet-50 y DarkNet-53 mediante el algoritmo YOLOv2. • El segundo tipo de código se encarga del entrenamiento de AlexNet, GoogLeNet, ResNet-50 y DarkNet-53 mediante el algoritmo YOLOv3. • Por ultimo, el tercer tipo se encarga del despliegue de los algoritmos para la detección de instrumental quirúrgico en video. Los datasets de entrenamiento se cargan de la misma forma en el entrenamiento de las redes, pero de distinta manera dependiendo de si es el dataset de gasas o pinzas quirúrgicas. 8.1. Dataset de gasas quirúrgicas % Reading bbox coordinates and image location from Train.txt File = fopen('Train.txt'); Format = '%s %f %f %f %f %*[^\n]'; A = textscan(File,Format,'Delimiter',',','EmptyValue',NaN); fclose(File); imageFilename = string(A{1,1}); min_x = A{1,2}; min_y = A{1,3}; max_x = A{1,4}; max_y = A{1,5}; Tabla = table(imageFilename,min_x,min_y,max_x,max_y); Tabla = rmmissing(Tabla); % Image input size 720x57628 Gauzes = {size(Tabla)}; for i=1:size(Tabla) % Adjusting bbox dimension if any exceed the image input size imageFilename2(i) = Tabla{i,1}; min_x(i) = Tabla{i,2}; min_y(i) = Tabla{i,3}; max_x(i) = Tabla{i,4}; max_y(i) = Tabla{i,5}; if min_x(i) <= 0 min_x(i) = 1; end P á g i n a 72 | 106 if min_y(i) <= 0 min_y(i) = 1; end if max_x(i) >= 720 max_x(i) = 720; end if max_y(i) >= 576 max_y(i) = 576; end Gauzes{i,1} = [min_x(i), min_y(i), max_x(i)-min_x(i), max_y(i)-min_y(i)]; end imageFilename2 = imageFilename2.'; BoundingBoxes_Gauzes = table(imageFilename2,Gauzes); BoundingBoxes_Gauzes = standardizeMissing(BoundingBoxes_Gauzes,NaN); BoundingBoxes_Gauzes = rmmissing(BoundingBoxes_Gauzes); 8.2. Dataset de pinzas quirúrgicas % Cargamos la tabla con las imagenes y bbox data = load('BoundingBoxes_Herramientas.mat'); imageFilename = data.gTruth.DataSource.Source; Pinza = data.gTruth.LabelData{:,1}; BoundingBoxes_Herramientas = table(imageFilename,Pinza); 8.3. YOLOv2 8.3.1. AlexNet % Cargamos la red alexnet preentrenada net = alexnet; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Herramientas)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Herramientas(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Herramientas(shuffledIndices(idx+1:end),:); % Obtenemos los almacenes de entrenamiento y prueba imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); Tamano_imagen = [224 224 3]; Num_Clases = 1; P á g i n a 73 | 106 % Aumentamos el almacen de datos de entrenamiento y lo escalamos a [224 224] TrainingData_aumentado = transform(trainingData,@augmentData); trainingData_aumentado_escalado = transform(TrainingData_aumentado,@(data)PreprocessDatastore(data, Tamano_imagen)); % Creamos las anchor boxes para la red Yolo trainingData_escalado = transform(trainingData,@(data)PreprocessDatastore(data, Tamano_imagen)); anchorBoxes = estimateAnchorBoxes(trainingData_escalado,5); % Fijamos las opciones y las capas de entrenamiento Opciones = trainingOptions('sgdm','InitialLearnRate',0.0001, ... 'MaxEpochs',15, 'MiniBatchSize',10,'Shuffle','every-epoch'); Capas = yolov2Layers(Tamano_imagen,Num_Clases, ... anchorBoxes,net,'relu5'); % Entrenamos la red YOLO [Detector_Objetos, informacion] = trainYOLOv2ObjectDetector(trainingData_aumentado_escalado, ... Capas, Opciones); figure plot(informacion.TrainingLoss); grid on xlabel('Number of Iterations') ylabel('Training Loss for Each Iteration') preprocessedTestData = transform(testData,@(data)PreprocessDatastore(data,Tamano_imagen); detectionResults = detect(Detector_Objetos, preprocessedTestData); [ap,recall,precision] = evaluateDetectionPrecision(detectionResults,preprocessedTestData); figure plot(recall,precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f',ap)) save('Detector_Alexnet_Yolov2.mat','Detector_Objetos'); 8.3.2. GoogLeNet % Cargamos la red GoogleNet preentrenada net = googlenet; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Herramientas)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Herramientas(shuffledIndices(1:idx),:); P á g i n a 80 | 106 inputLayer = imageInputLayer(imageInputSize,'Normalization','none', ... 'Name','data'); lgraph = replaceLayer(lgraph,'data',inputLayer); end 8.4.1.7. Resnet50FeatureExtractor function lgraph = Resnet50FeatureExtractor(net, imageInputSize) % La función Resnet50FeatureExtractor elimina las capas tras % 'add_16' y elimina cualquier data normalization % en la capa de entrada de la red. % Convert to layerGraph. lgraph = layerGraph(net); lgraph = removeLayers(lgraph, {'activation_49_relu' ... 'avg_pool' 'fc1000' 'fc1000_softmax' ... 'ClassificationLayer_fc1000'}); inputLayer = imageInputLayer(imageInputSize, ... 'Normalization','none', 'Name','data'); lgraph = replaceLayer(lgraph,'input_1',inputLayer); end 8.4.1.8. DarknetFeatureExtractor function lgraph = DarknetFeatureExtractor(net, imageInputSize) % la función DarknetFeatureExtractor elimina las capas desde % 'res23' en Darknet-53 y cualquier normalización de datos en la % capa de entrada lgraph = layerGraph(net); lgraph = removeLayers(lgraph, {'avg1' 'conv53' ... 'softmax' 'output'}); inputLayer = imageInputLayer(imageInputSize,'Normalization','none','Name', ... 'input'); lgraph = replaceLayer(lgraph,'input',inputLayer); end 8.4.1.9. AlexNet net = alexnet; % Train parameters Input_size = [224 224 3]; Num_Clases = 1; numEpochs = 15; miniBatchSize = 10; learningRate = 0.001; warmupPeriod = 1000; P á g i n a 81 | 106 l2Regularization = 0.0005; penaltyThreshold = 0.5; velocity = []; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Gauzes)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Gauzes(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Gauzes(shuffledIndices(idx+1:end),:); % Train and test datastores imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename2'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename2'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); validateInputData(trainingData); validateInputData(testData); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); Preprocess_TrainingData = transform(Augmented_TrainingData, ... @(data)PreprocessDatastore(data,Input_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {[1,2,3],[4,5,6]}; classNames = {'Gauzes'}; numClasses = size(classNames, 2); numPredictorsPerAnchor = 5 + numClasses; % Adding detection heads lgraph = AlexnetFeatureExtractor(net, Input_size); lgraph = layerGraph(lgraph); lgraph = addFirstDetectionHead(lgraph, anchorBoxMasks{1}, numPredictorsPerAnchor); lgraph = addSecondDetectionHead(lgraph, anchorBoxMasks{2}, numPredictorsPerAnchor); lgraph = connectLayers(lgraph, 'conv5', 'conv1Detection1'); lgraph = connectLayers(lgraph, 'relu1Detection1', 'upsample1Detection2'); lgraph = connectLayers(lgraph, 'upsample1Detection2', 'depthConcat1Detection2/in2'); networkOutputs = ["conv2Detection1","conv2Detection2"]; P á g i n a 82 | 106 mbqTrain = minibatchqueue(Preprocess_TrainingData, ... 2,"MiniBatchSize", miniBatchSize,"MiniBatchFcn", ... @(images, boxes, labels) createBatchData(images, ... boxes, labels, classNames), "MiniBatchFormat", ... ["SSCB", ""],"DispatchInBackground", true, ... "OutputCast", ["", "double"]); % Convert layer graph to dlnetwork. net = dlnetwork(lgraph); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, anchorBoxes, anchorBoxMasks, ... penaltyThreshold, networkOutputs); % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs); % Update the network learnable parameters using the SGDM % optimizer. [net, velocity] = sgdmupdate(net, gradients, ... velocity, currentLR); % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter, learningRatePlotter, ... iteration, currentLR, lossInfo.totalLoss); end end P á g i n a 83 | 106 % Evaluating model confidenceThreshold = 0.5; overlapThreshold = 0.5; % Create the test datastore. preprocessedTestData = transform(testData, @(data)PreprocessDatastore(data,Input_size)); % Create a table to hold the bounding boxes, scores, and labels returned by the detector numImages = size(testDataTbl, 1); results = table('Size', [0 3], 'VariableTypes', ... {'cell','cell','cell'},'VariableNames', ... {'Boxes','Scores','Labels'}); mbqTest = minibatchqueue(preprocessedTestData, 1, ... "MiniBatchSize", miniBatchSize, "MiniBatchFormat", "SSCB"); % Run detector on images in the test set and collect results. while hasdata(mbqTest) % Read the datastore and get the image. XTest = next(mbqTest); % Run the detector. [bboxes, scores, labels] = yolov3Detect(net, XTest, ... networkOutputs, anchorBoxes, anchorBoxMasks, ... confidenceThreshold, overlapThreshold, classNames); % Collect the results. tbl = table(bboxes, scores, labels, 'VariableNames', ... {'Boxes','Scores','Labels'}); results = [results; tbl]; end % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); % Plot precision-recall curve. figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f', ap)) save('Detector_Alexnet.mat','net'); save('Salidas_Red_Alexnet','networkOutputs') save('AnchorBox_Alexnet','anchorBoxes'); save('AnchorBoxMask_Alexnet','anchorBoxMasks'); P á g i n a 84 | 106 8.4.1.10. GoogLeNet net = googlenet; % Train parameters Input_size = [224 224 3]; Num_Clases = 1; numEpochs = 15; miniBatchSize = 10; learningRate = 0.001; warmupPeriod = 1000; l2Regularization = 0.0005; penaltyThreshold = 0.5; velocity = []; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Gauzes)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Gauzes(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Gauzes(shuffledIndices(idx+1:end),:); % Train and test datastores imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename2'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename2'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); validateInputData(trainingData); validateInputData(testData); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); Preprocess_TrainingData = transform(Augmented_TrainingData, ... @(data)PreprocessDatastore(data,Input_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {[1,2,3],[4,5,6]}; classNames = {'Gauzes'}; numClasses = size(classNames, 2); numPredictorsPerAnchor = 5 + numClasses; % Adding detection heads lgraph = GooglenetFeatureExtractor(net, Tamano_imagen); P á g i n a 85 | 106 lgraph = addFirstDetectionHead(lgraph, anchorBoxMasks{1}, ... numPredictorsPerAnchor); lgraph = addSecondDetectionHead(lgraph, anchorBoxMasks{2}, ... numPredictorsPerAnchor); lgraph = connectLayers(lgraph, 'inception_5b-output', ... 'conv1Detection1'); lgraph = connectLayers(lgraph, 'relu1Detection1', ... 'upsample1Detection2'); lgraph = connectLayers(lgraph, 'inception_4c-output', ... 'depthConcat1Detection2/in2'); networkOutputs = ["conv2Detection1","conv2Detection2"]; mbqTrain = minibatchqueue(Preprocess_TrainingData, 2, ... "MiniBatchSize", miniBatchSize,"MiniBatchFcn", ... @(images, boxes, labels) createBatchData(images, boxes, ... labels, classNames), "MiniBatchFormat", ["SSCB", ""], ... "DispatchInBackground", true,"OutputCast", ["", "double"]); % Convert layer graph to dlnetwork. net = dlnetwork(lgraph); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs reset(mbqTrain); shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, anchorBoxes, anchorBoxMasks, ... penaltyThreshold, networkOutputs); % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs) % Update the network learnable parameters using the SGDM % optimizer. [net, velocity] = sgdmupdate(net, gradients, ... velocity, currentLR); P á g i n a 86 | 106 % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter, learningRatePlotter, ... iteration, currentLR, lossInfo.totalLoss); end end % Evaluamos el modelo confidenceThreshold = 0.5; overlapThreshold = 0.5; % Create the test datastore. preprocessedTestData = transform(testData, @(data)PreprocessDatastore(data,Input_size)); % Create a table to hold the bounding boxes, scores, and labels returned by % the detector. numImages = size(testDataTbl, 1); results = table('Size', [0 3], 'VariableTypes', ... {'cell','cell','cell'},'VariableNames', ... {'Boxes','Scores','Labels'}); mbqTest = minibatchqueue(preprocessedTestData, 1, ... "MiniBatchSize", miniBatchSize, "MiniBatchFormat", "SSCB"); % Run detector on images in the test set and collect results. while hasdata(mbqTest) % Read the datastore and get the image. XTest = next(mbqTest); % Run the detector. [bboxes, scores, labels] = yolov3Detect(net, XTest, ... networkOutputs, anchorBoxes, anchorBoxMasks, ... confidenceThreshold, overlapThreshold, classNames); % Collect the results. tbl = table(bboxes, scores, labels, 'VariableNames', ... {'Boxes','Scores','Labels'}); results = [results; tbl]; end % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); % Plot precision-recall curve. figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f', ap)) P á g i n a 87 | 106 save('Detector_Googlenet.mat','net'); save('Salidas_Red_Googlenet','networkOutputs') save('AnchorBox_Googlenet','anchorBoxes'); save('AnchorBoxMask_Googlenet','anchorBoxMasks'); 8.4.1.11. ResNet-50 net= resnet50; % Train parameters Input_size = [224 224 3]; Num_Clases = 1; numEpochs = 15; miniBatchSize = 10; learningRate = 0.0005; warmupPeriod = 1500; l2Regularization = 0.0005; penaltyThreshold = 0.5; velocity = []; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Gauzes)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Gauzes(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Gauzes(shuffledIndices(idx+1:end),:); % Train and test datastores imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename2'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename2'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); validateInputData(trainingData); validateInputData(testData); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); Preprocess_TrainingData = transform(Augmented_TrainingData,@(data)PreprocessDatastore(data, Input_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {[1,2,3],[4,5,6]}; P á g i n a 88 | 106 classNames = {'Gauzes'}; numClasses = size(classNames, 2); numPredictorsPerAnchor = 5 + numClasses; % Adding detection heads lgraph = Resnet50FeatureExtractor(net, Input_size); lgraph = addFirstDetectionHead(lgraph, anchorBoxMasks{1}, ... numPredictorsPerAnchor); lgraph = addSecondDetectionHead(lgraph, anchorBoxMasks{2},... numPredictorsPerAnchor); lgraph = connectLayers(lgraph, 'add_16', 'conv1Detection1'); lgraph = connectLayers(lgraph, 'relu1Detection1', ... 'upsample1Detection2'); lgraph = connectLayers(lgraph, 'add_8', ... 'depthConcat1Detection2/in2'); networkOutputs = ["conv2Detection1","conv2Detection2"]; mbqTrain = minibatchqueue(Preprocess_TrainingData, ... 2,"MiniBatchSize", miniBatchSize,"MiniBatchFcn", ... @(images, boxes, labels) createBatchData(images, boxes, ... labels, classNames), "MiniBatchFormat", ["SSCB", ""], ... "DispatchInBackground", true,"OutputCast", ["", "double"]); % Convert layer graph to dlnetwork. net = dlnetwork(lgraph); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs reset(mbqTrain); shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, anchorBoxes, anchorBoxMasks, ... penaltyThreshold, networkOutputs); % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs); P á g i n a 89 | 106 % Update the network learnable parameters using the SGDM % optimizer. [net, velocity] = sgdmupdate(net, gradients, ... velocity, currentLR); % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter, learningRatePlotter, ... iteration, currentLR, lossInfo.totalLoss); end end % Evaluating model confidenceThreshold = 0.5; overlapThreshold = 0.5; % Create the test datastore. preprocessedTestData = transform(testData, ... @(data)PreprocessDatastore(data,Input_size)); % Create a table to hold the bounding boxes, scores, and labels returned by % the detector. numImages = size(testDataTbl, 1); results = table('Size', [0 3], 'VariableTypes', ... {'cell','cell','cell'},'VariableNames', ... {'Boxes','Scores','Labels'}); mbqTest = minibatchqueue(preprocessedTestData, 1, ... "MiniBatchSize", miniBatchSize, "MiniBatchFormat", "SSCB"); % Run detector on images in the test set and collect results. while hasdata(mbqTest) % Read the datastore and get the image. XTest = next(mbqTest); % Run the detector. [bboxes, scores, labels] = yolov3Detect(net, XTest, ... networkOutputs, anchorBoxes, anchorBoxMasks, ... confidenceThreshold, overlapThreshold, classNames); % Collect the results. tbl = table(bboxes, scores, labels, 'VariableNames', ... {'Boxes','Scores','Labels'}); results = [results; tbl]; end % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); P á g i n a 96 | 106 rng(0); shuffledIndices = randperm(height(BoundingBoxes_Herramientas)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Herramientas(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Herramientas(shuffledIndices(idx+1:end),:); % Obtenemos los almacenes de entrenamiento y prueba imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); Preprocess_TrainingData = transform(Augmented_TrainingData,@(data)PreprocessDatastore(data,I nput_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {anchorBoxes(1:3,:) anchorBoxes(4:6,:) }; classNames = {'Pinza'}; numClasses = size(classNames, 2); net = yolov3ObjectDetector(net, ... classNames,anchorBoxMasks,'DetectionNetworkSource', ... {'inception_5b-output','inception_4c-output'}); mbqTrain = minibatchqueue(Preprocess_TrainingData, ... 2,"MiniBatchSize", miniBatchSize,"MiniBatchFcn",... @(images, boxes, labels) createBatchData(images, boxes, ... labels, classNames), "MiniBatchFormat", ["SSCB", ""], ... "DispatchInBackground", true,"OutputCast", ["", "double"]); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; P á g i n a 97 | 106 % Custom training loop. for epoch = 1:numEpochs reset(mbqTrain); shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, penaltyThreshold); % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs); % Update the network learnable parameters using the SGDM % optimizer. [net.Learnables,velocity] = sgdmupdate(net.Learnables, ... gradients, velocity, currentLR); % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter,learningRatePlotter, iteration,... currentLR, lossInfo.totalLoss); end end % Create the test datastore. preprocessedTestData = transform(testData, ... @(data)PreprocessDatastore(data,Input_size)); results = detect(net,preprocessedTestData,'MiniBatchSize', ... miniBatchSize); % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); % Plot precision-recall curve. figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on P á g i n a 98 | 106 title(sprintf('Average Precision = %.2f', ap)) save('Detector_Googlenet.mat','net'); 8.4.2.3. ResNet-50 net = resnet50; % Train parameters Input_size = [224 224 3]; Num_Clases = 1; numEpochs = 40; miniBatchSize = 8; learningRate = 0.0005; warmupPeriod = 1500; l2Regularization = 0.0005; penaltyThreshold = 0.5; velocity = []; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Herramientas)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Herramientas(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Herramientas(shuffledIndices(idx+1:end),:); % Obtenemos los almacenes de entrenamiento y prueba imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); Preprocess_TrainingData = transform(Augmented_TrainingData,@(data)PreprocessDatastore(data,I nput_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {anchorBoxes(1:3,:) anchorBoxes(4:6,:) }; P á g i n a 99 | 106 classNames = {'Pinza'}; numClasses = size(classNames, 2); net = yolov3ObjectDetector(net, ... classNames,anchorBoxMasks,'DetectionNetworkSource', ... {'add_16','add_8'}); mbqTrain = minibatchqueue(Preprocess_TrainingData, ... 2,"MiniBatchSize", miniBatchSize,"MiniBatchFcn", ... @(images, boxes, labels) createBatchData(images, boxes, ... labels, classNames), "MiniBatchFormat", ["SSCB", ""], ... "DispatchInBackground", true,"OutputCast", ["", "double"]); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs reset(mbqTrain); shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, penaltyThreshold); % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs); % Update the network learnable parameters using the SGDM % optimizer. [net.Learnables, velocity] = sgdmupdate(net.Learnables,... gradients, velocity, currentLR); % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter, learningRatePlotter, ... iteration, currentLR, lossInfo.totalLoss); end end P á g i n a 100 | 106 % Create the test datastore. preprocessedTestData = transform(testData, @(data)PreprocessDatastore(data,Input_size)); results = detect(net,preprocessedTestData,'MiniBatchSize', ... miniBatchSize); % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); % Plot precision-recall curve. figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f', ap)) save('Detector_Resnet50.mat','net'); 8.4.2.4. DarkNet-53 net = darknet53; % Train parameters Input_size = [256 256 3]; Num_Clases = 1; numEpochs = 40; miniBatchSize = 10; learningRate = 0.0005; warmupPeriod = 1500; l2Regularization = 0.0005; penaltyThreshold = 0.5; velocity = []; rng(0); shuffledIndices = randperm(height(BoundingBoxes_Herramientas)); idx = floor(0.9 * length(shuffledIndices)); trainingDataTbl = BoundingBoxes_Herramientas(shuffledIndices(1:idx),:); testDataTbl = BoundingBoxes_Herramientas(shuffledIndices(idx+1:end),:); % Obtenemos los almacenes de entrenamiento y prueba imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,2:end)); imdstest = imageDatastore(testDataTbl{:,'imageFilename'}); bldstest = boxLabelDatastore(testDataTbl(:,2:end)); trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdstest,bldstest); % Augmenting and preprocessing trainingdata Augmented_TrainingData = transform(trainingData,@augmentData); P á g i n a 101 | 106 Preprocess_TrainingData = transform(Augmented_TrainingData,@(data)PreprocessDatastore(data,I nput_size)); % Creating anchor boxes for YOLO rng(0); trainingData_Estimation = transform(trainingData,@(data)PreprocessDatastore(data,Input_size) ); [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingData_Estimation,6); area = anchorBoxes(:, 1).*anchorBoxes(:, 2); [~, idx] = sort(area, 'descend'); anchorBoxes = anchorBoxes(idx, :); anchorBoxMasks = {anchorBoxes(1:3,:) anchorBoxes(4:6,:) }; classNames = {'Pinza'}; numClasses = size(classNames, 2); % Eliminamos las capas de clasificación, añadimos las propias de YOLOv3 lgraph = removeLayers(net, {'avg1' 'conv53' 'softmax_' 'output'}); net = dlnetwork(lgraph); net = yolov3ObjectDetector(net, ... classNames,anchorBoxMasks,'DetectionNetworkSource', ... {'res23','res12'}); mbqTrain = minibatchqueue(Preprocess_TrainingData, ... 2,"MiniBatchSize", miniBatchSize,"MiniBatchFcn",... @(images, boxes, labels) createBatchData(images, boxes, ... labels, classNames), "MiniBatchFormat", ["SSCB", ""], ... "DispatchInBackground", true,"OutputCast", ["", "double"]); % Create subplots for the learning rate and mini-batch loss. fig = figure; [lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs reset(mbqTrain); shuffle(mbqTrain); while(hasdata(mbqTrain)) iteration = iteration + 1; [XTrain, YTrain] = next(mbqTrain); % Evaluate the model gradients and loss using dlfeval and % the modelGradients function. [gradients, state, lossInfo] = dlfeval(@modelGradients,... net, XTrain, YTrain, penaltyThreshold); P á g i n a 102 | 106 % Apply L2 regularization. gradients = dlupdate(@(g,w) g + l2Regularization*w, ... gradients, net.Learnables); % Determine the current learning rate value. currentLR = piecewiseLearningRateWithWarmup(iteration, ... epoch, learningRate, warmupPeriod, numEpochs); % Update the network learnable parameters using the SGDM % optimizer. [net.Learnables, velocity] = sgdmupdate(net.Learnables,... gradients, velocity, currentLR); % Update the state parameters of dlnetwork. net.State = state; % Display progress. displayLossInfo(epoch, iteration, currentLR, lossInfo); % Update training plot with new points. updatePlots(lossPlotter,learningRatePlotter, iteration,... currentLR, lossInfo.totalLoss); end end % Create the test datastore. preprocessedTestData = transform(testData, @(data)PreprocessDatastore(data,Input_size)); results = detect(net,preprocessedTestData,'MiniBatchSize', ... miniBatchSize); % Evaluate the object detector using Average Precision metric. [ap, recall, precision] = evaluateDetectionPrecision(results, ... preprocessedTestData); % Plot precision-recall curve. figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f', ap)) save('Detector_Darknet53.mat','net'); P á g i n a 103 | 106 8.5. Detección de video En este apartado se comentan las funciones utilizadas para implementar las redes neuronales en los videos laparoscópicos, así como la función para calcular los fotogramas por segundo de cada una de las redes. 8.5.1. YOLOv2 % Elegimos el video N = 2; % Cargamos el video videoObject = VideoReader(strcat('VID000',num2str(N),'.mp4')); % Creamos el video de salida VideoSalida = VideoWriter(strcat('VideoDetectado_Yolov2_000',num2str(N)),'MPEG- 4'); VideoSalida.FrameRate = videoObject.FrameRate; open(VideoSalida); fps = 0; avgfps = []; % Extract the frame from the movie structure. for i=1:videoObject.NumFrames % Leemos el frame actual thisFrame = read(videoObject, i); % Redimensionamos el frame a la entrada de la red YOLO thisFrame = imresize(thisFrame,[224 224]); tic; % Detectamos los objetos del frame [bbox, score, label] = detect(net,thisFrame); newt = toc; fps = .9*fps + .1*(1/newt); avgfps = [avgfps; fps]; % Si encuentra el elemento, inserta la bbox y la etiqueta if (~isempty(bbox)) thisFrame = insertObjectAnnotation(thisFrame, ... 'rectangle',bbox,label); end % Guardamos las imagenes detectadas en el video de salida writeVideo(VideoSalida,thisFrame); end Framerate = CalculoMediaFps(avgfps); Texto = ['Fps = ',num2str(Framerate)]; disp(Texto); close(VideoSalida); P á g i n a 104 | 106 8.5.2. YOLOv3 8.5.2.1. MATLAB 2020b % Choose video for detection N = 2; % Loading video chosen videoObject = VideoReader(strcat('VID000',num2str(N),'.mp4')); % Creating output video OutputVideo = VideoWriter(strcat('YoloV3_VideoDetectado_000',num2str(N)),'MPEG- 4'); OutputVideo.FrameRate = videoObject.FrameRate; open(OutputVideo); fps = 0; avgfps = []; % Extract the frame from the movie structure. for i=1:videoObject.NumFrames % Reading frame thisFrame = read(videoObject, i); thisFrame = imresize(thisFrame,[224 224]); tic; % Detecting objects on frame [bbox, score, label] = detect(net,thisFrame); newt = toc; fps = .9*fps + .1*(1/newt); avgfps = [avgfps; fps]; % if object found, it inserts the bbox and label if (~isempty(score)) thisFrame = insertObjectAnnotation(thisFrame, ... 'rectangle',bbox,label); end % Saving frame on outputVideo writeVideo(OutputVideo,thisFrame); end Framerate = CalculoMediaFps(avgfps); Texto = ['Fps = ',num2str(Framerate)]; disp(Texto); close(OutputVideo); P á g i n a 105 | 106 8.5.2.2. MATLAB 2021a % Load rest of detection parameters confidenceThreshold = 0.5; overlapThreshold = 0.5; classNames = {'Gasa'}; % Choose video for detection N = 3; % Loading video chosen videoObject = VideoReader(strcat('VID000',num2str(N),'.mp4')); % Creating output video OutputVideo = VideoWriter(strcat('YoloV3_VideoDetectado_000',num2str(N)),'MPEG- 4'); OutputVideo.FrameRate = videoObject.FrameRate; open(OutputVideo); fps = 0; avgfps = []; % Extract the frame from the movie structure. for i=1:videoObject.NumFrames % Reading frame thisFrame = read(videoObject, i); thisFrame = dlarray(im2single(imresize(thisFrame, ... [224 224])),'SSCB'); executionEnvironment = "auto"; if (executionEnvironment == "auto" ... && canUseGPU) || executionEnvironment == "gpu" thisFrame = gpuArray(thisFrame); end tic; % Detecting objects on frame [bbox, score, label] = yolov3Detect(net,thisFrame, ... networkOutputs, anchorBoxes,anchorBoxMasks, ... confidenceThreshold, overlapThreshold, classNames); newt = toc; fps = .9*fps + .1*(1/newt); avgfps = [avgfps; fps]; clear yolov3Detect thisFrame = extractdata(thisFrame); thisFrame = gather(thisFrame); % if object found, it inserts the bbox and label if (~isempty(score{1})) thisFrame = insertObjectAnnotation(thisFrame, ... 'rectangle',bbox{1},label{1}); end % Saving frame on outputVideo writeVideo(OutputVideo,thisFrame);