Full text
Proyecto Fin de Carrera Ingeniería de Telecomunicación Formato de Publicación de la Escuela Técnica Superior de Ingeniería Autor: F. Javier Payán Somet Tutor: Juan José Murillo Fuentes Dep. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2013 Trabajo Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Reconocimiento facial basado en redes neuronales convolucionales Autor: Ildefonso Jiménez Silva Tutores: Rubén Martín Clemente Sergio Antonio Cruces Álvarez Dpto. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2018
Trabajo Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Reconocimiento facial basado en redes neuronales convolucionales Autor: Ildefonso Jiménez Silva Tutores: Rubén Martín Clemente Profesor Titular Sergio Antonio Cruces Álvarez Catedrático de Universidad Dpto. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2018
Trabajo Fin de Grado: Reconocimiento facial basado en redes neuronales convolucionales Autor: Ildefonso Jiménez Silva Tutores: Rubén Martín Clemente Sergio Antonio Cruces Álvarez El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores: Presidente: Vocal/es: Secretario: acuerdan otorgarle la calificación de: El Secretario del Tribunal Fecha:
Agradecimientos En primer lugar, me gustaría agradecer a mis padres por su continuo apoyo en todo momento y por confiar siempre en mí. También me gustaría dar las gracias a Cristina quien me ha acompañado en tantos momentos difíciles y me ha conseguido aportar motivación siempre que la he necesitado. No puedo olvidarme de los compañeros con los que he tenido el gusto de compartir camino de estudios: Daniel, Javier, Jesús, Sergio y mis compañeros de intensificación Abraham, Diego y Guillermo. Finalmente, me gustaría agradecer a mi tutor, Rubén, quien además de aconsejarme y darme orientaciones para completar este proyecto, me ayudó a tener un primer contacto con un tema que desde entonces me ha llamado mucho la atención: las redes neuronales. Ildefonso Jiménez Silva Sevilla, 2018 I
Resumen El reconocimiento facial representa un importante campo de estudio en la actualidad debido a la variedad de aplicaciones para las que puede ser empleado, que van desde la mejora de la seguridad o aplicaciones industriales hasta utilidades en dispositivos personales. Por otro lado, las redes neuronales han experimentado en los últimos años un incremento de su uso en todo tipo de sectores gracias a su adaptación a diferentes problemas. En este proyecto se pretende hacer un estudio de algunos de los algoritmos que usan los sistemas de reconocimiento facial y, posteriormente, implementar un sistema que aúne este área con la de las redes neuronales, donde estas sean de utilidad en algunas fases que componen todo el proceso, así como realizar una evaluación de los resultados. III
Notación RCuerpo de los números reales kvkNorma del vector v A>Transpuesto de A e.o.c. En cualquier otro caso enúmero e sen Función seno arctg Función arco tangente cot Función cotangente senh Función seno hiperbólico cosh Función coseno hiperbólico tanh Función tangente hiperbólica sgn Función signo ∂y ∂xDerivada parcial de yrespecto a x x◦Notación de grado, xgrados. σ2 XVarianza de la variable aleatoria X ≷Menor o mayor bxcFunción piso XI
1 Introducción 1.1 Motivación del proyecto En la sociedad actual se está produciendo un continuo desarrollo de las tecnologías de automatización. Los sistemas automáticos se han ido utilizando poco a poco en una gran cantidad de aplicaciones, tanto industriales, como en el hogar. La biometría también ha sido un campo que ha experimentado un gran avance tecnológico, estando cada vez más presente en la sociedad actual donde la importancia de la seguridad está siendo un factor clave. Es por este motivo que los sistemas de verificación biométrica estén en continuo desarrollo, surgiendo sistemas de reconocimiento de huella dactilar, de voz o incluso de retina. En este proyecto, se va a realizar un estudio de algunas de las tecnologías utilizadas en el desarrollo de uno de los sistemas biométricos que mayor desarrollo están mostrando actualmente, los sistemas de reconocimiento facial. Los sistemas de reconocimiento facial emplean algoritmos para reconocer la identidad de personas que aparecen en imágenes o en vídeos a partir de sus características fisiológicas. Esto permite que cuenten con una amplia variedad de posibilidades de uso, como pueden ser la identificación de personas para sistemas de vigilancia, control de acceso o desbloqueo de dispositivos. El reconocimiento facial representa un campo que cuenta con el interés de una gran cantidad de grandes compañías. Ya la empresa Apple ha incluido un sistema de reconocimiento facial en su iPhone X para el desbloqueo del dispositivo o la autenticación de usuario; Google cuenta con un sistema capaz de reconocer rostros en las imágenes almacenadas y Facebook ha implementado un sistema para la identificación de personas en fotografías donde no han sido etiquetadas. En definitiva, un sistema de reconocimiento facial pretende imitar la capacidad de un ser humano para diferenciar rostros. Y es en este punto donde entra en común con las redes neuronales, las cuales tienen como objetivo desarrollar cierta inteligencia artificial y una capacidad de análisis de los datos, a partir de imitar el funcionamiento del cerebro humano. El interés de aunar ambos conceptos representa uno de los mayores motivos por los que este proyecto ha sido llevado a cabo, donde una serie de redes neuronales serán implementadas para conseguir un sistema capaz de diferenciar personas tanto en imagen como en vídeo imitando, en cierto modo, el comportamiento de un ser humano. 1.2 Objetivos El objetivo de este proyecto es implementar un sistema de reconocimiento facial que haga uso de redes neuronales en algunas de sus etapas y luego evaluar su funcionamiento. Se desarrollará una interfaz que permita hacer uso de los algoritmos establecidos para analizar tanto imágenes como vídeos. El sistema presentará una fase previa a su funcionamiento en la que será necesario un entrenamiento donde analice una fuente de imágenes que le servirán de referencia para la posterior identificación de los rostros que sean analizados. Para desarrollar el sistema, será necesaria una documentación técnica de diferentes métodos usados en el reconocimiento facial, así como una introducción a los fundamentos de redes neuronales, que tomarán importancia en ciertas etapas del sistema. 1
2Capítulo 1. Introducción 1.3 Estructura de la memoria La presente memoria se ha organizado en un total de seis capítulos: 1. Introducción: Que recoge la motivación y los objetivos de este proyecto, así como su estructura. 2. Estado de la tecnología del reconocimiento facial: Capítulo en el que se hará una revisión de la tecnología del reconocimiento facial, pasando por cada una de las etapas que la componen, introduciendo ejemplos de algunos métodos de especial relevancia. 3. Redes neuronales artificiales: Capítulo que recoge una introducción a las redes neuronales artificiales, haciendo un estudio de su estructura general y un repaso de algunos casos concretos que tendrán un papel importante en la implementación del sistema. 4. Sistema propuesto: En esta sección se describirán las herramientas de desarrollo del sistema, así como la serie de algoritmos que son implementados. 5. Validación experimental: Se realizará una serie de pruebas para fijar algunos parámetros del sistema y analizar los resultados obtenidos. 6. Conclusiones: Última sección donde se recogerán los conceptos más importantes que han resultado del proyecto y una visión de las líneas futuras para el sistema propuesto.
2 Estado de la tecnología del reconocimiento facial 2.1 Introducción histórica Los sistemas de reconocimiento facial se podrían considerar como relativamente modernos. Uno de sus pioneros fue Woodrow Bledsoe, quien junto con su grupo de investigación desarrolló una técnica que fue denominada “reconocimiento facial hombre-máquina”, a mediados de los años 60. Esta técnica requería una clasificación de las fotografías de las caras que eran digitalizadas manualmente. Además, también era necesario indicar las coordenadas donde se encontraban los rasgos faciales dentro de cada imagen, entre los que destacaban los ojos, la nariz y la línea del pelo. Posteriormente, era necesario registrar los datos recogidos junto con el nombre de la persona en una base de datos. Finalmente, con una fotografía de una cara desconocida, el sistema utilizaría un método basado en distancias euclídeas para obtener la imagen en la base de datos que más se aproxime a la fotografía en cuestión [1]. Un acontecimiento importante en el campo del reconocimiento facial se dio en 1988, cuando L. Sirobich y M. Kirby [ 2 ] aplicaron la técnica del análisis de componentes principales (PCA) al problema del reconocimiento facial y del que posteriormente surgiría el método de Eigenfaces de la mano de Turk y Pentland en 1991 [ 3 ]. Aunque hubo unos años en los que el campo del reconocimiento facial no presentó importantes desarrollos, en los años 90 se convirtió en una actividad en crecimiento debido al aumento de la investigación comercial, así como el alza de los clasificadores basados en redes neuronales en tiempo real [ 4 ]. Desde entonces, han surgido numerosos tipos de algoritmos, así como variaciones de los primeros, que aún en la actualidad siguen utilizándose. 2.2 Procesamiento de reconocimiento facial El problema del reconocimiento facial se basa en una identificación de patrones visuales. Generalmente, un sistema de reconocimiento facial se divide en cuatro fases (ver Figura 2.1) detección, preprocesado, extracción de características y comparación y clasificación. La primera fase de detección facial consiste en localizar el rostro en la imagen. A continuación, se realiza un preprocesado a la imagen para alinear y normalizar los rostros, de manera que se obtengan unas características geométricas en común con todas las imágenes que se procesen. Luego, se lleva a cabo una extracción de características faciales para obtener información útil que será usada para distinguir unas caras de otras. Finalmente, el vector de características obtenido será comparado con la base de datos para decidir a quién pertenece el rostro [5]. Todas y cada una de las etapas presentan una gran importancia ya que el resultado final dependerá de la precisión con la que se han obtenido las características, lo cual depende tanto de la localización del rostro en la imagen como de la normalización de la imagen. En los siguientes apartados se hará un estudio individual de las fases que se llevan a cabo a lo largo del funcionamiento de un sistema de reconocimiento facial. 3
4Capítulo 2. Estado de la tecnología del reconocimiento facial Detecci´on Preprocesado Extracci´on de caracter´ısticas Comparaci´on y clasificaci´on Base de datos Figura 2.1 Diagrama de un sistema de reconocimiento facial. 2.3 Detección facial La detección facial es el proceso mediante el cual el sistema localiza la posición de los rostros de personas en una imagen o fotograma1. Aunque en los inicios del reconocimiento facial, el proceso de localización de la cara en la imagen tenía que ser llevada a cabo manualmente, en la actualidad existen diferentes técnicas de detección automática, con diferentes fundamentos. Aunque en algunas ocasiones es difícil clasificar algunos métodos, existen autores que han realizado clasificaciones para diferenciar entre algunos métodos y otros, según su fundamento. En el trabajo de Yang et al. [ 6 ] se distinguen los métodos que se basan en el conocimiento, los basados en características invariantes, los que hacen uso de plantillas o modelos y los que se basan en apariencia. Como no es posible nombrar y describir todos los métodos de detección existentes debido a la gran variedad de algoritmos (que además a su vez presentan variantes), se van a nombrar tres que se han considerado de relevancia en este proyecto. Para los dos primeros se hará un breve repaso de su funcionamiento y para el último se entrará en profundidad ya que será el método que se utilice para implementar el sistema de reconocimiento facial de este proyecto. El primer método será el propuesto por Viola y Jones, que representa el algoritmo pionero en detección facial. A continuación, se hará un repaso de un método que hace uso de redes neuronales con el objetivo de ver un ejemplo sobre cómo se pueden implementar estas para la tarea específica de la detección facial. Finalmente, se estudiará con mayor detalle el método HOG, uno más moderno que puede ser utilizado para la detección de cualquier tipo de objeto en una imagen a partir de unas plantillas. 2.3.1 Algoritmo de Viola-Jones El algoritmo que fue propuesto por Paul Viola y Michael Jones [ 7 ] fue la primera técnica de detección facial que, además, presentaba una rapidez y precisión apta para su uso en tiempo real. Este método se basa en utilizar una serie de características denominadas Haar-like features, que son obtenidas a partir del producto escalar entre una imagen y un patrón simple del mismo tamaño que la imagen, como se muestra en la Figura 2.2. Este producto escalar tendrá signo positivo o negativo según cómo se describa el propio patrón, del que existe una gran variedad. Este resultado será el que se compare para determinar si se encuentra o no una cara en una zona determinada de la imagen. Dado un conjunto de Haar-like features y un conjunto de imágenes positivas y negativas 2 , Viola y Jones implementaron una variante de AdaBoost para el entrenamiento de su clasificador. Este se trata de un algoritmo de aprendizaje creado por Freund y Schapire [ 8 ] que consiste en obtener un clasificador fuerte a partir de varios clasificadores débiles que fijarán unos umbrales que, puestos en forma de cascada como se muestra en la Figura 2.3, formarán la región delimitada para una clase. Una vez haya sido entrenado este clasificador, será posible distinguir si el resultado de calcular las Haar-like features se corresponde con un rostro en cierto lugar de la imagen. 2.3.2 Redes Neuronales Convolucionales Como se verá en el Capítulo 3, las redes neuronales representan una herramienta que tiene infinidad de aplicaciones, y aunque en este proyecto no se van a utilizar para la tarea de la detección facial, se va a hacer 1Un fotograma se puede definir como cada una de las imágenes de las que se suceden en una película cinematográfica. 2 En el ámbito de machine learning, se conocen como datos positivos y negativos aquellos que describen o no una clase para la que se va a entrenar un modelo, respectivamente.
2.3 Detección facial 5 Figura 2.2 Aplicación de Haar-like features a una imagen [7]. x h1 hj hn Pmin(ε) wt,1 wt,j wt,n . . . . . . Figura 2.3 Diagrama simplificado del proceso de AdaBoost. un breve repaso a título informativo de un método que hace uso de redes neuronales convolucionales (CNN) para detectar caras en imágenes. A diferencia de en el último paso del reconocimiento facial, que consiste en la clasificación de rostros, el uso de redes neuronales para la detección de rostros en imágenes se trata de una tarea más difícil de llevar a cabo [9]. En la actualidad existen diferentes trabajos en los que se han implementado redes neuronales para la detección facial [ 9 ] [ 10 ], y en este apartado se hará un breve repaso del trabajo presentado en 2015 por H. Li et al. [ 11 ], donde proponen aplicar una serie de CNN en forma de cascada para detectar rostros directamente de la propia imagen, aprendiendo automáticamente las características en las que se tiene que basar. Concretamente, en su trabajo describen 6 CNN, 3 de las cuales son de detección y 3 de calibración, estando intercaladas unas con otras. Las redes de detección, especializadas en 12, 24 y 48 píxeles de resolución respectivamente, son utilizadas para localizar posibles caras en la imagen. Luego, la correspondiente red de calibración se encargará de procesar las ventanas detectadas en las imágenes para ajustar su tamaño y localización para acercarse a una cara potencial cercana. En definitiva, se encarga de calibrar los recuadros que rodean las caras para ajustarlos a la cara que es posible que puedan contener. De esta forma, la cascada irá acercándose a las localizaciones de los rostros en la imagen hasta detectarlas por completo. Este proceso se ve representado en la Figura 2.4. En capítulos posteriores se estudiarán con mayor detalle la estructura y funcionamiento de las redes neuronales así como algunas formas de entrenarlas para conseguir buenos resultados con imágenes y datos que no hayan sido previamente analizados.
6Capítulo 2. Estado de la tecnología del reconocimiento facial Figura 2.4 Estructura del detector facial basado en CNN en cascada [11]. 2.3.3 Método de los histogramas de gradientes orientados A diferencia del algoritmo de Viola-Jones, existen algoritmos que no han sido desarrollados específicamente para la detección facial, sino para la detección de objetos en general. Sin embargo, estos también pueden presentar un buen comportamiento si se ajustan al problema de la detección de rostros. Uno de estos métodos puede ser el de los histogramas de gradientes orientados (HOG), que fue presentado por Navneet Dalal y Bill Triggs en 2005 [ 12 ] y que, a pesar de que lo utilizaron para la detección de peatones en imágenes, es un método que puede ser utilizado para la detección de cualquier objeto, según se modele. Este método se basa en la evaluación de histogramas locales normalizados de la orientación del gradiente de una imagen dividida en cuadrículas (que presentan un determinado solape entre ellas), que serán llamadas células. Para cada una de las divisiones de la imagen, se calcula el histograma de las direcciones de gradiente y, combinándolos, se obtiene la representación completa de la imagen. Además, con el objetivo de mejorar la invarianza frente a las condiciones de iluminación y sombras, se realiza una normalización de contraste a partir del cálculo de la energía de los histogramas locales de grandes regiones espaciales denominadas bloques. Los histogramas normalizados de los bloques son los conocidos como descriptores HOG y son los que proporcionan la información sobre cómo cambia la intensidad de la imagen debido a los bordes contenidos en ella. Se verá a continuación la relación de los pasos que se sigue con el método HOG. Transformación a escala de grises El primer paso para llevar a cabo el método de HOG es disponer de una imagen de entrada que esté representada por un único canal de color, es decir, en escala de grises. Si la imagen está en escala de grises por defecto, este paso será inmediato. En cambio, si la imagen inicial es a color, habrá que recurrir a la Ecuación (2.1) para realizar la conversión [13]. Y=0.299R+0.588G+0.114B(2.1) Donde Y representa el valor de un píxel en escala de grises, y R , G y B , son los valores de intensidad de los canales rojo, verde y azul en dicho punto, respectivamente. Cálculo de gradientes El vector gradiente de una magnitud indica la dirección de máxima variación y su módulo indica el grado de variación de la misma. Para cada píxel, se asignará un valor de gradiente, en función del valor de los píxeles que los rodean, generalmente, los situados arriba, abajo, a la izquierda y a la derecha del píxel en cuestión. En una imagen, el gradiente ∇f indica el nivel de variación de la intensidad de la imagen y su dirección. Por definición, se sabe que el gradiente es: ∇f=Gx Gy= ∂f ∂x ∂f ∂y (2.2) Por lo que a partir de ello se podrá obtener la magnitud del gradiente M(x,y)para un píxel (x,y): M(x,y) = k∇fk=qkGxk2+ Gy 2≈kGxk+ Gy (2.3) Donde Gx,GyyM(x,y)son matrices del mismo tamaño que la imagen foriginal (M×N).
2.3 Detección facial 7 La dirección del gradiente α(x,y)dado un píxel (x,y)se define como: α(x,y) = arctgGx Gy(2.4) El cálculo de las derivadas para una imagen completa puede ser implementado usando máscaras de diferentes tamaños, existiendo algunas ya predefinidas como la de Roberts, la de Prewitt o la de Sobel [14]. División en bloques Con los gradientes de la imagen completa calculados, se procede a hacer una división de la imagen en celdas de un tamaño variable que puede ser, entre otros, de 6×6,8×8o16 ×16 píxeles, según el objetivo fijado. Por otro lado, hay que designar un rango de orientaciones en un intervalo concreto. Se puede usar un gradiente “sin signo” con un intervalo de 0 ◦ a 180 ◦ , o gradiente “con signo” con un intervalo de 0 ◦ a 360 ◦ . Para el intervalo fijado, se hace una partición en subregiones que, tras varias pruebas, se comprobó que el número que presenta mejores resultados es un total de 9 particiones para un gradiente sin signo. Luego, para cada celda de la imagen, se hace un recuento de cada uno de los gradientes, obteniendo un histograma con el número de gradientes situados en cada subregión. Por ejemplo, para el caso de gradientes sin signo con 9 particiones, se contarán cuántos puntos de cada bloque presentan un gradiente entre 0 ◦ y 20 ◦ , cuántos entre 20◦y 40◦, etc, obteniendo un histograma por cada bloque en los que se ha dividido la imagen [12]. Normalización de histogramas El último paso antes de la detección del rostro será la normalización de los histogramas calculados anteriormente. Esto es llevado a cabo con el objetivo de paliar las variaciones indeseadas producidas por los diferentes niveles de iluminación, ya que es muy común que una imagen presente zonas más oscuras o con más sombras que otras. Por este motivo, la normalización de los histogramas habrá que hacerla adaptándose a la iluminación de las diferentes partes de la imagen. Para ello, se toman los histogramas calculados para cada celda y se agrupan en bloques para trabajar con cada uno de ellos individualmente. Para cada bloque, se concatenan sus histogramas de forma que se obtenga un vector v que represente dicho bloque. Una vez se cuenta con tantos vectores v como número de bloques, se lleva a cabo la normalización de estos de manera individual, siguiendo una de las normas siguientes: Norma L2: v→v/q||v||2 2+ε2(2.5a) Norma L1: v→v/(||v||1+ε)(2.5b) Raíz cuadrada de norma L1: v→pv/(||v||1+ε)(2.5c) Donde ε representa una constante de valor pequeño. También se puede usar la norma L2-Hys, que consiste en limitar los valores de v a 0,2 y renormalizar. La norma L1 funciona un 5% peor que las demás, y no aplicar el proceso de normalización hace que los resultados sean aproximadamente un 27% peores [12]. En la Figura 2.5, se puede observar una imagen original en escala de grises y, a la derecha, el resultado de calcular la imagen HOG siguiendo el método descrito, en la que se han tomado celdas de 16 ×16 píxeles de tamaño y una celdas por bloque, es decir, hay el mismo número de celdas que de bloques. (a) Imagen original. (b) Imagen HOG. Figura 2.5 Ejemplo del cálculo de una imagen HOG.
14 Capítulo 2. Estado de la tecnología del reconocimiento facial proyecto, por lo que se reservará la descripción de su funcionamiento dedicado a la clasificación para el desarrollo del Capítulo 3.
3 Redes neuronales artificiales Las redes neuronales artificiales (RNA) representan un campo de la inteligencia artificial (IA) que en la actualidad se encuentra en pleno auge debido a la enorme variedad de posibilidades que pueden llegar a ofrecer. Inspiradas en el propio comportamiento de un sistema nervioso biológico, las RNA son capaces de aprender a realizar diferentes tareas entre las que, para el desarrollo de este proyecto, se destacará su capacidad de clasificación. 3.1 Introducción histórica Aunque las redes neuronales artificiales ha presentado una importante evolución en los últimos años, ya en 1936 Alan Turing empezó a estudiar el funcionamiento del cerebro desde el punto de vista de la computación y en 1943 W. McCulloch y W. Pitts lanzaron una teoría sobre la forma de trabajar de las neuronas, modelando su propia red neuronal simple con circuitos eléctricos. En 1957, F. Rosenblatt inició el desarrollo del Perceptrón, la primera red neuronal, capaz de reconocer y clasificar patrones sin antes haberlos analizado. En 1959, B. Widrow y M. Hoff desarrollaron el modelo ADALINE, la primera red neuronal aplicada a un problema real. En 1969, M. Misnky y S. Papert publicaron su libro Perceptrons, donde se introducía el concepto de percetrones multinivel y, posteriormente, K. Fukushima propuso en 1980 el Neocognitrón, usado para reconocimiento de caracteres manuscritos. Desde entonces, las redes neuronales artificiales han seguido desarrollándose, hasta llegar a la publicación de revistas especializadas como Neural Networks de la INNS o IEEE Transactions on Neural Networks del IEEE Neural Networks Council [30]. 3.2 Estructura de una red neuronal artificial Las redes neuronales artificiales presentan una serie de componentes que hacen que su estructura sea muy variable, según la configuración elegida. 3.2.1 Neurona artificial Las neuronas artificiales Uj son las unidades de proceso y su función es recibir las entradas de células vecinas, calcular un valor de salida y enviarlo a otras células. En una red neuronal se suelen diferenciar tres tipos de unidades: las de entrada, de salida y ocultas [30]. 1. Neuronas de entrada: son aquellas que reciben las señales o información de entrada a la red neuronal. 2. Neuronas ocultas: se ocupan del procesado de la información y no tienen contacto con el exterior, es decir, tanto sus entradas como sus salidas pertenecen al sistema. 3. Neuronas de salida: son aquellas que se encargan de ofrecer la respuesta del sistema tras el procesado de la información. 15
16 Capítulo 3. Redes neuronales artificiales Además, estas se organizan en capas o niveles, es decir, en grupos de neuronas cuyas entradas provienen de la misma fuente (o capa) y cuyas salidas se dirige al mismo destino. Al igual que las neuronas, las capas se dividen en capas de entrada, ocultas o de salida, según las neuronas que forman parte de estas. Σϕ Uj x1 xi xn w1,j wi,j wn,j yj . . . . . . Figura 3.1 Representación de una neurona artificial genérica. 3.2.2 Conexión entre neuronas Las neuronas deben estar conectadas entre ellas para transmitir la información a través de las diferentes capas. Si ninguna de las salidas de las neuronas hacen de entrada en neuronas de la misma capa o de niveles anteriores, la red se define como de propagación hacia delante. Si por el contrario, algunas salidas de neuronas entran en capas anteriores o en una neurona de la propia capa, la red presenta propagación hacia atrás [30]. Por otro lado, cada conexión entre una neurona i y una neurona j tiene asociado un peso wi,j , tal como se observa en la Figura 3.1. Si este es positivo, la conexión o sinapsis se denomina excitadora; si es negativo, la conexión será inhibidora; y si su valor es cero, supondrá que la conexión entre ambas neuronas es nula [ 30 ]. Además, se suele simplificar la entrada neta de una neurona en función de los pesos wi,j y de las salidas de las neuronas que se conectan a ella yi: Netj= n ∑ i=0 wi,jyi(3.1) 3.2.3 Estado de activación El estado de activación de la red se define como un vector A(t) de N números reales del cual cada elemento ai(t) representa la activación de una neurona Ui en función del tiempo t . Cada neurona puede presentar un estado de reposo o excitado y puede ser representado con valores continuos o discretos [30]. 3.2.4 Función de salida Cada unidad neuronal está asociada a una función de salida ϕi(ai(t)) que transforma el estado actual de activación ai(t)en una señal de salida: yi(t) = ϕi(ai(t)) (3.2) Las funciones de salida o de transferencia más comunes en las redes neuronales pueden ser de tipo escalón, lineal, sigmoidal o Gaussiana [30].
3.3 El Perceptrón 17 3.2.5 Regla de activación La regla o función de activación es aquella que produce un nuevo estado de activación a partir del anterior y de las entradas con los pesos de las conexiones. Dada una neurona Ui con estado de activación ai(t) y su entrada total Neti, la función de activación Fproducirá un nuevo estado: ai(t+1) = F(ai(t),Neti)(3.3) Normalmente la regla de activación es la función de identidad por lo que el nuevo estado de activación ai(t+1) de la neurona j coincidirá con su entrada total Netj en el instante anterior. De este modo, la función de salida de dicha neurona recibirá la propia entrada a esta Netj, sin tener en cuenta el estado de activación anterior, por lo que se suele considerar una única función en la neurona, la función de transferencia o de activación [30]. De esta forma, la salida de una neurona yjen el instante t+1seguirá la Ecuación (3.4). yj(t+1) = ϕj(Netj−θj) = ϕj( n ∑ i=0 wi,jyi(t)−θj)(3.4) Donde θirepresenta un umbral de desplazamiento de la función de activación. 3.2.6 Regla de aprendizaje La regla de aprendizaje es aquella que fija el proceso mediante el que la red neuronal modifica los pesos de sus conexiones en función de la información de entrada. Existen dos formas principales de clasificar las redes neuronales según su regla de aprendizaje. En primer lugar, una red neuronal puede presentar aprendizaje supervisado o no supervisado, dependiendo si necesita o no de un agente externo que controle el proceso, respectivamente. Por otro lado, en función de si se distingue una fase de aprendizaje y otra de funcionamiento, el aprendizaje será Offline, u Online si la red puede aprender a la vez que funciona [30]. 3.3 El Perceptrón El Perceptrón es la red neuronal artificial más antigua, siendo capaz de aprender a reconocer patrones sencillos y realizar una clasificación binaria. La estructura del Perceptrón presenta una única neurona de salida, la cual obtiene la suma ponderada de sus entradas, calcula su diferencia con el umbral θ y le aplica una función escalón o signo sgn como función de transferencia, tal como se muestra en la Ecuación (3.5). y(t) = sgn∑N i=1wi(t)xi(t)−θ(3.5) De esta forma, el Perceptrón calcula la ecuación de un hiperplano (Ecuación (3.6) ) que separa las regiones de cada clase, a partir de los valores de los pesos w> y del valor umbral θ de la función de activación. Sin embargo, al estar compuesto por una única capa de entrada y otra de salida con una sola neurona, solo puede diferenciar patrones sencillos linealmente separables [30], tales que: w>x−θ≷0(3.6) 3.3.1 Regla de aprendizaje El aprendizaje del Perceptrón es de tipo supervisado, por lo que cuando se evalúen los resultados obtenidos, se deben hacer unas modificaciones del sistema hasta que este se ajuste correctamente al problema. Como se ha visto, la salida del sistema depende de los pesos de las conexiones, por tanto, estos valores serán modificados para ajustar el sistema. Para ello, el algoritmo es el siguiente [30]: 1. Inicialización de los pesos wiy el umbral θ=−w0. 2. Presentación de los datos de entrada Xp= (x1,x2,...,xN)con la salida esperada d(t). 3. Cálculo de la salida del sistema según la Ecuación (3.5).
18 Capítulo 3. Redes neuronales artificiales 4. Adaptación de los pesos según la Ecuación (3.7). wi(t+1) = wi(t)+α[d(t)−y(t)]xi(t)0≤i≤N(3.7) Donde α∈[0,1]es un factor de aprendizaje. 5. Repetición desde el paso 2 hasta que el sistema sea capaz de clasificar sus entradas y se de por terminado el aprendizaje. 3.4 El Perceptrón Multicapa Como se ha visto, el Perceptrón no es capaz de realizar clasificaciones que no puedan separarse de forma lineal. De la necesidad de establecer regiones más complejas nace el perceptrón multicapa (MLP). Como su propio nombre indica, el MLP es una red neuronal de tipo feedforward compuesta por una o más capas ocultas [30], cuya estructura se representa en la Figura 3.2. Capa de entrada . . . . . . . . . . . . Capas ocultas . . . . . . Capa de salida . . . x0 x1 xN y0 y1 yM Figura 3.2 Estructura de un Perceptrón Multicapa. El MLP presenta los tres tipos de capas descritas anteriormente: la capa de entrada, encargada de recibir los parámetros hacia el interior de la red; las capas ocultas que realizan el procesamiento de la información; y las de salida, que entregan el resultado obtenido por el sistema. 3.4.1 Regla de aprendizaje Como se ha dicho, el MLP es una red de tipo feedforward y su técnica de aprendizaje es una de las más populares, la back-propagation. El funcionamiento de este método es similar al algoritmo de aprendizaje del Perceptrón, pero con el añadido de dividir la contribución del error para cada peso de la red. Así, su procedimiento es el siguiente [31]: 1. Inicialización del valor de los pesos de la red. 2. Presentación de los datos de entrada Xp= (x1,x2,...,xN)con la salida esperada d(t). 3. Comparación de la salida esperada con la salida del sistema y(t)y calcular el error: ε=d(t)−y(t). 4. Actualización de los pesos de la capa de salida: wi,j(t+1) = wi,j(t)+αajεjF0(Netj)(3.8) Donde F0 representa la derivada de la función de activación F (que deberá ser una función derivable como la rampa, tangente hiperbólica, logística, etc.) y aj=F(Netj) es el estado de activación de la neurona.
3.5 Redes neuronales convolucionales 19 5. Definiendo el término de error de una capa j: ∆j=εjF0(Netj)(3.9) La regla de propagación de los valores de error será: ∆i=F0(Neti)∑ i wi,j∆j(3.10) 6. Calcular los nuevos pesos de la capa anterior k: wk,i(t+1) = wk,i(t)+αak∆i(3.11) Repitiendo este proceso las veces que sea requerido, se pueden configurar todos los pesos de la red para ajustarla a una aplicación concreta. El Perceptrón multicapa será usado en este proyecto para la tarea de clasificación en el sistema de reconocimiento facial, por lo que en posteriores secciones serán detalladas las características de configuración, así como un método para evaluar su comportamiento. 3.5 Redes neuronales convolucionales Las redes neuronales convolucionales (CNN) son un tipo concreto de red neuronal artificial que son capaces de aprender a distinguir características en un conjunto de datos a través del cálculo de convoluciones. Es por ello que este tipo de redes sean muy utilizadas en el reconocimiento de objetos en imágenes [31]. El funcionamiento de una CNN consiste en transformar los datos que obtiene mediante la capa de entrada en un conjunto de valores calculados por capas ocultas completamente conectadas. De esta forma, la estructura más general de una CNN se divide en tres tipos de capas: una de entrada, una de extracción de características y otra de clasificación (ver Figura 3.3). Figura 3.3 Representación general de la estructura de una CNN [31]. 3.5.1 Capa de entrada La capa de entrada es aquella que recibe los datos provenientes del exterior de la CNN. En el caso de que estos datos sean imágenes, las entradas serán tridimensionales cuyas dimensiones son el ancho, el alto y los canales de color como, por ejemplo, los tres valores RGB de cada píxel [31].
20 Capítulo 3. Redes neuronales artificiales 3.5.2 Capas de extracción de características Son una serie de capas que se encargan de obtener información relevante para construir progresivamente características de orden superior. A su vez, las capas de extracción de características se pueden diferenciar en dos tipos: las capas de convolución, encargadas de calcular dicha función, y las capas de pooling que, a continuación, reúnen los resultados obtenidos por las anteriores capas [31]. Capas convolucionales Las capas convolucionales representan la parte más importante de una CNN. Estas tienen como objetivo transformar los datos de entrada mediante un conjunto de neuronas que son conectadas localmente desde la capa anterior. Esta capa calculará un producto de puntos entre una región concreta de la capa de entrada y los pesos que la conectan a la capa de salida. Normalmente, este proceso suele mantener las mismas dimensiones espaciales. La detección de características de la CNN es realizada mediante la de convolución, operación que es realizada en este tipo de capas. La entrada de esta pueden ser los propios datos brutos de entrada, o una salida proveniente de otra convolución anterior. En muchas ocasiones, esta operación se interpreta como un filtrado de los datos de entrada, donde un kernel encargado de filtrar se suele corresponder con el conjunto de pesos de la capa convolucional [31]. En la Figura 3.4 se muestra cómo un kernel se va desplazando a lo largo de unos datos de entrada. En cada paso, se multiplica el filtro por los valores de los datos de entrada, creando una nueva característica de salida. Figura 3.4 Representación de la operación de convolución con un kernel [31]. Como se muestra en la Figura 3.3, las capas convolucionales pueden ir seguidas de unas capas ReLU, las cuales tendrán el objetivo de aplicar una función de activación a modo de umbral en cero a sus datos de entrada, por lo que estas capas podrán cambiar algunos valores, pero no la dimensionalidad inicial de los datos. Capas de pooling Las capas de pooling son situadas entre capas convolucionales para reducir la dimensionalidad de los datos que pasan a través de las diferentes capas. Para ello, las capas de pooling suelen usar un filtro de, por ejemplo, 2×2 . Este filtro es aplicado a los datos, de modo que los cuatro píxeles que sean filtrados serán sustituidos por un único valor, que se corresponderá con el máximo valor de los píxeles filtrados [ 31 ], según se muestra en la Figura 3.5. 3.5.3 Capa de clasificación La capa de clasificación representa la última capa de la CNN, aunque en algunas ocasiones puede haber más de una capa de este tipo. Este tipo de capa se encuentra completamente conectada a su capa adyacente y su objetivo es tomar las características finales calculadas por el resto de la red y producir puntuaciones o probabilidades correspondientes a las clases entrenadas. El resultado de estas capas representará los datos de
3.6 El método de aprendizaje Triplet Loss 21 Figura 3.5 Funcionamiento de la capa de pooling [32]. salida, los cuales tendrán unas dimensiones completamente menores, siendo únicamente un vector con tantos elementos como clases hayan sido analizadas [31]. 3.6 El método de aprendizaje Triplet Loss El Triplet Loss es un método de aprendizaje supervisado que puede ser utilizado para realizar el entrenamiento de una CNN. Concretamente, este método fue introducido por F. Schroff et al. [ 33 ] para llevar a cabo el entrenamiento de su propio modelo de sistema de reconocimiento facial. El fundamento de este método de entrenamiento recae en obtener lo que llaman un embedding f(i) a partir de una imagen i , que servirá de representación de esta imagen en un espacio de características Rd . Este espacio debe ser tal que las imágenes de una misma persona se encontrarán próximas, mientras que las imágenes entre personas distintas presentarán distancias mayores, independientemente de las condiciones de iluminación de las imágenes. Además, cada embedding calculado se encontrará en una hiperesfera, de modo que su módulo se corresponda con la unidad: kf(i)k=1. Figura 3.6 Ejemplo del funcionamiento de los triplets [33]. Por otro lado, se toma un triplet, que consistirá básicamente en un trío de imágenes. Cada triplet se corresponderá con la identidad de una persona concreta, de forma que habrá tres tipos de imágenes por persona: Una imagen de referencia ai , una imagen positiva pi y una imagen negativa ni , como se muestra en la Figura 3.6. La imagen de referencia será una en la que aparezca el rostro de la persona en cuestión. La imagen positiva, será otra imagen distinta de la misma persona, de modo que, tras haber terminado todo el proceso, presente la menor distancia posible respecto a la imagen de referencia en el espacio de características. Finalmente, en la imagen negativa deberá aparecer el rostro de una persona distinta a las que aparecen en las otras dos imágenes. Esta imagen tendrá el objetivo de fijar distancias mayores respecto a la que podría presentar una imagen positiva con la de referencia, en el espacio de características. Esto evita que se produzcan futuros falsos positivos, es decir, que la red relacione a una persona con la identidad de otra diferente. Matemáticamente, se representa con la siguiente restricción: kai−pik2+α<kai−nik2,∀(ai,pi,ni)∈τ(3.12)
22 Capítulo 3. Redes neuronales artificiales Donde α representa un margen entre los pares de imágenes positiva y negativa para evitar que la red no optimice hacia la igualdad, y τes el conjunto de todos los Ntriplets posibles para entrenar. Para realizar el entrenamiento de la CNN usando los triplets que optimicen los resultados se deberá calcular el mínimo valor de la llamada función Loss L que se representa en la Ecuación (3.13) , en dependencia de los embeddings fde las tres imágenes del triplet. L= N ∑ i [kf(ai)−f(pi)k2−kf(ai)−f(ni)k2+α](3.13) Para elegir estos triplets de una forma adecuada, habrá que buscar una imagen positiva que, dada una imagen de referencia, maximice el primer término de la Ecuación (3.13) y una imagen negativa que minimice el segundo término de la misma, sin llegar a ser nulo. Como calcular uno a uno todos los triplets posibles no es factible por el tamaño de la base de datos, se calcularán los máximos y mínimos valores de los términos de la función Loss haciendo uso de una base de datos de tamaño menor, sacada a partir de la base de datos completa. Por ejemplo, F. Schroff et al. tomaron 40 imágenes positivas de cada persona y se añadieron un conjunto de ejemplos de imágenes negativas de forma aleatoria. Luego, a partir de este conjunto, se deberá seleccionar las imágenes negativas más adecuadas teniendo en cuenta la restricción de la Ecuación (3.14) , es decir, que la distancia entre la imagen positiva y la imagen de referencia sea menor que la distancia entre la negativa y la de referencia, lo que evita problemas de convergencia a la hora de entrenar el modelo. kf(ai)−f(pi)k2<kf(ai)−f(ni)k2(3.14) Finalmente, cuando se hayan seleccionado los triplets para cada persona, bastará con presentarlos a la CNN para llevar a cabo el entrenamiento mediante el método de descenso de gradientes estocástico (SGD), con un funcionamiento muy similar al del método de backpropagation que ha sido explicado anteriormente para ajustar los pesos de la red.
4 Sistema propuesto Al o largo de este capítulo se pretende llevar a cabo una revisión del sistema que se ha elegido para llevar a cabo el reconocimiento facial en este proyecto, así como los algoritmos que se han empleado a la hora de diseñarlo, después de haber hecho un estudio de las fases de reconocimiento facial, así como algunos de los algoritmos más utilizados. Para esta labor, se va a dividir el capítulo en secciones, que coincidirán con los pasos que se deben de seguir para completar todo el proceso de reconocimiento facial, explicando cada uno de los métodos y algoritmos empleados. No obstante, antes de esto se va a realizar un repaso de las herramientas utilizadas para ello, como pueden ser el lenguaje de programación y las librerías utilizadas. 4.1 Herramientas de desarrollo 4.1.1 Lenguaje de programación El lenguaje de programación que se va a utilizar a lo largo del desarrollo del proyecto es Python [ 34 ], ya que cuenta con una gran variedad de librerías que facilitan el desarrollo de aplicaciones de visión artificial, reconocimiento facial e inteligencia artificial, como se verá a continuación. Concretamente, ha sido utilizada la versión 3.6, al ser compatible con las librerías utilizadas y ser la última versión estable de Python a fecha del inicio del desarrollo del sistema. 4.1.2 Entorno de desarrollo El entorno de desarrollo utilizado ha sido Spyder, disponible bajo la distribución multiplataforma Anaconda [ 35 ], la cual es libre y abierta. La versión de Anaconda empleada ha sido la 5.1, también por ser la última estable a inicios del proyecto. 4.1.3 Librerías utilizadas Para la implementación del sistema se han usado una serie de librerías que han facilitado el desarrollo gracias a una serie de funciones o clases que llevan implementan los algoritmos explicados durante este trabajo. Las principales librerías que se han utilizado son: •NumPy [ 36 ] (versión 1.14.15): representa el paquete de matemáticas de Python más importante ya que añade funcionalidades de vectores y matrices. •OpenCV [ 29 ] (versión 3.4.1): es una librería de código abierto que aporta funciones de visión artificial y machine learning. •Face Recognition [ 37 ] (versión 1.2.2): se trata de una librería que aporta herramientas para reconocer y manipular caras de una forma muy sencilla. •Scikit-Learn [ 38 ] (versión 0.19.1): es una librería que integra algoritmos de machine learning de forma eficiente como algoritmos de clasificación, regresión y clustering. 23
30 Capítulo 5. Validación experimental Además, los algoritmos de validación cruzada permiten evitar un problema muy común a la hora de entrenar los modelos de clasificación. Si se lleva a cabo un entrenamiento con la totalidad de los datos disponibles, cuando se vuelvan a utilizar los mismos datos para obtener las predicciones, probablemente se obtendrán buenos resultados. Sin embargo, es posible que el clasificador pierda efectividad cuando en el futuro se prueben datos que no hayan sido vistos previamente. Este fenómeno se conoce como overfitting o sobreajuste [45]. Dentro de la validación cruzada existen diferentes métodos, como pueden ser el K-Fold, que consiste en dividir los datos en k pequeñas particiones y dejar una de ellas para la validación, repitiendo este proceso tantas veces como particiones se definan; o el LOOCV (siglas de Leave-One-Out Cross-Validation), que sería un caso particular del K-Fold, donde el valor de kcoincide con el número total de datos disponibles [45]. Para el caso concreto de este proyecto, se ha optado por una variante de validación cruzada aleatoria. Este método consiste en tomar cierto porcentaje de los datos para dedicarlo al entrenamiento, y el resto para la validación, de modo que la división en ambos subconjuntos se lleve a cabo de forma aleatoria, como puede verse representado en la Figura 5.1. Figura 5.1 Validación Cruzada con selección aleatoria. Este proceso de división de la base de datos, entrenamiento y validación tendrá que ser llevado a cabo de forma repetida, con el objetivo de obtener diferentes valores de error (o precisión) en cada iteración para luego calcular la media aritmética. Además, esto será realizado en paralelo para diferentes sistemas y, de esta forma, será posible obtener una buena aproximación de la precisión general de cada uno de ellos, con el fin de compararlos y elegir la topología de red neuronal más adecuada. De esta forma, se procede a explicar el procedimiento seguido para llevar a cabo dicha técnica. En primer lugar, será necesario cargar la base de datos. Para ello, habrá que acceder a los directorios y, dentro de cada uno de estos, a las imágenes que se encuentran en ellos. Una vez obtenido el vector de codificación de cada rostro de las imágenes y, a su vez, las etiquetas correspondientes a cada uno de estos rostros, se crearán dos archivos en los que se encontrarán almacenados estos parámetros, evitando así procesar toda la base de datos cada vez que se quisiera realizar estas pruebas. El siguiente paso será la creación de los clasificadores de tipo Perceptrón Multicapa. Para llevar a cabo la validación experimental, se crearán varios clasificadores con distintas características, con el objetivo de comparar sus comportamientos y elegir el más adecuado. En una primera instancia, se han creado tres clasificadores distintos. En primer lugar, se ha definido un Perceptrón Multicapa de una capa oculta, con 100 nodos, además de las capas de entrada con 128 nodos, uno para cada valor de los vectores que definen las características del rostro, y la de salida, que presenta una función de salida de tipo Softmax, definida en la Ecuación (5.1) . Esta se encarga de reducir la dimensionalidad de un vector K -dimensional de entrada x . Posteriormente, han sido creados otros dos clasificadores de tipo Perceptrón Muticapa, con dos y tres capas ocultas, del mismo número de nodos: cien en cada una de ellas. La estructura de estos será configurada de diferentes formas en los experimentos para llegar a una arquitectura final con la que se obtengan los mejores resultados. σ(x)j=exj ∑K k=1exk j=1,...,K(5.1) Donde xj es la entrada a la neurona j de la capa de salida y K es el número de clases o, en este caso, de personas de la base de datos, es decir, en este caso el valor de Kes 21.
5.2 Método empleado 31 Con la base de datos disponible para poder ser manipulada adecuadamente y los clasificadores para realizar experimentos con ellos, se procede a hacer la división de los datos, para formar los dos subconjuntos: uno para utilizarlo a la hora de entrenar cada uno de los modelos de red neuronal, y otro para llevar a cabo la posterior validación de los mismos. De esta forma, se entrena cada modelo con los datos destinados a ello y, tras esto, se van a realizar una serie de experimentos que se describen a continuación. 5.2.1 Experimento 1: Evaluación de función de activación La primera prueba que será realizada estará destinada a elegir una función de activación para la capa o capas ocultas. Para llevarlo a cabo, se va a comparar el comportamiento de tres MLP con una capa oculta cada uno, pero con diferentes funciones de activación (ver Figura 5.2). El primero presentará la función de activación rampa o ReLU, definida en la Ecuación (5.2). f1(x) = max(0,x) = 0,x<0 x,x≥0(5.2) El segundo contará con la función tangente hiperbólica, definida en la Ecuación (5.3). f2(x) = tanh(x) = senh(x) cosh(x)=ex−e−x ex+e−x(5.3) Finalmente, el tercero será implementado con la función logística, que se define en la Ecuación (5.4). f3(x) = 1 1+e−x(5.4) −2−1 1 2 −2 −1 1 2 x f1(x) (a) Función ReLU. −2−1 1 2 −1 1 x f2(x) (b) Función tangente hiperbólica. −2−1 1 2 −1 1 x f3(x) (c) Función logística. Figura 5.2 Funciones que serán evaluadas como función de activación del MLP. Una vez están definidos los tres MLP, con un estado inicial similar para que los resultados del estudio sean lo más precisos posible, será hora de hacer la prueba. Como se ha explicado anteriormente, se va a dividir el conjunto de datos en uno de entrenamiento y otro de prueba. Tras entrenar los tres modelos con el primer grupo, se harán dos mediciones. En primer lugar, se medirá el coeficiente de determinación R2 de la predicción y, a continuación, la media de la precisión obtenida para el caso correcto. Coeficiente de determinación Para hacer la primera medida, será necesario describir el coeficiente en que se basa. El coeficiente de determinación R2 se puede definir como el estadístico que proporciona la medida de variabilidad de una variable Y, debida a la variabilidad de la variable explicativa X [46]. Matemáticamente, este parámetro se define en la Ecuación (5.5). R2=1−σ2 r σ2(5.5) Donde σ2 r y σ2 representan la varianza residual y la varianza de la variable Y, respectivamente, y se definen en la Ecuación (5.6) y en la Ecuación (5.7). σ2 r=∑N i=1(yi−˜yi)2 N(5.6)
32 Capítulo 5. Validación experimental σ2=∑N i=1(yi−¯y)2 N(5.7) Donde yi se corresponderá con el valor de la etiqueta correspondiente al rostro, siendo ¯y su valor medio que se calcula según la Ecuación (5.8) , ˜yi representará el valor predicho por el modelo y N será el número total de datos. ¯y=∑N i=1yi N(5.8) En este caso, la variable X representará a los datos descriptivos de cada rostro, y la variable Y representa la etiqueta numérica que identifica a la persona a quien pertenece dicho rostro. Haciendo uso de este parámetro, será posible medir la bondad de las predicciones que hagan los clasificadores. Si R2 toma un valor igual a la unidad, indicará que el modelo se ajusta totalmente a la variabilidad de Y, por lo que no se producirá error alguno. Dicho de otra manera, cuanto más se acerque el valor de R2 a 1 , mayor porcentaje de acierto conseguirá el modelo en cuestión. Para obtener una buena estimación de este parámetro, en este proyecto cada MLP será entrenado con los mismos datos y se calculará el coeficiente con el grupo de datos de prueba correspondiente. No obstante, este proceso será realizado hasta un total de 100 iteraciones para variar los datos con los que se entrena y se comprueba, siempre de forma aleatoria. De esta forma se obtendrá un total de 100 valores de R2 , a partir de los cuales se calculará su media aritmética para obtener un único valor promedio que represente los resultados del experimento. Adicionalmente, cabe decir que el valor del coeficiente R2 coincide con el porcentaje de aciertos del modelo, por lo que la interpretación de los resultados obtenidos resultará una sencilla tarea: cuanto mayor valor de R2, más aciertos habrá conseguido el modelo en cuestión. Promedio de la precisión La otra prueba que será realizada en paralelo con el cálculo del coeficiente R2 consistirá en medir el porcentaje de similitud que el clasificador presenta ante la etiqueta correcta, es decir, qué porcentaje devuelve el modelo para la persona correspondiente a esa imagen, independientemente de si existe una con más porcentaje (y por tanto el modelo falle). El procedimiento consistirá en entrenar cada modelo con el subconjunto de entrenamiento, al igual que en el anterior, para que todos reciban exactamente los mismos datos. Cuando hayan sido entrenados, se tomará cada uno de los datos del conjunto de validación y se le presentará a los diferentes modelos de MLP. Estos procesarán la información de entrada y calcularán el porcentaje de similitud de esta entrada para cada una de las clases que ha aprendido en el entrenamiento, es decir, el MLP devolverá el porcentaje de parecido entre los datos del rostro de entrada y las diferentes personas que ha aprendido a diferenciar con el entrenamiento. Este porcentaje es calculado haciendo uso de la función de pérdida de entropía cruzada (Cross-Entropy loss), que mide el rendimiento de clasificación de un modelo siguiendo la Ecuación (5.9). H(p,q) = −∑ x p(x)ln(q(x)) (5.9) Donde p(x) representa la probabilidad deseada para la clase x , y q(x) representa la probabilidad real obtenida que, en este caso, será la salida de la capa Softmax del MLP. En la práctica, como p(x) no suele ser conocida, se suele suponer que todas las N observaciones son equiprobables, es decir, p(x) = 1/N , por lo que la entropía cruzada será calculada como: H(p,q) = −1 N∑ x ln(q(x)) (5.10) En este caso se habrán aprendido un total de 21 personas diferentes, por lo que cada MLP devolverá un vector de 21 elementos, uno por cada porcentaje de parecido entre el dato de entrada y cada rostro. Luego, se extraerá de este vector el resultado obtenido para la que se conoce a priori que es la clase correcta, es decir, se tomará el porcentaje obtenido para la persona de la que en realidad se trata. Idealmente, este valor debería ser el mayor del vector devuelto por el MLP, pero en las ocasiones en las que la predicción de un modelo sea errónea, esto no ocurrirá.
5.3 Resultados e interpretación 33 Este proceso se hará para todos los datos de validación y, al igual que el proceso anterior, será realizado un total de 100 iteraciones para obtener un valor promedio de cada MLP, con el fin de compararlos y decidir cuál se comporta mejor. El objetivo de este experimento no es únicamente que el modelo acierte, lo cual está contemplado en el anterior, sino que presente el máximo porcentaje de similitud posible. 5.2.2 Experimento 2: Determinación del número de capas ocultas Una vez se haya realizado el primer experimento y se haya decidido la función de activación en función de sus resultados, se realizará el experimento que compare los 3 MLP con diferentes números de capas ocultas. Tras haber revisado el experimento anterior, la explicación de este resultará mucho más sencilla. El procedimiento de este experimento será muy similar al seguido en el primero. Se realizarán dos pruebas en paralelo: el cálculo del coeficiente de determinación R2 y la medida de la precisión obtenida para el resultado correcto. La principal diferencia con el anterior, será que este experimento será realizado con una función de activación ya fijada (la elegida a partir de los primeros resultados) y que los tres MLP ahora variarán en sus dimensiones, teniendo una, dos y tres capas ocultas, respectivamente, con 100 nodos o neuronas cada una. 5.2.3 Experimento 3: Variación del número de neuronas El último experimento seguirá el mismo procedimiento que los dos anteriores. Sin embargo, en este caso ya se habrán fijado la función de activación y el número de capas ocultas del MLP. Con estos parámetros, se hará una comparación de los resultados obtenidos para el coeficiente de determinación R2 y para la estimación que devuelve el MLP. En función de estos resultados se decidirá si el número de neuronas fijado al inicio puede ser reducido o, por el contrario, debe ser incrementado para conseguir mejores resultados. 5.3 Resultados e interpretación En esta sección se hará un análisis de los resultados de los experimentos descritos, para tomar una decisión acerca de la topología o estructura más adecuada para el diseño del Perceptrón Multicapa. 5.3.1 Experimento 1 El objetivo del primer experimento es fijar una función de activación adecuada a este caso. Para ello se ha seguido el procedimiento explicado en la Subsección 5.2.1 y se han obtenido los resultados de la Tabla 5.1. Tabla 5.1 Resultados del experimento 1. Función f(x)Coeficiente de determinación R2(%) Similitud (%) ReLU 99,2700 95,2438 Tangente hiperbólica 99,2700 96,5802 Logística 99,1970 95,2438 Haciendo un estudio los resultados obtenidos, se observa que la función logística ha presentado un valor de R2 ligeramente menor al obtenido para las funciones ReLU y tangente hiperbólica. Por la parte de la segunda medida, la función ReLU y la función logística han presentado el mismo porcentaje de similitud, encontrándose por debajo del resultado para la tangente hiperbólica. Con estos resultados como referencia, resulta evidente que la elección de la función de activación del MLP se corresponderá con una tangente hiperbólica ya que, aunque no se presenten diferencias abismales, ha quedado claro con este experimento que, para este caso concreto, la tangente hiperbólica es la que ha presentado un mejor comportamiento. Por tanto, la función elegida es la tangente hiperbólica y, a partir de este resultado, se llevará a cabo el siguiente experimento. 5.3.2 Experimento 2 Una vez se ha fijado la función de activación como tangente hiperbólica, se procede a realizar el segundo experimento, en el que se va a llevar a cabo el mismo procedimiento de comparación, pero esta vez comparando
34 Capítulo 5. Validación experimental varios MLP con diferente número de capas ocultas. Los resultados de este experimento se muestran en la Tabla 5.2. Tabla 5.2 Resultados del experimento 2. Número de capas ocultas Coeficiente de determinación R2(%) Similitud (%) 1 99,2993 96,8010 2 99,0438 97,3120 3 98,9489 97,2883 Como se puede apreciar, se hace presente el hecho de que cada vez que se le añade una capa oculta al MLP, el valor promedio del coeficiente de determinación se reduce, lo que significa que el número de aciertos se hace cada vez menor. Por otro lado, el valor promedio de la similitud resultante con una capa es aproximadamente 0,5% menor que con dos capas. Si se tuviera en cuenta únicamente esta prueba, sería muy posible que un usuario eligiera un Perceptrón Multicapa con una estructura definida por dos capas ocultas. Sin embargo, es necesario definir unas prioridades según la aplicación del modelo. Para el caso de este proyecto, en el ámbito del reconocimiento facial va a resultar prioritario el número medio de aciertos de un sistema, frente a la probabilidad media de parecido. Esto es fácil de entender con un ejemplo: si se dispone de un sistema de reconocimiento facial, es preferible que detecte de quién se trata una persona, aunque presente un menor porcentaje de parecido, a que cuando acierte aporte un mayor porcentaje de parecido, pero que en general falle un mayor número de veces el reconocimiento. Por tanto, teniendo como referencia estos resultados, se toma la decisión de que el MLP contará con una única capa oculta, por lo que en este caso se confirma lo que se adelantaba en la Subsección 4.2.4, donde se decía que para una una gran cantidad de aplicaciones se obtienen buenos resultados con un MLP de una única capa oculta. Además, el hecho de que el MLP presente una única capa oculta no solo presenta los mejores resultados según este experimento, sino que además el coste computacional, sobre todo a la hora del entrenamiento, será menor para una capa que para más de una. 5.3.3 Experimento 3 Como última prueba para fijar la estructura final del MLP que se utilizará en el sistema de reconocimiento facial implementado en este proyecto, se va a comprobar cómo varían los resultados en función del número de neuronas que componen la capa oculta. Para ello, se hace un primer ensayo con 50, 100 y 150 neuronas para cada MLP, respectivamente. Los resultados se representan en la Tabla 5.3, donde se observa una mejoría del comportamiento del MLP cuanto mayor número de neuronas compongan la capa oculta, tanto en la prueba del coeficiente de determinación como en la similitud obtenida. Por este motivo, se decide realizar un nuevo ensayo del experimento, esta vez cambiando el MLP de 50 neuronas, cuyos resultados son peores, por uno de 200 neuronas, para comprobar si los resultados siguen mejorando. Tabla 5.3 Resultados del primer ensayo del experimento 3. Número de neuronas Coeficiente de determinación R2(%) Similitud (%) 50 99,3869 96,3272 100 99,4818 96,8585 150 99,4891 97,0910 Tras realizar el segundo ensayo, se obtienen los resultados que han sido reflejados en la Tabla 5.4. En este caso, se ha obtenido que para una capa de 200 neuronas el coeficiente de determinación es mayor que para 100 neuronas, pero menor que el obtenido para el MLP de 150 neuronas. Por tanto, los resultados muestran la gran posibilidad de que se encuentre un pico alrededor de las 150 neuronas, a partir del cual el número de aciertos del MLP empezará a disminuir. Respecto a la similitud obtenida, se sigue obteniendo mayores porcentajes aumentando el número de neuronas. Sin embargo, siguiendo el mismo razonamiento que para el experimento anterior, se priorizará el caso que mayor número de aciertos presente.
5.4 Representación gráfica de los resultados 35 Tabla 5.4 Resultados del segundo ensayo del experimento 3. Número de neuronas Coeficiente de determinación R2(%) Similitud (%) 100 99,1015 96,8332 150 99,4161 97,0538 200 99,4088 97,1036 Por tanto, teniendo como referencia estos resultados, junto con los de los anteriores experimentos, se llega a la conclusión de que el Perceptrón Multicapa que será usado para este proyecto contará con una única capa oculta de 150 neuronas con la tangente hiperbólica como función de activación. Por otro lado, es posible que exista una solución en la que variando un poco más el número de neuronas se consiga mejorar el coeficiente de determinación R2 , pero debido a que la mejoría sería muy pequeña, se fijará el valor de 150 neuronas. Por este motivo, esta solución estará muy cerca de ser la óptima para este problema. 5.4 Representación gráfica de los resultados A través de los resultados de los experimentos anteriores ha sido posible fijar los parámetros del MLP que se encargará de clasificar las caras detectadas. Además, estos han sido elegidos de forma que en las pruebas se ha obtenido aproximadamente un total del 99,40% de aciertos, por lo que se podría afirmar que el sistema, en general, reconoce rostros con una considerable efectividad. Para mostrar unos resultados más atractivos, se han tomado algunos ejemplos de imágenes que han sido analizadas por el sistema. Por supuesto, estas imágenes no han sido utilizadas para llevar a cabo el previo entrenamiento del MLP. En el primer ejemplo representado en la Figura 5.3 se muestra una imagen analizada por el sistema en la que aparecen cuatro rostros. Concretamente, dos de ellos aparecen en primer plano y los otros dos se encuentran detrás y se ven un poco más borrosos debido al modo de enfoque. Como se puede comprobar, el sistema ha conseguido detectar a la perfección los cuatro rostros. Además, la capacidad de reconocimiento en esta imagen supera todos los objetivos, debido a que todas las personas cuyas caras han formado parte del entrenamiento, han sido reconocidas con una importante similitud. En primer lugar, las dos caras del primer plano han sido reconocidas con 99,93% y 99,8%, lo que significa que prácticamente con toda seguridad se tratan de las personas con las que han sido identificadas. Respecto a las dos caras del segundo plano, se diferencian dos casos. En primer lugar, a la derecha se ha obtenido un resultado del 99,48% de parecido, a pesar de que la cara se muestra desenfocada en la imagen. En segundo lugar, a la izquierda, se encuentra una persona cuya cara no ha sido utilizada en el entrenamiento, por lo que el resultado coincide con lo esperado, ya que el sistema ha descrito esa cara como desconocida (Unknown). En el segundo caso, mostrado en la Figura 5.4, se observan dos imágenes. En ambas se muestra a la misma persona con gafas de sol. Sin embargo, en la fotografía de la izquierda, el sistema logra reconocer a la persona con un 92,96% de parecido. Sin embargo en la imagen de la derecha, el resultado ha sido erróneo. Este fenómeno puede haberse producido porque el sistema no sea efectivo cuando las personas llevan complementos tales como las gafas de sol. Sin embargo, aunque pueda ser cierto que el sistema funcione mejor cuando la cara está al descubierto, es muy posible que el error que se ve en este ejemplo haya sido producido porque haya sido necesario un mayor número de imágenes de esta persona con gafas a la hora de entrenar el MLP, ya que en la imagen de la izquierda sí que ha conseguido reconocerlo. Para probar esta teoría, se decide hacer una nueva prueba con otra persona, de la cual han sido utilizadas para el entrenamiento 3 fotografías en las que aparecía con gafas de sol, además de imágenes con la cara descubierta. Para este caso, el resultado ha sido mucho más favorable ya que para una serie de imágenes de la misma persona con gafas de sol, el resultado siempre ha sido favorable puesto que siempre ha sido reconocida la persona correctamente. En la Figura 5.5 se representan dos ejemplos, en las que se observa claramente que el sistema ha sido capaz de identificar a la persona perfectamente teniendo gafas de sol o incluso sombrero como en el ejemplo de la derecha. Con esta prueba, se llega a la conclusión de que la base de datos tendrá un papel muy importante a la hora de entrenar, en este caso, el MLP, ya que deberá incluir ejemplos que representen de manera adecuada los casos que se quiere ser capaz de distinguir con el sistema. Por último, se ha querido probar hasta qué punto el sistema es capaz de detectar la cara, en función de las direcciones en las que mira una persona. Ya en la Figura 5.5 se observa que el sistema es capaz de detectar
36 Capítulo 5. Validación experimental Figura 5.3 Imagen resultante tras ser procesada por el sistema. (a) Cara reconocida. (b) Cara no reconocida. Figura 5.4 Ejemplo de imágenes con gafas de sol. rostros con diferentes perspectivas, pero se ha decidido probar el comportamiento con una imagen donde aparece un rostro girado y otra en la que sale completamente de perfil. Esto se muestra en la Figura 5.6, donde aparece a la izquierda una imagen donde la persona ha sido detectada e identificada perfectamente a pesar de estar algo girada, gracias al preprocesado realizado para adaptar las caras antes de la extracción de características. Sin embargo, en la imagen de la derecha, se muestra a la misma persona totalmente de perfil, pero no ha sido detectada, puesto que a la hora de pasar la plantilla HOG con la forma de una cara genérica no se ha obtenido la correlación suficiente como para ser identificada como un rostro.
5.4 Representación gráfica de los resultados 37 (a) (b) Figura 5.5 Segundo ejemplo de fotografías con gafas de sol. (a) Cara detectada e identificada. (b) Cara no detectada. Figura 5.6 Comportamiento ante personas de perfil.
6 Conclusiones 6.1 Conclusión Durante el desarrollo de este proyecto se ha llevado a cabo un estudio del funcionamiento de los sistemas de reconocimiento facial. Ha sido necesario realizar un análisis de algunos algoritmos específicos para las diferentes etapas que componen el proceso. Por otro lado, se ha hecho una revisión del funcionamiento de las redes neuronales artificiales para el posterior empleo de un tipo concreto a la hora de implementar el sistema, el Perceptrón Multicapa. Tras una serie de pruebas, destacando la técnica denominada validación cruzada, se ha conseguido definir una estructura para el MLP que hará la función de clasificador, de modo que se obtengan los mejores resultados posibles. Finalmente, se ha comprobado el comportamiento definitivo del sistema, exponiendo algunos ejemplos y representándolos de forma gráfica, con imágenes resultantes del propio procedimiento del sistema. Como se ha demostrado, la capacidad de reconocimiento del sistema para personas que hayan sido correctamente entrenadas es bastante notable, tanto en imagen como en vídeo, aunque en este último caso no se pueda demostrar en este documento. No obstante, sí se reconoce que el tiempo de procesamiento a la hora de usar vídeos en tiempo real mediante una cámara provoca que la reproducción del vídeo no sea completamente fluida. A pesar de este último punto, el proyecto ha conseguido cumplir sus objetivos principales, destacando sobre todo la implementación de un sistema capaz de reconocer rostros haciendo uso de redes neuronales con muy buenos resultados. 6.2 Líneas futuras Con todos los aspectos relevantes de este trabajo revisados, se pretende terminar esta memoria con algunos conceptos que podrían ser tenidos en cuenta para mejorar en un futuro el sistema implementado. En primer lugar, a pesar de que la interfaz por línea de comandos ha sido preparada para presentar un menú sencillo e intuitivo, siempre será más accesible para un usuario el uso de una interfaz gráfica. Por este motivo, se propone diseñar una interfaz gráfica en la que se ofrezcan unas opciones similares a un usuario de este sistema, además de que se le podrían añadir funcionalidades como seleccionar un grupo de imágenes concreto para analizar o incluso la visualización de los resultados de una manera rápida y sencilla una vez que haya sido procesada una imagen o un vídeo. Por otro lado, se podrían hacer modificaciones en el sistema, que requerirían la elección de dos opciones distintas. En primer lugar, se podría investigar en sustituir algunos algoritmos para reducir el tiempo de procesamiento, con el objetivo de mejorar el comportamiento del sistema frente a flujos de vídeo en tiempo real como son los recogidos a través de cámaras web. Otra opción podría ser implementar un entrenamiento del sistema de tal forma que sea capaz de reconocer personas totalmente de perfil, como podría ser por ejemplo el empleo de modelos de imágenes HOG preparadas para tal misión. Sin embargo, el hecho de tener que detectar caras tanto de perfil como de frente, podría exceder el tiempo de computación, por lo que podría no ser compatible con la primera opción descrita. Finalmente, también se plantea una tarea que podría no requerir la modificación del sistema. Se trata de llevar a cabo un entrenamiento más exhaustivo, utilizando bases de datos mayores. Esto podría mejorar, por 39
46 Capítulo A. Códigos utilizados 30 print("Elija una opción:") 31 print("1) Tomar de la cámara Web.") 32 print("2) Tomar un vídeo existente.") 33 34 ini = input() 35 if ini is "1": 36 funciones.video(0) 37 elif ini is "2": 38 funciones.select("Videos/") 39 else: 40 print("Opción incorrecta.") 41 else: 42 seguir=False Código A.2 funciones.py. 1 # -*- coding: utf-8 -*- 2 """ 3 Created on Mon Jul 9 19:22:17 2018 4 5 @author: Ildefonso Jiménez Silva 6 """ 7 8 import numpy as np 9 import sys 10 import face_recognition #Librería de reconocimiento facial 11 import os #Librería para interactuar con el entorno 12 import cv2 #Librería de visión artificial 13 from sklearn.neural_network import MLPClassifier #Clasificador MLP 14 from sklearn.externals import joblib #Para guardar/cargar clases en archivos 15 16 ###############################Función 1####################################### 17 18 #Función que crea el modelo MLP 19 def model_creator(): 20 #Por defecto, se tomará la carpeta Source 21 dirs=os.listdir(path='./Source/') 22 23 #Inicializando parámetros 24 encodings_final=[] 25 tags=[] 26 known_names=[] 27 28 print("Analizando directorios:") 29 for (directorio,index) in zip(dirs, range(len(dirs))): 30 #Muestra el directorio analizado 31 print(str(index+1) + ') ' + directorio) 32 load_dir(directorio, encodings_final, index, tags) 33 #Suponiendo que hay al menos un rostro correcto en cada directorio 34 known_names.append(directorio) 35 36 #Si se han obtenido algunas etiquetas (y por tanto encodings) 37 if tags: 38 #Crea y entrena el clasificador 39 clf = MLPClassifier(verbose=False, max_iter=1000, activation= 'tanh', hidden_layer_sizes = (100))
A.1 Sistema de reconocimiento facial 47 40 model = clf.fit(encodings_final, tags) 41 42 #Guarda el modelo de MLP entrenado y la lista de nombres 43 joblib.dump(model, './Model/MLPClassifier.pkl') 44 joblib.dump(known_names, './Model/Names.pkl') 45 print("Clasificador MLP creado.") 46 else: 47 print("No se obtuvieron rostros") 48 49 50 #Función que toma las imágenes de un directorio y obtiene la codificación sus rostros 51 def load_dir(directorio, encodings_final, index, tags): 52 path= './Source/' + directorio +'/' 53 #Lista con los nombres de las imágenes de la carpeta de la persona 54 file_list = os.listdir(path) 55 56 for imagen in file_list: 57 #Forma la ruta de la imagen 58 complete_path= path + imagen 59 #Carga la imagen y extrae su codificación (encodings) 60 imagen = face_recognition.load_image_file(complete_path) 61 encodings=face_recognition.face_encodings(imagen) 62 #Si se ha obtenido, se añade a la lista final de encodings y de etiquetas 63 if encodings: 64 encodings_final.append(encodings[0]) 65 tags.append(index) 66 67 68 ###############################Función 2####################################### 69 70 #Función que muestra los nombres disponibles 71 def print_names(): 72 73 try: 74 #Carga el modelo y los nombres disponibles 75 model=joblib.load('./Model/MLPClassifier.pkl') 76 known_names=joblib.load('./Model/Names.pkl') 77 except Exception: 78 sys.exit("No se pudo cargar el clasificador.") 79 80 #Si ambos existen se imprime la lista de nombres 81 if known_names and model: 82 print("Los nombres disponibles son:") 83 for i in range(len(known_names)): 84 print(str(i+1) + ') ' + known_names[i]) 85 else: 86 print("No hay nombres disponibles.") 87 88 89 ###############################Función 3####################################### 90 91 #Función para seleccionar la imagen o vídeo que se va a analizar 92 def select(path): 93 #Comprueba si se ha elegido imágen o vídeo y se carga el directorio 94 correct_path=(path == "Images/" or path == "Videos/")
48 Capítulo A. Códigos utilizados 95 if(correct_path): 96 file_list=os.listdir(path) 97 98 if not file_list: 99 print("Sin archivos para analizar.") 100 else: 101 print("Elija una opción:") 102 #Muestra la lista de archivos del directorio 103 for name,i in zip(file_list,range(len(file_list))): 104 print(str(i+1) + ') ' + name) 105 106 if path == "Images/": 107 print("Introduzca 'ALL' para todos.") 108 109 #Lee por teclado 110 num = input() 111 is_all= (num == "ALL" or num =="all") 112 113 #Analiza las imágenes o imagen o vídeo seleccionado 114 if path == "Images/" and is_all: 115 print("Se procesarán todas las imágenes.") 116 for img in file_list: 117 image(path+img) 118 print("Completado.") 119 elif num.isdigit(): 120 if(int(num) > 0 and int(num) <= len(file_list) ): 121 num=int(num)-1 122 name=file_list[num] 123 124 if path == "Images/": 125 image(path+name) 126 elif path == "Videos/": 127 video(path+name) 128 print("Completado.") 129 else: 130 print("Opción errónea.") 131 else: 132 print("Opción errónea.") 133 else: 134 print("Error.") 135 136 137 #Función que analiza los rostros de una imagen 138 def image(image_input): 139 #Toma la ubicación y encoding de cada rostro de la imagen 140 image = face_recognition.load_image_file(image_input) 141 (detected_names, face_locations)=detect(image) 142 143 #Inserta la ventana de identificación en la imagen 144 insert_name(detected_names, face_locations, image) 145 146 #Pasa del formato de color de face_recognition (RGB) al de OpenCV (BGR) 147 image = image[:, :, ::-1] 148 149 #Guarda la imagen procesada 150 splited_name=os.path.splitext(image_input) 151 name_image="./Output/"+splited_name[0]+"_out"+splited_name[1]
A.1 Sistema de reconocimiento facial 49 152 cv2.imwrite(name_image, image) 153 print(name_image+" creada.") 154 155 156 #Función que detecta las caras de una imagen y devuelve sus nombres y localizaciones 157 def detect(rgb_frame): 158 159 try: 160 #Carga el modelo 161 model=joblib.load('./Model/MLPClassifier.pkl') 162 known_names=joblib.load('./Model/Names.pkl') 163 except Exception: 164 sys.exit("No se pudo cargar el clasificador.") 165 166 detected_names=[] 167 #Establece el umbral: mínimo parecido posible 168 prox_min=0.8 169 170 # Encuentra todos los rostros del frame y obtiene sus encodings 171 face_locations = face_recognition.face_locations(rgb_frame) 172 face_encodings = face_recognition.face_encodings(rgb_frame) 173 174 n_face=0 175 for face_encoding in face_encodings: 176 [proximities]=model.predict_proba(face_encoding.reshape(1,-1)) 177 178 prox_max=max(proximities) 179 if prox_max >=prox_min: 180 tag=np.argmax(proximities) 181 proximity = prox_max*100 182 name = known_names[tag] + '('+str(round(proximity,2))+'%)' 183 detected_names.append(name) 184 else: 185 name = "Unknown" 186 detected_names.append(name) 187 n_face+=1 188 189 return detected_names, face_locations 190 191 192 #Función que añade a una imagen el marco con la identificación de cada rostro detectado 193 def insert_name(names, face_locations, frame): 194 for (top, right, bottom, left), name in zip(face_locations, names): 195 #Añade el marco y el texto a la imagen 196 cv2.rectangle(frame, (left, top), (right, bottom), (0,255,0), 2) 197 cv2.putText(frame, name, (left, top-6), cv2.FONT_HERSHEY_DUPLEX, 1, (0,255,0), 1) 198 199 200 ###############################Función 4####################################### 201 202 #Función que analiza los rostros de un vídeo 203 def video(video_input): 204 #Si video_input es 0, se usa la webcam y se muestra por pantalla 205
50 Capítulo A. Códigos utilizados 206 #Abre el vídeo 207 video = cv2.VideoCapture(video_input) 208 209 if (video.isOpened() == False): 210 print("No se pudo leer el video.") 211 else: 212 #Si se ha tomado un archivo de vídeo 213 if(video_input): 214 # Obtiene la resolución del video en formato entero. 215 frame_width = int(video.get(3)) 216 frame_height = int(video.get(4)) 217 218 splited_name=os.path.splitext(video_input) 219 220 video_name="./Output/"+splited_name[0]+"_out.avi" 221 # Crea el objeto que se encargará de guardar el vídeo destino 222 out = cv2.VideoWriter(video_name,cv2.VideoWriter_fourcc(*'XVID'), video.get(cv2.CAP_PROP_FPS), (frame_width,frame_height)) 223 print("Procesando video en: "+video_name+"...") 224 else: 225 print("Pulse ESPACIO para detener la grabación.") 226 227 #Se procesará un fotograma sí y otro no 228 process_this_frame=False 229 while (video.isOpened()): 230 # Toma un frame y comprueba 231 ret, frame = video.read() 232 process_this_frame=not process_this_frame 233 234 if ret==True: 235 if(process_this_frame): 236 #Convierte la imagen de color BGR (OpenCV) a RGB ( Face_Recognition) 237 rgb_frame = frame[:, :, ::-1] 238 (detected_names, face_locations)=detect(rgb_frame) 239 240 insert_name(detected_names, face_locations, frame) 241 #Si se toma de la cámara, se muestra por pantalla 242 if(not video_input): 243 # Muestra la iamgen por pantalla 244 cv2.imshow('Video', frame) 245 else: 246 out.write(frame) 247 248 # Se detiene si se presiona la barra espaciadora 249 if cv2.waitKey(1) & 0xFF == ord(' '): 250 video.release() 251 break 252 else: 253 break 254 255 if(not video_input): 256 cv2.destroyAllWindows() 257 else: 258 out.release()
A.2 Experimentos 51 A.2 Experimentos En este apartado se muestra el Código A.3, que recoge las funciones que han sido utilizadas para llevar a cabo los experimentos para fijar una estructura del MLP final. Las líneas 49, 50 y 51 han sido modificadas en función del experimento que se quisiera ensayar. En el Código A.3 se muestra la función completa para el último experimento y en el Código A.4 se recogen las líneas correspondientes a cada experimento. Código A.3 inicio.py. 1 # -*- coding: utf-8 -*- 2 """ 3 Created on Mon Jul 9 19:22:17 2018 4 5 @author: Ildefonso Jiménez Silva 6 """ 7 import funciones 8 import os #Interactuar con el entorno 9 from sklearn.neural_network import MLPClassifier 10 from sklearn.externals import joblib #Para guardar/cargar clases en archivos 11 from sklearn.model_selection import train_test_split 12 13 #Función que obtiene las características extraídas de cada rostro de las imá genes que conforman la base de datos 14 def carga_datos(): 15 #Por defecto, se tomará la carpeta Source 16 dirs=os.listdir(path='./Source/') 17 18 #Inicializando parámetros 19 encodings_final=[] 20 tags=[] 21 22 #Se extraen las características de las imágenes 23 print("Analizando directorios:") 24 for (directorio,index) in zip(dirs, range(len(dirs))): 25 #Muestra el directorio analizado 26 print(str(index+1) + ') ' + directorio) 27 funciones.load_dir(directorio, encodings_final, index, tags) 28 29 #Guarda los datos en dos ficheros para evitar repetir este proceso en los experimentos 30 joblib.dump(encodings_final, './Model/encodings.pkl') 31 joblib.dump(tags, './Model/tags.pkl') 32 33 #Función que realiza los experimentos 34 def experimentos(n_iter): 35 #Carga los vectores de características guardados de cada rostro y su correspondiente etiqueta para identificar de quién se trata 36 X=joblib.load('./Model/encodings.pkl') 37 Y=joblib.load('./Model/tags.pkl') 38 39 (aciertos_prc1_total, aciertos_prc2_total, aciertos_prc3_total)=(0,0,0) 40 (prob_total1, prob_total2, prob_total3)=(0,0,0) 41 42 #Se realizará el número de iteraciones que se elija al llamar a la función 43 for iteration in range(n_iter):
52 Capítulo A. Códigos utilizados 44 print("Iteración número:", iteration+1) 45 #Divide la base de datos en entrenamiento y validación 46 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2) 47 48 #Crea y entrena los diferentes MLPs 49 clf1 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100)) 50 clf2 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (150)) 51 clf3 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (200)) 52 53 model1=clf1.fit(X_train, Y_train) 54 model2=clf2.fit(X_train, Y_train) 55 model3=clf3.fit(X_train, Y_train) 56 57 #Calcula el númmero de aciertos a partir de los datos de validación 58 aciertos_prc1_total+=model1.score(X_test, Y_test)*100 59 aciertos_prc2_total+=model2.score(X_test, Y_test)*100 60 aciertos_prc3_total+=model3.score(X_test, Y_test)*100 61 62 #Calcula las probabilidades obtenidas por los MLP y calcula su media 63 probs1=model1.predict_proba(X_test) 64 probs2=model2.predict_proba(X_test) 65 probs3=model3.predict_proba(X_test) 66 67 (probi1, probi2, probi3)=(0,0,0) 68 69 for prob1, prob2, prob3, label in zip(probs1, probs2, probs3, Y_test): 70 probi1+=prob1[label] 71 probi2+=prob2[label] 72 probi3+=prob3[label] 73 74 N=len(probs1) 75 76 prob_total1+=probi1/N 77 prob_total2+=probi2/N 78 prob_total3+=probi3/N 79 80 #Prepara los datos finales diviendo entre el número de iteraciones para calcular la media de cada parámetro 81 aciertos_prc1_total/=n_iter 82 aciertos_prc2_total/=n_iter 83 aciertos_prc3_total/=n_iter 84 aciertos = [aciertos_prc1_total, aciertos_prc2_total, aciertos_prc3_total] 85 86 prob_total1/=n_iter 87 prob_total2/=n_iter 88 prob_total3/=n_iter 89 probabilidades=[prob_total1*100, prob_total2*100, prob_total3*100] 90 91 return aciertos, probabilidades Código A.4 inicio.py.
A.2 Experimentos 53 1 #Crea y entrena los diferentes MLPs del experimento 1 2 clf1 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'relu', hidden_layer_sizes = (100)) 3 clf2 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100)) 4 clf3 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'logistic', hidden_layer_sizes = (100)) 5 6 #Crea y entrena los diferentes MLPs del experimento 2 7 clf1 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100)) 8 clf2 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100,100)) 9 clf3 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100,100,100)) 10 11 #Crea y entrena los diferentes MLPs del experimento 3 12 clf1 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (50)) 13 clf2 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (100)) 14 clf3 = MLPClassifier(verbose=False, max_iter=1000, random_state=1, activation= 'tanh', hidden_layer_sizes = (150))
Índice de Figuras 2.1 Diagrama de un sistema de reconocimiento facial 4 2.2 Aplicación de Haar-like features a una imagen [7] 5 2.3 Diagrama simplificado del proceso de AdaBoost 5 2.4 Estructura del detector facial basado en CNN en cascada [11] 6 2.5 Ejemplo del cálculo de una imagen HOG 7 2.6 Detector HOG para encontrar rostros en una imagen [15] 8 2.7 Deformación de un objeto en el eje x[16] 9 2.8 Ejemplo del preprocesamiento de una imagen 10 2.9 Clasificación de las técnicas de reconocimiento facial 11 2.10 Representación gráfica del algoritmo KNN 13 2.11 Representación de un hiperplano óptimo en un problema de clasificación [29] 13 3.1 Representación de una neurona artificial genérica 16 3.2 Estructura de un Perceptrón Multicapa 18 3.3 Representación general de la estructura de una CNN [31] 19 3.4 Representación de la operación de convolución con un kernel [31] 20 3.5 Funcionamiento de la capa de pooling [32] 21 3.6 Ejemplo del funcionamiento de los triplets [33] 21 4.1 Ejemplo del cálculo de una imagen HOG 24 4.2 Los 68 puntos de referencia que serán buscados en cada imagen [41] 25 4.3 Ejemplo de preprocesamiento de una imagen 25 4.4 Introducción al menú de la interfaz 27 4.5 Comportamiento de la interfaz durante la creación de un modelo de MLP 27 4.6 Lista de imágenes mostradas con la tercera opción del menú 28 4.7 Opciones de reconocimiento facial en vídeo 28 5.1 Validación Cruzada con selección aleatoria 30 5.2 Funciones que serán evaluadas como función de activación del MLP 31 5.3 Imagen resultante tras ser procesada por el sistema 36 5.4 Ejemplo de imágenes con gafas de sol 36 5.5 Segundo ejemplo de fotografías con gafas de sol 37 5.6 Comportamiento ante personas de perfil 37 55