Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Sirve 1

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 74

Introducción a las redes

neuronales artificiales

UNIVERSIDAD COMPLUTENSE DE
MADRID
GRADO EN INGENIERÍA MATEMÁTICA

Trabajo n de grado
Juan Miguel Sierra Ramos
Tutor: Antonio López Montes
Facultad de Matemáticas
Departamento de Análisis Matemático y Matemática Aplicada

Curso: 2021/2022
27 de febrero de 2022
Resumen

En la actualidad las redes neuronales son una de las herramientas con ma-
yor número y variedad de aplicaciones a todos los campos de la ciencia , la
ingeniería, la medicina, la arquitectura. . .. A diario aparecen en los medios de
comunicación noticias que relacionan a las redes neuronales con aplicaciones
novedosas, sorprendentes y muy prometedoras.
El ánimo que nos mueve en la realización de este trabajo es profundizar en
el conocimiento y las aplicaciones de las redes neuronales.
La estructura del trabajo es la siguiente: en este primer apartado hablamos
sobre la historia de las redes neuronales articiales, describimos los componen-
tes básicos de las redes neuronales, las neuronas articiales, y de donde surgen.
Así como algunos conceptos básicos que nos serán útiles en el desarrollo de los
modelos. En el segundo apartado presentamos los primeros modelos de redes
neuronales articiales junto a sus algoritmos de aprendizaje y algunos ejemplos.
En el tercer y último apartado, desarrollamos algunos ejemplos de redes neuro-
nales articiales multicapa y tratamos las redes neuronales convolucionales.

Palabras clave

Adaline, Backpropagation, Hopeld, Perceptrón, Red Neuronal articial,


Red neuronal convolucional.

1
Abstract

Nowadays, articial neural networks are a tool with lot of applications in


many elds of the science such as engineering, medicine, architecture . . . .Daily
we see news that link articial neural networks to astonising results in various
elds.
The objetive of this proyect is making a reference where you can dive into
the knowledge and the applications of articial neural networks.
The proyect is structured as follow: on the rst section we talk about the
history of articial neural networks, their basic components and how all of them
emerged. The second section presents the rsts models and their learning process
with a few examples. On the third and last section we develop more examples
and we talk about the convolutional neural networks.

Keywords

Adaline, Articial Neural Network, Backpropagation, Convolutional Neural


Network, Hopeld, Perceptron.

2
Índice

Índice de guras 5
1. Fundamentos 6
1.1. Un poco de historia . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Introducción teórica . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.1. La neurona . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.2. La neurona articial . . . . . . . . . . . . . . . . . . . . . 8
1.3. Funciones de activación . . . . . . . . . . . . . . . . . . . . . . . 9
1.3.1. Función de Salto Binaria . . . . . . . . . . . . . . . . . . 9
1.3.2. Unidad Recticada Uniforme (RELU) . . . . . . . . . . . 10
1.3.3. Función SoftMax . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.4. Función sigmoide . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.5. Tangente hiperbólica (Tanh) . . . . . . . . . . . . . . . . 11
1.4. Aprendizaje supervisado y aprendizaje no supervisado . . . . . . 12
1.5. Overtting y undertting . . . . . . . . . . . . . . . . . . . . . . 12

2. Los primeros modelos 13


2.1. El Perceptrón . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.1.1. Algoritmo de aprendizaje . . . . . . . . . . . . . . . . . . 14
2.1.2. Ejemplo:Clasicación de conjuntos linealmente separables 15
2.2. ADALINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1. Algoritmo de aprendizaje . . . . . . . . . . . . . . . . . . 17
2.2.2. Ejemplo:Decodicador . . . . . . . . . . . . . . . . . . . . 18
2.3. Algoritmo del Gradiente Descendente . . . . . . . . . . . . . . . . 19
2.4. Redes Hopeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4.1. Estructura de la red . . . . . . . . . . . . . . . . . . . . . 21
2.4.2. Aprendizaje . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4.3. Función de Energía . . . . . . . . . . . . . . . . . . . . . . 23
2.4.4. Problema del viajante con redes Hopeld . . . . . . . . . 23
2.4.5. Ejemplo:Problema del viajante . . . . . . . . . . . . . . . 24
2.5. Perceptrón multicapa . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.6. Algoritmo Backpropagation . . . . . . . . . . . . . . . . . . . . . 27
2.6.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.6.2. Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3
ÍNDICE 4

3. Aplicaciones de redes multicapa 32


3.1. Perceptrón Multicapa:Clasicación de Patrones . . . . . . . . . . 32
3.2. Perceptrón multicapa: Curvas de Funciones . . . . . . . . . . . . 34
3.3. Redes neuronales convolucionales . . . . . . . . . . . . . . . . . . 36
3.3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3.2. Convolución . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3.3. Pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3.4. Entrenamiento . . . . . . . . . . . . . . . . . . . . . . . . 42
3.3.5. Redes pre-entrenadas . . . . . . . . . . . . . . . . . . . . 44
3.3.6. Alexnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.3.7. Ejemplo:Alexnet . . . . . . . . . . . . . . . . . . . . . . . 45

Bibliografía 47
Referencias Web 49
Anexo:GoogleNet 50
Anexo:Códigos 55
Índice de guras

1.1. Neurona . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2. Función salto binario . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3. Función RELU . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4. Función sigmoide . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.5. Función tangente hiperbólica . . . . . . . . . . . . . . . . . . . . 11

2.1. Estructura de un Perceptrón . . . . . . . . . . . . . . . . . . . . 13


2.2. Nube de puntos a dividir . . . . . . . . . . . . . . . . . . . . . . . 15
2.3. Recta inicial sin entrenar . . . . . . . . . . . . . . . . . . . . . . 15
2.4. Recta entrenada . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5. Estructura de la red ADALINE . . . . . . . . . . . . . . . . . . . 17
2.6. Error cuadrático medio a lo largo del entrenamiento . . . . . . . 19
2.7. Situaciones en función del valor α . . . . . . . . . . . . . . . . . . 20
2.8. Estructura de un perceptrón multicapa . . . . . . . . . . . . . . . 26
2.9. Nomenclatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.1. Ejemplo puerta XOR . . . . . . . . . . . . . . . . . . . . . . . . . 33


3.2. Error durante el entrenamiento . . . . . . . . . . . . . . . . . . . 33
3.4. Imagen original en escala de grises . . . . . . . . . . . . . . . . . 39
3.5. Filtro Sobel 3.3.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.6. Max-pooling con desplazamiento de 2 . . . . . . . . . . . . . . . 41
3.7. Estrucura de Alexnet . . . . . . . . . . . . . . . . . . . . . . . . . 45

5
1. Fundamentos

1.1. Un poco de historia


El primer modelo de una red neuronal articial surge en 1943, de la mano de
Warren McCulloch y Walter Harry Pitts. Pretende simular el funcionamiento
de una neurona en el cerebro humano. Es un modelo básico y que no se llegó a
implementar físicamente debido a las limitaciones técnicas de la época.
Hebb [6] escribe The Organization of Behavior libro que establece una co-
nexión entre psicología y siología. Postula que la información se representa
en el cerebro mediante un conjunto de neuronas activas o inactivas y que el
aprendizaje se localiza en las conexiones entre las neuronas. Da lugar a la teo-
ría hebbiana que sentó las bases que todavía se usan en el desarrollo de redes
neuronales articiales.
En 1958 Rosenblatt [21] elabora el modelo del perceptrón, modelo formado
por una única neurona articial que posee una salida binaria y que es capaz
de variar sus pesos. El Perceptrón puede resolver problemas de clasicación
cuya solución presenta una separación lineal, por ejemplo la puerta AND o la
puerta OR. Sin embargo el Perceptrón es incapaz de resolver problemas que no
presentan una solución lineal, como sería el ejemplo de la puerta XOR.
Dos años más tarde se desarrolla el modelo Adaptative Linear Neuron (ADA-
LINE) de la mano de Bernard Widrow y Ted Ho, red neuronal articial con una
estructura también sencilla pero que en lugar de presentar una salida binaria
genera salidas reales y utiliza el método de la regla delta en su aprendizaje. La
red ADALINE incorpora más neuronas, aunque sigue teniendo una sola capa.
Marvin and Seymour [12] publican en su libro Perceptrons las deciencias
de los modelos monocapa, lo que provoca una ralentización en el desarrollo tanto
teórico como práctico de las redes neuronales hasta mediados de la década de los
ochenta [4]. Durante este periodo surgen modelos alternativos a los establecidos
como por ejemplo la red Hopeld.
Es, con la publicación del algoritmo Backpropagation de Rumelhart, Hin-
ton, and Williams [22] en 1986, cuando se produce el resurgir del desarrollo de
las redes neuronales articiales. Este algoritmo presenta una nueva forma de
aprendizaje para las redes neuronales, mediante la retropropagación de errores
desde las últimas capas y haciendo uso del descenso del gradiente para corregir
este error.

6
El desarrollo tecnológico de las últimas décadas, así como la aparición de
grandes conjuntos de datos, como los grandes conjuntos de imágenes de uso libre
que veremos, ha permitido la elaboración de nuevas y mas ecientes estructuras
en las redes neuronales articiales como son las redes neuronales convolucionales
o las redes neuronales recurrentes entre otras.
Cabe destacar la aparición en los últimos años de redes neuronales pre-
entrenadas, las cuales se enfocan en la realización de una tarea especíca con
enormes cantidades de datos y una estructura compleja. Un ejemplo de estas
redes son VGG16 o VGG19 dos redes neuronales convolucionales pre-entrenadas
en la tarea de clasicación de imágenes.
En los últimos años, han surgido multitud de aplicaciones de las redes neu-
ronales articiales con resultados prometedores. Por citar algunas de las últimas
estructuras tenemos alphafold y alphafold2 aplicadas en el campo de la biomedi-
cina y que lograron resolver el problema planteado en la competición CASP [1]
1
una competición para decidir el software que predice mejor la estructura de pro-
teínas a partir de sus secuencias de aminoácidos. TCAV un método que permite
visualizar como actuan las capas intermedias u ocultas de las redes neuronales
[9]. VQGAN red neuronal capaz de producir imágenes a partir de texto[2].

1 Critical Assessment of Protein Structure Prediction

Introducción a las redes neuronales articiales 7


1.2. Introducción teórica
1.2.1. La neurona
La neurona es un tipo de célula
diferente del resto. Forma parte del
sistema nervioso, que es el responsa-
ble de todas las funciones cognitivas.
Está formada por 3 partes fundamen-
tales: el núcleo o soma , las dendritas
y el axón. Las señales son recibidas
a través de las dendritas , estas se-
ñales pueden provenir de un sistema
sensorial externo o de otra neurona.
El núcleo procesa esta información y
la envía por el axón el cual posee va-
rios terminales. Una neurona puede
recibir información de miles de otras
Figura 1.1: Representación de una neu-
neuronas y enviar información a otros
rona
miles de ellas.
Se estima que en el cerebro tene-
mos unas 1011 neuronas con 1015 conexiones, gracias a estar tan altamente
conectadas es como consiguen una gran capacidad de procesamiento y realiza-
ción de tareas complejas. La comunicación entre neuronas no es física sino que
se hace a través de la sinapsis, un espacio ocupado por sustancias químicas de-
nominadas neurotransmisores. Estos son los que se encargan de bloquear o dejar
pasar las señales. Dichas señales se procesan en el núcleo de la neurona y bajo
ciertas condiciones apropiadas(activación) se transmiten a través del axón.

1.2.2. La neurona articial


La pieza básica sobre la que se desarrollan las redes neuronales es la neurona
articial(o simplemente neurona), la cual, puede ser entendida no como una
estructura física sino como una función que trata de modelar matemáticamente
el funcionamiento de una neurona del cerebro humano.
La información recibida por
la neurona se representa como el
vector ~x = (x1 , x2 , . . . , xn ) ∈ Rn .
Para modelar la sinapsis otorga-
mos unos pesos sinápticos wi a
cada entrada xi para todo i =
1, . . . , n. Estos dan lugar al vector
de pesos w ~ = (w1 , . . . , wn ) ∈ Rn .
La neurona articial realiza un
producto escalar entre los vecto-
res ~x y w
~ . A este producto escalar

Introducción a las redes neuronales articiales 8


se le añade el umbral(bias) w0 de la neurona, que representa el valor a partir
del cual se considerará que la neurona se activa. La neurona realiza una suma
ponderada de las entradas por los pesos asignados a lo que suma el bias:

n
X
EntradaN eta =< ~x, w
~ > +w0 = xi wi + w0 = x1 w1 + . . . + xn wn + w0 (1.1)
i=1

A esta suma se le llama también entrada neta de la neurona, la activación


o no de la neurona articial vendrá además determinada por la función de
activación. El uso de esta función de activación nos permite la concatenación de
neuronas, pues la sucesión de múltiples regresiones lineales sería equivalente a
realizar solo una regresión lineal. La salida de la neurona vendrá determinada
por la función de activación del valor de la cantidad neta 1.1:

y = f (EntradaN eta) = f (x1 w1 + . . . + xn wn + w0 ) (1.2)

Podemos ver un análisis más profundo de como la neurona articial surge


del modelado de la neurona biológica en [2], [20].
La versatilidad en las redes neuronales reside en la concatenación de muchas
neuronas. Esto permitirá al modelo poder tener en consideración tanto los ele-
mentos de nuestro problema como la relación entre los mismos. No obstante,
como comentamos antes, la concatenación de funciones lineales da como resul-
tado una función lineal. Tenemos entonces que aplicar una transformación no
lineal, es aquí donde entran las funciones de activación.

1.3. Funciones de activación


Pasamos a describir las principales funciones de activación (f ) usadas en las
redes neuronales articiales 1.2. Recordemos que la entrada de estas funciones
es la suma ponderada de los valores de entrada de las neuronas por sus pesos,
sumando el parámetro de Bias 1.1. Describiremos brevemente las funciones de
activación más usadas e importantes.

1.3.1. Función de Salto Binaria


La primera de las funciones de activación que usaron las redes neuronales
articiales, está presente en las estructuras del Perceptrón y Hopeld que vere-
mos más adelante. Haciendo uso del Bias o parámetro de sesgo, desplazaremos
esta función según se requiera. Pueden tomarse tanto el valor 0 como 1 en la
discontinuidad de la función. Es una función que anula todos los valores que
estén a la izquierda de la discontinuidad y establece en 1 todos aquellos que
estén a la derecha.

Introducción a las redes neuronales articiales 9


Figura 1.2: Función salto binario

1.3.2. Unidad Recticada Uniforme (RELU)

f (x) = max(0, x)
Mediante esta función de activación consideramos solo los valores positivos
para la salida, es la más usada pues tiene un menor coste computacional que
otras funciones de activación denidas más adelante.

Figura 1.3: Función RELU

1.3.3. Función SoftMax

α : RK → [0, 1]K
ezj
α(z)j = PK j = 1, . . . , K
k=1 ez k
Su coste computacional es bastante más elevado que el de la RELU. Devuelve
valores en el intervalo [0, 1] que suman 1 en total, por lo que muchas veces se
usa para asignar probabilidades en problemas categóricos.

Introducción a las redes neuronales articiales 10


1.3.4. Función sigmoide
1
P (t) =
1 + e−t
Otra función bastante usada al nal de las redes neuronales reeja muy bien
la curva de aprendizaje de cualquier red, penalizando aquellos valores cercanos
a cero o a uno. Su coste computacional es bastante elevado lo que hace que para
estructuras elaboradas de redes neuronales no se use dicha función de activación
en las capas intermedias.

Figura 1.4: Función sigmoide

1.3.5. Tangente hiperbólica (Tanh)


2
f (x) = −1
1 + e−2x
Actúa de manera similar a las 2 funciones de activación anteriores, devol-
viendo los valores en el intervalo (-1,1) en lugar de (0,1). Al igual que la sigmoide
reeja muy bien la curva de aprendizaje del modelo.

Figura 1.5: Función tangente hiperbólica

Introducción a las redes neuronales articiales 11


1.4. Aprendizaje supervisado y aprendizaje no supervisado
Nuestros datos se representan mediante un vector con n componentes, donde
cada componente es una variable que nuestro problema contempla. Así, repre-
sentamos con x~j = (xj1 , . . . , xjn ) la observación j-ésima de nuestras variables
j = 1, . . . , P . Siendo P el número total de observaciones con las que trabajare-
mos.
Podemos tener una o varias variables que se desean estudiar, a las que lla-
maremos variables respuestas y que denotaremos por d~j = (dj1 , . . . , djm ) j=
con

1, . . . , P . En el aprendizaje supervisado tenemos las respuestas ~j )


esperadas(d
para esas P observaciones. Lo que nos permitirá entrenar a las redes neurona-
les articiales. Así formamos patrones de entrenamiento donde cada patrón j
se dene como el par {x~j |d~j } j = 1, . . . , P , es decir, cada patrón está formado
por una observación y las salidas esperadas para dicha observación. Si por el
contrario se presentan los datos de entrada x~j en la red estaremos trabajando
con técnicas de aprendizaje no supervisado.
El uso de una red neuronal requiere del diseño de una estructura para la red.
Esta puede ser elaborada o se puede emplear una estructura ya creada. Se debe
decidir tanto el número de capas que posee la red como el número de neuronas
de cada capa. No existe ningún criterio para los mismos, no obstante, se suele
poner un número de neuronas más elebado en las primeras capas que en las
posteriores [25].

1.5. Overtting y undertting


Cuando trabajamos con cualquier método relacionado con el tratamiento de
datos para realizar una tarea de aprendizaje debemos tener cuidado a la hora
de entrenar. Se pueden presentar 2 situaciones durante el entrenamiento que
debemos evitar. La primera es cuando nuestro modelo durante la fase de entre-
namiento no da buenos resultados, es decir, no aprende o tiene mucho sesgo
2
[19]. Si suponemos que estamos desarrollando un modelo para diferenciar fotos
de perros y gatos, nuestro modelo tendría undertting si durante el entrena-
miento no llegase nunca a poder diferenciar entre ambos conjuntos de datos.
La otra situación, denominada overtting, que se puede presentar se detecta
con datos externos a los usados durante el entrenamiento. En este caso, nuestro
modelo sí ha obtenido un buen desempeño en la fase de entrenamiento con
las fotos proporcionadas, no obstante, al usar una foto de un perro o un gato
externa al conjunto de entrenamiento nuestro modelo no diferencia de forma
correcta. Esto puede ocurrir por varias razones , pero la principal es una falta
de generalización en el propio conjunto de datos de entrenamiento, por ejemplo
si durante la fase de entrenamiento usásemos solo fotos de razas grandes de
perros, al presentar una nueva foto con razas de perros pequeñas el modelo
podría equivocarse.

2 Diferencia entre la respuesta obtenida y la esperada

Introducción a las redes neuronales articiales 12


2. Los primeros modelos

En este apartado vamos a introducir los modelos básicos de redes neuronales


en el orden cronológico en que se desarrollaron. Describiremos sus procesos de
aprendizaje y como estos mismos han ido evolucionando para solventar proble-
mas que iban surgiendo. La combinación de estructuras complejas y entrena-
mientos ecientes han dado lugar a la evolución que se ha vivido en el mundo
de la inteligencia articial.

2.1. El Perceptrón
El perceptrón fue el primer modelo de una red neural articial. Es capaz
de resolver problemas con una supercie de separación lineal. Su estructura es
sencilla, posee varias entradas(x1 , x2 , . . . , xn ) con pesos (w1 , w2 , . . . , wn ) y una
única salida (y) con una función de activación binaria como vemos en la imagen
2.1, donde hemos supuesto que w0 es el bias de la neurona.


1 si w1 x1 + w2 x2 + . . . + wn xn + w0 ≥ 0
f (w1 x1 +w2 x2 +. . .+wn xn +w0 ) =
0 si w1 x1 + w2 x2 + . . . + wn xn + w0 ≤ 0

Figura 2.1: Estructura de un Perceptrón

13
Si suponemos un perceptrón con 2 entradas (x1 , x2 ) de pesos (w1 , w2 ) y sesgo
w0 . La función de activación crea una separación en el plano formado por el par
(x1 , x2 ).
x1 w1 + x2 w2 + w0 = 0
Que corresponde a la recta de ecuación:

w1 w0
x2 = − x1 −
w2 w2
Si ampliamos una dimensión más considerando una tercera entrada x3 , obten-
dremos que la función de activación separa el espacio con el plano:

w1 w2 w0
x3 = − x1 − x2 −
w3 w3 w3
En general, si tenemos n entradas la función de activación generará una división
en el espacio euclídeo n-dimensional cuya frontera es un hiperplano[3].

2.1.1. Algoritmo de aprendizaje


En primer lugar, asignamos unos pesos (w1 , w2 , . . . , wn ) a las entradas de
la neurona, así como elegimos un bias o sesgo w0 1 . Dichos valores se suelen
tomar en el intervalo [−1, 1] e irán cambiando a lo largo del entrenamiento en
caso de ser necesario. Suponemos que tenemos un conjunto de vectores X =
{x~1 , x~2 , . . . , x~p } correspondientes a los P patrones de entrenamiento de salidas
esperadas D = {d ~1 , d~2 , . . . , d~p } donde cada d~i ∈ R al tratarse de un perceptrón
con una sola salida. La salida del perceptrón viene dada por:

n
X
y = f( (wi xi ) + w0 )
i=1

Siendo f la función de activación denida en 2.1. Podemos pues, calcular la


diferencia entre la salida deseada di para el vector de entrada x~i y el valor
obtenido por el perceptrón con esas entradas yi . Esto nos da el error cometido
para ese patrón de entrenamiento:

ej = dj − yj para j = 1, . . . , P

A continuación, se actualizan los pesos de las entradas siguiendo la siguiente


fórmula, tenemos en cuenta que nos encontramos con el patrón de entrenamien-
to j(j = 1 . . . , P ) formado por el par {x~j |dj } y tenemos un error cometido
ej (debido a la forma de la función de activación este error tomará los valores
0,1 o -1):

wi (t + 1) = wi (t) + αej xji P ara i = 1, . . . , n


w0 (t + 1) = w0 (t) + αej
1 Puede verse que el sesgo sirve para que la recta que separará el plano no quede anclada
en el origen

Introducción a las redes neuronales articiales 14


Donde wi (t) es el valor del peso i-ésimo en la fase de entrenamiento t ,
wi (t + 1) el nuevo valor que le damos, w0 (t) es el sesgo en la misma fase y α
es el factor de aprendizaje. Actualizamos los pesos de las entradas y el sesgo
hasta que todas las salidas del perceptrón sean iguales a las salidas deseadas o
hasta que llegamos a un número determinado de iteraciones. En el último caso
deberemos tratar de cambiar los parámetros iniciales, aumentar el número de
iteraciones o tratar de buscar una estructura de red neuronal más elaborada.
El Perceptrón realiza su proceso de entrenamiento en base a la diferencia
entre las entradas obtenidas y las deseadas, sin buscar ningún óptimo en la
función de costes como algunas estructuras que veremos en secciones posteriores.
Esto provoca que el algoritmo de aprendizaje pueda darnos distintos resultados,
todos válidos, para diferentes conguraciones de peso iniciales. Asimismo, hace
a esta red neuronal articial vulnerable a los datos con ruido.

2.1.2. Ejemplo:Clasicación de conjuntos linealmente separables


En el siguiente ejemplo usaremos el perceptrón para separar dos conjuntos
de puntos distintos presentados de la siguiente forma.

Figura 2.2: Nube de puntos a dividir

Dada una recta cuyos parámetros iniciales los establecemos de forma aleato-
ria, mediante el uso del perceptrón, se variarán dichos parámetros para dividir
de forma correcta el plano separando ambas nubes de puntos.

Figura 2.3: Recta inicial sin entrenar

Introducción a las redes neuronales articiales 15


Haciendo uso del perceptrón, se entrenarán los parámetros de la recta hasta
que la misma separe de forma correcta los puntos. A diferencia de otras re-
des neuronales articiales que veremos más adelante, con la salida binaria del
perceptrón solo se puede determinar si una salida es correcta o incorrecta no
pudiendo cuanticar cuanto dieren. El resultado nal se muestra en la siguiente
imagen:

Figura 2.4: Recta entrenada

Puede encontrarse el código implementado en Matlab en 3.3.7. Tanto la


formulación teórica como el ejemplo aparecen en [2].

Introducción a las redes neuronales articiales 16


2.2. ADALINE
La red ADALINE o Adaptative Linear
Neuron es similar al perceptrón, es una red
monocapa con varias entradas conectadas to-
talmente. Su salida es un número real, no bi-
naria como en el caso del Perceptrón.
Mientras que en el Perceptrón se denía
simplemente si la red tiene una salida erró-
nea o correcta durante el aprendizaje, la red
ADALINE toma en cuenta cuanto diere la
salida obtenida de la esperada.Tanto el de-
Figura 2.5: Estructura de la red
sarrollo teórico de esta red como el ejemplo
ADALINE
presentado de la misma pueden encontrarse
tratados con mayor extensión en [24].

2.2.1. Algoritmo de aprendizaje


La red ADALINE emplea en su proceso de aprendizaje un algoritmo todavía
muy presente en las redes neuronales actualmente, la llamada Regla Delta que
fue la precursora del algoritmo Backpropagation. Este algoritmo se basa en la
idea del empleo de las derivadas parciales para, dado un punto, hacerlo avanzar
hacia el mínimo de la función. Para ello denimos el error total producido en
los P patrones de entrenamiento como:

P m P
1 XX 1X
J= (dij − yij )2 = ej (2.1)
2 j=1 i=1 2 j=1

Es decir, hacemos uso del error cuadrático. Donde d~j = (d1j , . . . , dmj ) ∈ Rm es el
valor de salidas deseadas para el patrón de entrenamiento j e y ~j = (y1j , . . . , ymj ) ∈
Rm es el vector de salidas de la red en el patrón de entrenamiento. El objetivo
del algoritmo es encontrar el conjunto de pesos que haga mínimo J . En cada
patrón de entrenamiento j ∈ {1, . . . , P } se ajustan los pesos wik entre la entrada
i-ésima y la neurona k-ésima de la siguiente forma:

wik (t + 1) = wik (t) + 4wik (t) (2.2)

w0k (t + 1) = w0k (t) + 4w0k (t) (2.3)

∂J
Con 4wik (t) = −α ∂wik
con i = 0, . . . , n(numero de entradas en la primera capa) k =
1, . . . , m(numero de N euronas)
Aplicando la regla de la cadena tenemos:

∂J ∂J ∂ej ∂ykj
=
∂wik ∂ej ∂ykj ∂wik
Por 2.1 tenemos:
∂J 1
=
∂ej 2

Introducción a las redes neuronales articiales 17


Como ej = (d1j − y1j )2 + . . . + (dkj − ykj )2 + . . . + (dmj − ymj )2 :

∂ej
= −2(dkj − ykj )
∂ykj
Por último, ykj = w1k x1 + . . . + wik xi + . . . + wnk xn + w0k :

∂ykj
= xi i = 1, . . . , n
∂wik
∂ykj
=1
∂w0k
Así:

∂J
= −(dkj − ykj )xi , 4wik (t) = α(dkj − ykj )xi
∂wik
i = 1, . . . , n k = 1, . . . , m
∂J
= −(dkj − ykj ) , 4w0k (t) = α(dkj − ykj )
∂w0k
Con lo que la fórmula del aprendizaje 2.2 nos queda:

wik (t + 1) = wik (t) + α(dkj − ykj )xi , w0k (t + 1) = w0k (t) + α(dkj − ykj )

Repetimos el proceso hasta que el valor del error total J es menor que un valor
determinado o hasta que lleguemos a un número de iteraciones.
La elección del factor o ratio de aprendizaje α es crucial, si lo tomamos
demasiado pequeño el algoritmo avanzará demasiado lento pero si lo escogemos
muy grande el algoritmo tendrá inestabilidad alrededor del mímimo de J. A
diferencia del Perceptrón, diferentes valores de pesos iniciales nos darán el mismo
resultado tras el entrenamiento. Pese a esto, la red ADALINE solo es capaz de
separar clases que tienen una separación lineal. Al introducir un valor tras la
fase de entrenamiento la red propagará los valores obtenidos multiplicandolos
por los pesos wij entrenados produciendo así las salidas yj , el hecho de converger
hacia el mínimo de J hace a esta red más robusta analizando datos con ruido.

2.2.2. Ejemplo:Decodicador
Un decodicador tomará números escritos en binario y los con-
vertirá en número decimales, nuestro objetivo en este ejemplo es
emplear a la red ADALINE con este propósito. Cuando la red re-
ciba cada una de las entradas buscamos, mediante el aprendizaje,
obtener las diversas salidas. La red estará formada por una única
neurona con 3 entradas(x1 , x2 y x3 ).
Iniciamos con un valor en el factor de aprendizaje α = 0,3 y
una precisión de parada requerida de 0,001. Los pesos iniciales
tomados son w = (30 12, 2, 10 86) , la red irá variando estos pesos
de forma proporcional a la diferencia entre la salida obtenida y

Introducción a las redes neuronales articiales 18


la esperada. De esta forma obtenemos la siguiente tabla donde se
reeja como los pesos varían minimizando el error en cada paso
hasta obtener un valor menor que la precisión requerida.

Iteración Pesos Error


1 3.6084984 1.9855184 1.4244324 0.3116599
2 3.8234569 1.9823698 1.20311109 0.06892449
3 3.92060785 1.98678987 1.09678491 0.01502946
4 3.9644138 1.99157779 1.04595917 0.00327488
5 3.98410452 1.99505004 1.02175287 0.00071314

Cuadro 2.1: Ajuste de los pesos en el proceso de entrenamiento

Figura 2.6: Error cuadrático medio a lo largo del entrenamiento

Este proceso está implementado en python y puede encontrarse en 3.3.7.

2.3. Algoritmo del Gradiente Descendente


Método iterativo, dado un punto inicial lo desplaza siguiendo el valor nega-
tivo del gradiente hasta un punto crítico que será un mínimo local de la función.
Este algoritmo es local pues encontrar el mínimo global de la función sería
computacionalmente muy exigente. Es bastante popular para grandes proble-
mas de optimización por su fácil implementación, así como su reducción en el
costo de procesamiento a medida que el algoritmo avanza. La principal desven-
taja es que puede converger muy lento o incluso no converger dependiendo del
tamaño del ratio de aprendizaje que elijamos o si el punto inicial es un máximo
local de la función.
Dada una función escalar diferenciable f (~ x) : Rn → R y un punto inicial
x~0 = (x01 , . . . , x0n ), el algoritmo del descenso del gradiente mueve de forma itera-
tiva dicho punto inicial tomando pasos cuya longitud viene determinada por el
ratio de aprendizaje α en la dirección del gradiente negativo − 5 f (x0 ). Dicha

Introducción a las redes neuronales articiales 19


dirección es la que debe tomar x0 para hacer descender lo más rápido posible el
valor de f. Así denimos el siguiente punto del algoritmo como:



xt = −
x−→ −−→
t−1 − α 5 f (xt−1 )

Detendremos el algoritmo cuando, dados , 0 > 0 jados previamente tengamos


que:

|| 5 f (−
x−→
t−1 )|| <  en cuyo caso diremos que el algoritmo converge en un
punto crítico.

||−
x−→ → −
t−1 − xt || < 
0
en cuyo caso diremos que el algoritmo converge en


xt .

f (→

xt ) > f (−
x−→
t−1 ) el algoritmo converge.

Se alcance el número máximo de iteraciones en cuyo caso variaremos el


parámetro α de forma adecuada.

El ratio de aprendizaje debe jarse antes de iniciar el algoritmo, su valor debe


escogerse con cuidado, pues si es muy pequeño el algoritmo tardará mucho en
converger y si es muy grande no alcanzará nunca un punto crítico.
A continuación, vemos un ejemplo del uso de este algoritmo sobre la función
θ12 θ22
f (θ1 , θ2 ) = sin( 2 − 4 + 3)cos(2θ1 + 1 − eθ1 ):

(a) Valor adecuado (b) Valor inferior (c) Valor superior

Figura 2.7: Situaciones en función del valor α

La elección del parámetro α es crucial, si el ratio de aprendizaje es muy


pequeño el algoritmo tardará mucho en converger hacia un mínimo de la función,
como vemos en la imagen central, donde se reeja en rojo las posiciones que
adquiere en cada iteración el punto y en verde el punto que se devuelve como
mínimo hallado. Si el ratio de aprendizaje es demasiado grande, como en la
tercera imagen, el algoritmo no converge en ningún punto crítico. Para un valor
adecuado del parámetro de aprendizaje el algoritmo moverá el punto hacia el
mínimo de la función como ocurre en la imagen de la izquierda. Podemos ver
el código que permite visualizar el entrenamiento del descenso del gradiente en
3.3.7(Python) o en 3.3.7(Matlab). Así como una descripción mas detallada del
algoritmo del descenso del gradiente en [5], [16].

Introducción a las redes neuronales articiales 20


2.4. Redes Hopeld
Esta red neuronal fue propuesta por John Hopeld en 1982. Surge un poco
antes del modelo Backpropagation, con una arquitectura de red algo distinta a
las propuestas hasta entonces. Hasta ese momento las redes que se habían plan-
teado, el Perceptrón y la red ADALINE, eran redes neuronales articiales que
propagaban la información de las primeras capas a las últimas (feedforward) in-
dependientemente en cada patrón de entrenamiento, sin embargo, la estructura
de red propuesta por Hopeld no sigue este principio.
En la red Hopeld, cada neurona en-
vía su salida como nueva entrada de datos
a todas las neuronas de la red salvo a sí
misma. Este proceso recibe el nombre de
recursividad. Además es una red autoaso-
ciativa, durante la etapa de entrenamien-
to varios patrones se almacenan en la red,
luego asocia las nuevas entradas con esta
información almacenada. Esto hace que se
suela usar en aprendizaje no supervisado,
donde se presentan los datos directamen-
te a la red sin tener información sobre la
salida esperada.
El desarrollo teórico de las redes de
Hopeld puede verse con mayor extensión
en [7], [13].

2.4.1. Estructura de la red


La red Hopeld es una red monocapa formada por N neuronas
2 , cada neu-
rona se conecta con todas las demás salvo consigo misma. Sea wij el peso de
la conexión entre la neurona i y la j. Estos pesos suponemos que son simétricos
wij = wji ∀i, j y wij = 0 ∀i, j con i = j.
El primer modelo presentado por Hopeld tenía una función de activación
discreta con salidas binarias entre -1/1 o 0/1 haciendo uso de la función escalo-
nada 1.3.1. 
 1 si x > θi
f (x) = x si x = θi
−1 si x < θi

La función de activación no modicará el valor recibido si x = θi .


θi es el umbral de la neurona denido anteriormente, en este caso nos per-
mitirá movernos en el eje de las abscisas. Se suele tomar como valor de θi :
N
X
θi = K wji ∀i
j=1

2 Número de elementos que componen la información a procesar

Introducción a las redes neuronales articiales 21


1
Para k = 0, f (x) toma los valores −1/1, 2 toma 0/1.
mientras que si k=
Los datos se deben presentar como vectores de N componentes. Estas com-
ponentes tomarán valores binarios entre 0 y 1 o -1 y 1. Cada combinación recibe
el nombre de estado de la red.
Recordemos que la red de Hopeld es autoasociativa. Primero se almacena-

− −→
ran en la red unos valores o estados { e1 , . . . , eM }. A continucación se le presen-
tará una nueva entrada ~
e = (e1 , . . . , eN ) y la red devolverá el valor almacenado
que más se parezca a dicha nueva entrada. El proceso matemático que sigue
para encontrar dicho valor es el siguiente:

1. Se dene Si (t = 0) = ei 1≤i≤N y con ei el elemento i-ésimo de la


nueva entrada.

2. Se repite el siguiente proceso hasta que se estabilice, es decir, hasta que


Si (t + 1) = Si (t) ∀i:
XN
Si (t + 1) = f ( wji Sj (t) − θi )
j=1

Con f la función de activación denida anteriormente.

Una vez se estabilice, tendremos unos valores (S1 , S2 , . . . , SN ) que corresponde-


rán al valor almacenado que más se parece a la nueva entrada. Se debe tener en
cuenta si todas las neuronas actualizan su salida a la vez o en distintos tiempos.
Supondremos que se actualizan de la primera forma.

2.4.2. Aprendizaje
La red Hopeld tiene una primera etapa de aprendizaje antes de introducir
los datos a procesar. En esta primera etapa se denen los pesos de las conexiones
entre las neuronas i y j mediante el producto de las componentes i-ésima y
j-ésima del patrón a almacenar. Suponemos que tenemos M patrones todos
presentados en forma de vector N-dimensional, la red de Hopeld discreta asigna
los pesos de las conexiones de la siguiente forma:
 PM
k k
 k=1 ei ej si 1 ≤ i, j ≤ N ; i 6= j
wij =
0 si 1 ≤ i, j ≤ N ; i = j

O bien si tomamos valores de la función de activación entre 0/1:


 PM
k k
 k=1 (2ei − 1)(2ej − 1) si 1 ≤ i, j ≤ N ; i 6= j
wij =
0 si 1 ≤ i, j ≤ N ; i = j

Denimos la matriz de pesos:


 
w11 w12 ... w1N
 w21 w22 ... w2N 
W=
 ... ... ...

... 
wN 1 wN 2 ... wN N

Introducción a las redes neuronales articiales 22


Con wij = wji ∀i, j y wij = 0 si i = j, por tanto será una matriz simétrica con
una diagonal formada por ceros. Alternativamente podemos denir esta matriz
mediante la ecuación:
M
W=
X
[EkT Ek − IN ]
k=1
k k k
Donde Ek = (e1 , e2 , . . . , eN ) es el patrón k de entrenamiento, EkT es su tras-
puesta e IN es la matriz identidad de orden N.

2.4.3. Función de Energía


Introducimos en este apartado la función de energía, muy usada para el
desarrollo teórico de estas redes y cuya fórmula es:

N N N
1 XX X
E=− wij Si Sj + θi Si
2 i=1 j=1 i=1

Considerando el espacio de dimensión N donde cada punto representa un estado


de la red podemos asignar a cada uno de estos puntos el valor de la función de
energía. Una vez se han almacenado los M estados en la primera fase, queremos
que estos representen los mínimos de la función de energía E. Al presentar una
nueva entrada esta evolucionará hasta alcanzar uno de estos mínimos.
Así, nuestro objetivo en la red de Hopeld autoasociativa es que los pa-
trones a memorizar se sitúen en los mínimos de la función de energía. Esto lo
P
conseguiremos asignando los pesos wii = 0 ∀i y wij = Sj Si (Ver [7]).

2.4.4. Problema del viajante con redes Hopeld


Las redes Hopeld permiten el tratamiento de problemas más complejos
que las redes Perceptrón y ADALINE. Una de las aplicaciones de las redes de
Hopeld es su uso en la resolución de problemas de optimización. En el siguiente
ejemplo resolveremos el problema del viajante, introduciendo de forma breve el
desarrollo teórico de la función de energía para este problema.
El problema del viajante se anuncia como sigue: Dadas N ciudades, nuestro
objetivo es visitarlas todas una vez, partiendo de una de ellas cualquiera, y
recorriendo la menor distancia posible. Este problema se puede abordar haciendo
uso de una red Hopeld con N xN neuronas donde cada neurona representa la
posibilidad de llegar a la ciudad N en un instante. Se suelen representar mediante
una matriz cuadrada de orden N donde las las indican la ciudad y las columnas
el orden en que se visitan. Así, tenemos:

 1 si se llega a la ciudad i en el instante j
Sij =
0 en otro caso

Introducción a las redes neuronales articiales 23


Buscamos una expresión de la función objetivo a minimizar del problema que
queremos resolver. Debemos incluir como términos en dicha función las res-
tricciones pues más adelante enlazaremos nuestro problema con la función de
energía de la red de Hopeld.
La función objetivo se divide en 4 sumatorios, el primero de ellos penaliza
si se toma más de una vez cualquier ciudad. El segundo lo hace cuando se toma
más de una ciudad al mismo momento, añadiendo así la restricción de pasar por
una sola ciudad en cada momento. El tercer sumatorio asegura que se tomen N
puntos en total y el cuarto representa la distancia que deseamos minimizar.

N N N N N N N N
A XXX B XXX C XX
F = Sij Sil + Sij Skj + ( Sij − N )2 +
2 i=1 j=1 2 i=1 j=1 2 i=1 j=1
l=1 k=1
l6=j k6=i
N N N
D XXX
dij (Sij Skj+1 + Sij Skj−1 )
2 i=1 j=1
k=1
k6=i

Los valores A, B, C, D son pesos usados para determinar la importancia de cada


sumatorio y dij representa la distancia entre la ciudad i y la ciudad j. Se debe
relacionar esta función de coste con la función de energía de la red de Hopeld
para este problema:

N N N N N X N
1 XXXX X
E=− wij kl Sij Skl − θij Sij
2 i=1 j=1 i=1 j=1
k=1 l=1

Para que sean equivalentes los pesos de las conexiones de 2 neuronas situadas
en ij y en kl deben ser:

wij kl = −Aδik (1 − δjl ) − Bδjl (1 − δik ) − C − Dδik (δjl+1 + δjl−1 )

Donde δi k denota la delta de Kronecker, es decir:



 1 si i=k
δik =
0 en otro caso

El desarrollo en detalle de la red de Hopeld para el problema del viajante


podemos encontrarlo en [8]

2.4.5. Ejemplo:Problema del viajante


Para el siguiente ejemplo tomamos un total de 10 ciudades cuyas posiciones
son:

A:(0.25,0.16)

B:(0.85,0.35)

Introducción a las redes neuronales articiales 24


C:(0.65,0.24)

D:(0.70,0.50)

E:(0.15,0.22)

F:(0.25,0.78)

G:(0.40,0.45)

H:(0.90,0.65)

I:(0.55,0.90)

J:(0.60,0.25)

Por tanto nuestra red tendrá N xN = 100 neuronas y 9900 conexiones(Recordemos


que en la red Hopeld cada neurona se conectaba con todas las demás salvo
consigo misma). Haciendo uso del código que se muestra en 3.3.7 obtenemos la
siguiente matriz W con el momento en el que se visita cada ciudad.

 
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
 
0 0 0 0 0 1 0 0 0 0
 
0 0 1 0 0 0 0 0 0 0
 
0 0 0 0 0 0 0 1 0 0
 
1 0 0 0 0 0 0 0 0 0
 
0 0 0 0 0 0 1 0 0 0
 
0 0 0 0 1 0 0 0 0 0
 
0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1

Por tanto el orden en el que se recorren todas las ciudades una vez y a mínima
distancia es: F-I-D-B-H-C-G-E-A-J

Introducción a las redes neuronales articiales 25


2.5. Perceptrón multicapa
En una red neuronal articial una capa es una agrupación de neuronas que
reciben las mismas entradas provenientes de otras neuronas o directamente de
los datos, estas capas se representan en los diagramas de redes neuronales en
forma de columna y de forma secuencial con otras capas según la dirección de los
datos. El perceptrón multicapa es un modelo de red neuronal articial basado
en una estructura que posee al menos 3 capas. La capa que recibe los datos
recibe el nombre de capa de entrada, la que da los resultados de la red capa de
salida y la capa o capas intermedias entre ambas se llaman capas ocultas pues
no tienen contacto directo ni con los datos ni con los resultados , permaneciendo
invisibles desde fuera de la red neuronal
3.

Figura 2.8: Estructura de un perceptrón multicapa

Denotamos por


x = (x1 , . . . , xn ) ∈ Rn las entradas de la red neuronal arti-
cial por la capa


de entrada y por y = (y1 , . . . , yn ) ∈ R
m
las salidas de la red
por la capa de salida. El perceptrón multicapa está completamente conectado,
es decir, existen conexiones entre todas las neuronas de una capa y todas las
neuronas de la siguiente capa. Dichas conexiones tienen unos pesos que denota-
l
remos por wij siendo el peso que une la neurona i de la capa l −1 con la neurona
j de la capa l.
Rosenblatt, el creador del perceptrón, ya intuía que el problema señalado
por Misky y Papert sobre su modelo podía corregirse añadiendo más capas
en serie. Pero esto presentaba un nuevo inconveniente. Hasta ese momento se

3 Esquema elaborado mediante Draw.io

Introducción a las redes neuronales articiales 26


Figura 2.9: Nomenclatura

sabía como entrenar los pesos de la capa de salida, pero no se tenía ningún
método computacionalmente asequible que permitiese entrenar los pesos de las
capas ocultas. Dicho método llegó en los setenta cuando Paul Werbs propone el
algoritmo Backpropagation en su tesis doctoral. Este algoritmo permite entrenar
al perceptrón multicapa y abre su aplicación a una gran variedad de problemas
de alta complejidad.

2.6. Algoritmo Backpropagation


2.6.1. Introducción
Las redes neuronales monocapa no pueden resolver problemas que requieran
una separación no lineal. Tras la publicación de Perceptrons [12] en 1969 por
Marvin Lee Minsky y Seymour Papert este hecho provocó una ralentización en
el desarrollo de las redes neuronales articiales que terminó gracias a la creación
del algoritmo backpropagation. Este algoritmo establece un método mediante
el cual las redes neuronales multicapa
4 pueden entrenarse. Se basa en propagar
el error desde las últimas capas hacia las primeras mediante el error imputado
de una capa. El aprendizaje de las redes neuronales multicapa haciendo uso
del backpropagation se hace con conjuntos de datos supervisados y con redes

4 Con aprendizaje forward y función de activación f continua

Introducción a las redes neuronales articiales 27


neuronales totalmente conectadas. Podemos encontrar un desarrollo más extenso
del método Backpropagation en [17], [14] y un desarrollo con ejemplos en [18].

2.6.2. Algoritmo
Tomamos el patrón de entrenamiento p-ésimo con p ∈ 1, · · · , P , formado
por el par (x~p , d~p ), donde x~p = (x1p , x2p , · · · , xnp ) ∈ Rn es la entrada p-ésima
de datos a la red y d~p = (d1p , d2p , · · · , dmp ) ∈ Rm es la salida deseada para
esa entrada de datos. Tenemos entonces una red con n entradas y m salidas, es
decir, tenemos m neuronas en la capa de salida, suponemos esta red neuronal
l
está completamente conectada. Sea yip la componente i-ésima en la salida de la

capa l para el patrón de entrenamiento p, deniendo y~p0 = x~p las entradas del
patrón de entrenamiento p. Al estar la red completamente conectada esta salida
se pasará como dato de entrada a todas las neuronas de la siguiente capa l+1
salvo en el caso que l=L que obtendremos la salida de la red, calculamos el
error cometido en dicho patrón mediante el error cuadrático en lo que denimos
como la función de costes para p:
m
1X L 2
Ep = (dip − yip ) (2.4)
2 i=1

Es común repetir el proceso de entrenamiento con los P patrones varias


veces en lo que se conocen como épocas, para cuanticar el error cometido en
las distintas épocas se utiliza el error cuadrático medio de los P patrones de
entrenamiento:

P
1 X
E= Ep
P p=1

Nuestro objetivo es minimizar la función de coste Ep (2.4) en cada patrón de


entrenamiento. Esto se consigue variando los pesos de las conexiones de las
neuronas haciendo uso del algoritmo del descenso del gradiente. Para ello nece-
sitamos calcular las derivadas de la función de costes (2.4) respecto a los pesos
l
de las conexiones, los cuales denimos de la siguiente forma, wij representa el
peso de la conexión que va de la i-ésima neurona en la capa l − 1 a la j-ésima
neurona en la capa l. La salida de la capa L-ésima, es decir , la última capa
viene denida por la ecuación:

L
yip = f (N etaL−1 L L−1
ip ) = f (w1i y1p
L L−1
+ · · · + wni ynp + θL ) i = 1, . . . , m (2.5)

L−1
Donde f es la función de activación (lineal o sigmoidal) y N etaip es la suma
ponderada de las entradas a la neurona por los pesos de las conexiones. Por
tanto la función de costes es la composición de las siguientes funciones:

Ep (f (N etaL−1 L L L L
ip (w1i , w2i , . . . , wni , θ )))

Introducción a las redes neuronales articiales 28


∂Ep
Luego si queremos calcular L las derivadas de la función de coste respecto a
∂wji
los pesos de la última neurona debemos de usar la regla de la cadena:

L−1
∂Ep ∂Ep ∂f ∂N etaip
L
= L−1 L
(2.6)
∂wji ∂f ∂N etaip ∂wji

Desarrollando cada una de las derivadas tenemos:

∂Ep ∂Ep 1 L L
= L
= − 2(dip − yip ) = −(dip − yip ) (2.7)
∂f ∂yip 2

∂f
= f0 (2.8)
∂N etaL−1
ip

∂N etaL−1
ip
L L−1
∂w1i L L−1
y1p + · · · + wji L L−1
yjp + · · · + wni ynp + θL L−1
L
= L
= yjp (2.9)
∂wji ∂wji
Así, tenemos que la derivada de la función de costes (2.6) es el producto de (2.7)
por la derivada de la función de activación (2.8) y por la salida j-ésima de la
capa anterior (2.9), correspondiente a la neurona j-ésima de la capa anterior.
Respecto a la derivada de la función de activación (2.8) esta debe ser deri-
vable, por ello tomaremos siempre una función de activación lineal o sigmoidal,
si la función de activación es lineal tenemos entonces que f 0 (N etaL−1
ip ) = 1 y si
L−1
−N eta
0 L−1 e ip
es sigmoidal f (N etaip ) = L−1 .
−N eta
(1+e ip )2
En la ecuación (2.9) obtenemos los valores de la salida de la capa anterior
para la derivada de los pesos de las conexiones y obtenemos el peso de la entrada
del sesgo, es decir uno, derivando por el bias θL . Por lo tanto la ecuación (2.6)
queda:
∂Ep
L
L
= −(dip − yip )f 0 yjp
L−1
∂wji
∂Ep L
= −(dip − yip )f 0
∂θL
Denimos el error imputado a la neurona i-esima de la capa L como:

∂Ep ∂f
δiL = −(dip − yip
L
)f 0 = L−1
∂f ∂N etaip

Así las ecuaciones anteriores nos quedan:

∂Ep L−1
L
= δiL yjp
∂wji

∂Ep
= δiL
∂θL
Si ahora encontramos una ecuación que relacione las derivadas parciales
respecto a los pesos de las conexiones de una capa en función de las derivadas

Introducción a las redes neuronales articiales 29


de los pesos de la capa siguiente podríamos calcular todas las derivadas parciales
de todas las conexiones de la red propagando el error hacia las neuronas de las
∂Ep
capas anteriores. Queremos calcular entonces L−1 , para ello tenemos en cuenta
∂wkj
que Ep es la composición de las siguientes funciones:

Ep (f L (N etaL−1
ip (f
L−1 L−2
(N etajp L−1
(w1j L−1
, w2j , . . . , wnL−1
0 j )))))

Donde fL f L−1 la función de


denota la función de activación de la capa L y
∂Ep
activación de la capa L-1, luego para calcular L−1 aplicamos de nuevo la regla
∂wkj
de la cadena:

L−1 L−2
∂Ep ∂Ep ∂f L ∂N etaip ∂f L−1 ∂N etajp
L−1
= L−1
(2.10)
∂wkj L
∂f ∂N etaip ∂f L−1 ∂N etaL−2
jp
L−1
∂wkj

∂Ep ∂f L
No obstante , como
∂f L ∂N etaL−1
= δiL la ecuación (2.10) nos queda:
ip

L−1 L−2
∂Ep ∂N etaip ∂f L−1 ∂N etajp
L−1
= δiL
∂wkj ∂f L−1 ∂N etaL−2
jp
L−1
∂wkj

∂f L−1
Tenemos que L−2
∂N etajp
= (f L−1 )0 es la derivada de la función de activación de la

capa L-1, esta será lineal o sigmoidal, derivadas que ya vimos anteriormente.Por
otro lado:

L−1 L−2 L−1 L−2


∂N etaL−2
jp ∂w1j y1p + · · · + wkj ykp + · · · + wnL−1 L−2
0 j yn0 p + θ
L−1
L−2
L−1
= L−1
= ykp
∂wkj ∂wkj

L−1 L−2 L−1 L−2


∂N etaL−2
jp ∂w1j y1p + · · · + wkj ykp + · · · + wnL−1 L−2
0 j yn0 p + θ
L−1
= =1
∂θL−1 ∂θL−1
Por último:

∂N etaL−1
ip ∂N etaL−1
ip
L L−1
∂w1i L L−1
y1p + · · · + wji L L−1
yjp + · · · + wni ynp + θL L
L−1
= L−1
= L−1
= wji
∂f ∂yjp ∂yjp

Que es el peso de la conexión entre la neurona j de la capa L-1 y la neurona i


de la capa L, reescribiendo (2.10):

∂Ep
L−1
= δiL wji
L
(f L−1 )0 ykp
L−2
∂wkj

∂Ep
= δiL wji
L
(f L−1 )0
∂θL−1
Denotamos entonces el error imputado a neurona j-ésima de la capa L-1 como:

δjL−1 = δiL wji


L
(f L−1 )0

Introducción a las redes neuronales articiales 30


En resumen, el error imputado a la neurona i de la última capa viene dado por:

∂Ep ∂f
δiL = L−1
(2.11)
∂f ∂N etaip

Las derivadas parciales de la función de costes respecto a los pesos de las cone-
xiones y el parámetro de sesgo en la capa l-1 son:

∂Ep
l−1
= δjl−1 ykp
l−2
(2.12)
∂wkj

∂Ep
= δjl−1 (2.13)
∂θl−1
Siendo δjl−1 el error imputado a la capa l-1, calculada respecto al error de las
capas posteriores y el peso de la conexión correspondiente:

δjl−1 = δil wji


l
(f l−1 )0 (2.14)

Con las ecuaciones 2.11, 2.12,2.13 y 2.14 podemos calcular las derivadas
parciales de la función de costes en cualquier neurona localizada en cualquier
capa. Por 2.11 sabemos calcular el error imputado en la última capa, para ver el
error imputado en alguna capa anterior simplemente aplicamos la fórmula 2.14
hasta llegar a dicha capa. Por último, las derivadas de la función de costes las
calculamos usando 2.12 y 2.13 según queramos calcular la derivada en función
de un peso o un sesgo respectivamente.

Introducción a las redes neuronales articiales 31


3. Aplicaciones de redes multicapa

En este apartado desarrollaremos las principales aplicaciones que tienen las


redes neuronales multicapa, introduciendo en primer lugar desarrollos prácticos
del perceptrón multicapa en tareas de reconocimiento de clases y aproximación
de funciones. Posteriormente, describiremos algunos modelos más avanzados de
redes neuronales multicapa especícos tales como las redes neuronales convolu-
cionales, muy usadas actualmente para el tratamiento de imágenes. Estas redes
neuronales añaden algunas funciones a las denidas en el perceptrón multicapa
aunque sus principios estructurales se basan en los vistos anteriormente.

3.1. Perceptrón Multicapa:Clasicación de Patro-


nes
La primera de las aplicaciones más comunes del perceptrón multicapa que
veremos se trata de la clasicación de elementos en una serie de clases nume-
rables. Supongamos que tenemos unas entradas x~1 , . . . , x~n ∈ Rn a las cuales se
les asigna una variable de salida y. Cuyos posibles valores denotan las distin-
tas clases a considerar. En la mayoría de los casos, esta variable respuesta es
binaria, reejando la presencia o ausencia de un factor. Para una salida binaria
se necesitará únicamente una neurona en la capa de salida, en general, con m
neuronas se puede realizar una clasicación en 2m clases distintas.
Como vimos anteriormente tanto el Perceptrón como la red
ADALINE no podían resolver problemas de clasicación que re-
quiriesen una separación no lineal entre sus clases. Un ejemplo
sería la separación de las salidas producidas por una puerta XOR,
esta devolverá el valor 0 cuando ambas entradas sean iguales y el
valor 1 cuando sean distintas.
Podemos resolver este problema haciedo uso de una red multi-
capa, añadiendo una capa intermedia en el perceptrón multicapa la red es capaz
de realizar una división de forma correcta. En el siguiente ejemplo, introducimos
los siguientes datos en formato Excel en la red neuronal cuya estructura mos-
tramos en la imagen, con pesos entre las conexiones y bias aleatorios (Código
del ejemplo en 3.3.7).

32
Entrada A Entrada B Salida
0 0 0
1 0 1
0 1 1
1 1 0

(a) Entradas a la red

(b) Estructura de la red

Figura 3.1: Ejemplo puerta XOR

Vemos en la siguiente gráca como la red va reduciendo el error


1 a medida
que aumentan las épocas.

Figura 3.2: Error durante el entrenamiento

1 Reejamos el error total E en dicha gráca

Introducción a las redes neuronales articiales 33


Tras el entrenamiento, vemos como la red obtiene salidas satisfactorias al
pasar los distintos casos de la puerta XOR:

Caso Salida
0 0 0
1 0 1
0 1 1
1 1 0

Cuadro 3.1: Resultados obtenidos

El perceptrón multicapa puede resolver cualquier problema de clasicación


binaria siempre que una de las clases se encuentre en una región convexa y
cerrada [18]. El número de neuronas y capas dependerá de la complejidad de
dicha región.

3.2. Perceptrón multicapa: Curvas de Funciones


Otra aplicación del perceptrón multicapa son los problemas de aproximación
de funciones. Supongamos que tenemos un conjunto de entradas y salidas de una
función desconocida cuyo comportamiento queremos predecir. Haciendo uso del
perceptrón multicapa podemos aproximar el comportamiento de dicha función.
Si g es la función de activación de las neuronas del perceptrón multicapa, su-
ponemos que g es continua
2 entonces haciendo uso de una sola capa oculta
podemos aproximar cualquier función f real y continua [18]. En concreto:

n
X
f (x1 , . . . , xn ) = λi gi1 (N eta1i )
i=1

Donde gi1 son las funciones de activación de las neuronas de la capa intermedia,
λi son constantes que determinarán el peso de cada función de activación y
N eta1i son las entradas ponderadas por los pesos tal y como se denieron en
1.2.2.
n
X
N eta1i = 1
wji xj − w0i
j=1

Usaremos la identidad como función de activación en la última capa que posee


una única neurona y determinaremos los pesos de las funciones como los pesos
de las conexiones entre las neuronas de la capa intermedia y la neurona de la
2
capa de salida, es decir, λi = w1i .
En el siguiente ejemplo (3.3.7), utilizaremos el perceptrón multicapa para
aproximar la función f (x) = sin(x). Para ello, tomaremos todos los enteros
en el intervalo [0, 200] como datos de entrenamiento y los enteros del intervalo

2 Generalmente se usará la función sigmoide o la función tangente hiperbólica

Introducción a las redes neuronales articiales 34


[201, 300] como datos de test. En la siguiente gráca podemos ver el proceso de
entrenamiento de la red que realiza Matlab
3.

Como vemos, el error se reduce a medida que el entrenamiento avanza, esto


ajustará los pesos λi . Por último las siguiente grácas muestran el desempeño
de nuestra red en los 100 puntos del conjunto de test y el error cometido en los
mismos.

(a) Aproximación frente a valor (b) Error cometido en cada punto


real de la función del intervalo

Como vemos el RMSE tiene un comportamiento sinusoidal y un valor re-


lativamente bajo lo que indica que el resultado fue bastante preciso en este
ejemplo.

3 Mediante la función train del paquete NeuralToolbox

Introducción a las redes neuronales articiales 35


3.3. Redes neuronales convolucionales
3.3.1. Introducción
Es un tipo de red neuronal articial con aprendizaje supervisado, surgió en
1998 de la mano de Yann Lecun y su principal utilidad radica en la capacidad
de Analizar imágenes que otorga a las redes neuronales. Los datos de entrada
de este tipo de redes suelen ser imágenes en forma de matrices, donde cada
valor representa un píxel. Estas entradas estarán formadas por una sola matriz,
es decir, tendrán un solo canal si se trata de una imagen en escala de grises
o 3 canales para el formato RGB, donde cada píxel estará representado por 3
valores que corresponden al nivel de saturación de cada uno de los colores rojo,
azul y verde.
Usar imágenes como datos de entrada presenta una complicación añadida
a lo visto hasta el momento. Al procesar las matrices correspondientes a los
píxeles de las imágenes se debe tener en cuenta no solo la información que
obtenemos del propio píxel , sino el entorno que rodea al mismo. Por ejemplo,
una línea de píxeles de color negro rodeados de píxeles de color blanco en una
imagen en escala de grises podría indicar un margen de una gura. Nuestra red
neuronal articial debe ser capaz de analizar esto y para ello, se hace uso de
una nueva operación matemática llamada convolución, que deniremos en la
siguiente sección.
Otro problema es el coste computacional que supone el tratar con imágenes.
Para solventar esto, las redes neuronales convolucionales utilizan una operación
denominada Pooling. Su utilidad radica en la generalización de características
para la reducción del costo. Introduciremos esta operación en segundo lugar.
Podemos consultar de forma más extensa información teórica sobre las redes
convolucionales en [3] o [11]. Así mismo, la guía de matlab[1] presenta una serie
de ejemplos de uso de su paquete DeepLearningToolbox.

3.3.2. Convolución
Decimos que una red neuronal articial es convolucional si al menos en una
de sus capas aplica una operación denominada convolución.
En el caso continuo, dadas las funciones I y K denimos la convolución
como: Z +∞
I ∗ K(t) = I(a)K(t − a)da (3.1)
−∞
En el caso discreto la operación de convolución se dene como sigue:

+∞
X
I ∗ K(t) = I(a)K(t − a) (3.2)
a=−∞

En las redes neuronales convolucionales usaremos la expresión 3.2, siendo I los


datos de entrada, generalmente píxeles de una imagen representados en matri-
ces. K el ltro o núcleo de la convolución, que se aplicará a lo largo de toda

Introducción a las redes neuronales articiales 36


la entrada. Al resultado lo llamaremos mapa de características de la entrada
para dicho ltro y lo denotaremos por S. Una convolución puede tomar como
entrada tanto a una imagen como a un conjunto de m mapas de carecterísticas
producidos por alguna convolución anterior.
Denotaremos por N al número de canales o mapas de características de
la entrada, N=1 en escala de grises, y N=3 en formato RGB si estamos con
los datos de entrada de la red. Cada una de las longitudes de la entrada se
denotará por ij j = 1, 2 , respectivamente kj j = 1, 2 serán las longitudes del
ltro, donde kj ≤ ij j = 1, 2.
Así, expresamos matemáticamente la convolución (para N = 1) de los datos
de entrada I haciendo uso del ltro K como:

k1 X
X k2
S(i, j) = I(i − m + 1, j − n + 1)K(i, j)
m=1 n=1

O de forma equivalente [11]:

k1 X
X k2
S(i, j) = I(i + m − 1, j + n − 1)K(m, n)
m=1 n=1

Si N >1 el proceso es idéntico salvo en la denición del ltro, este deberá


tomar siempre todos los canales al recorrer la imagen en cada salto, para ello,
deniremos N matrices para el ltro K. Sea I l (m, n) el valor de la entrada a la
convolución en la posición de altura m y anchura n del canal l-ésimo con l =
1, . . . , N , K l (m, n) el mismo elemento para el canal l-ésimo del ltro, tenemos:

k1 X
X k2 X
N
S(i, j) = I l (i + m − 1, j + n − 1)K l (m, n)
m=1 n=1 l=1

El número de canales de la salida de la convolución vendrá determinado por


el número de ltros distintos que apliquemos, es decir, los canales serán iguales a
la cantidad de mapas de características que denamos para una misma entrada
I pero con distintos núcleos K [3]. De esta forma, al ir avanzando una imagen
en la red neuronal convolucional iremos perdiendo altura y anchura en la misma
pero esta irá ganando mayor profundidad gracias al uso de múltiples ltros.
En el siguiente ejemplo aplicamos una convolución a una imagen en escala de
grises, N=1. Las dimesiones de la imagen son i1 = 6 que denota la altura de la
imagen e i2 = 6 que denota la anchura. El nucleo que usamos tiene dimensiones
k1 = 3 de altura y k2 = 3 de anchura. En general, se suelen tomar imágenes
cuadradas en las entradas así como ltros cuadrados en las convoluciones
4.

4 Imagen del ejemplo creada en draw.io

Introducción a las redes neuronales articiales 37


Como vemos, la convolución se aplica a lo ancho y alto de la imagen, despla-
zando el ltro hasta que nos quedamos sin píxeles en la imagen de entrada. En
el ejemplo anterior el desplazamiento del ltro tenía un ancho de 1 píxel tanto
en la altura como en la anchura, no obstante se pueden denir convoluciones
con saltos superiores, para ello denotamos como sj con j = 1, 2 los saltos que
realiza el ltro en cada dimensión.
La salida de una convolución pro-
ducirá una reducción en todas las di-
mensiones de la entrada. Así mismo,
al tener denida de esta forma la con-
volución, se pierde la información de
los píxeles situados en los bordes. Pa-
ra solventar este problema, se suelen
añadir las de ceros en todas las di-
mensiones de la entrada en lo que se
conoce como zero-padding. El ltro
podrá recorrer posiciones extra y al Ejemplo zero-padding
tener estos nuevos elementos el valor
0 no aportarán ninguna información extra al resultado. Denotaremos por pj con
j = 1, 2 el zero-padding que se añade respectivamente en la altura y anchura de
la entrada .
5
El uso de los núcleos K es vital en las redes neuronales convolucionales,
en cada convolución se hacen uso de varios núcleos distintos para la misma
entrada. Esto permite obtener diversas caracterísitcas de la entrada como las

5 Si tenemos N>1 se añaden las de ceros en todos los canales.

Introducción a las redes neuronales articiales 38


lineas verticales que aparecen en la misma, las lineas horizontales, los contornos
o incluso la información de una sección de la entrada solo. El número de ltros
que se usan en una convolución denirá el número de canales en la salida, es
decir, si en una convolución de una imagen en escala de grises se usan 3 ltros
distintos, la salida de la misma tendrá dimensiones i1 × i2 × 3.
A continuación vemos un ejemplo de como un ltro permite obtener diversas
características de una imagen, en la siguiente imagen
6 aplicamos dos ltros
distintos usados para detectar tanto lineas horizontales como verticales.

Figura 3.4: Imagen original en escala de grises

La imagen se encuentra en escala de grises, por tanto el ltro que aplicamos


tendrá que ser considerado para un único canal. En caso de tener varios canales
en la imagen habría que denir varias matrices para el ltro y aplicar cada una
a un canal sumando los resultados para obtener un único valor de salida para
cada posición del ltro. En este ejemplo vamos a usar los ltros llamados ltro
Sobel [23] que permite encontrar bordes verticales y horizontales.

 
−1 −2 −1
0 0 0
1 2 1

Filtro Sobel para detectar bordes horizontales

 
−1 0 1
−2 0 2
−1 2 1

Filtro Sobel para detectar bordes verticales

6 Sacada de Unsplash, página que provee imágenes de uso libre.

Introducción a las redes neuronales articiales 39


Aplicamos ambos ltros a la matriz producida por los píxeles de la imagen
anterior en escala de grises, desplazando un píxel a la derecha el ltro hasta
llegar al borde derecho de la imagen para desplazarlo 1 píxel hacia abajo y
repetir hasta llegar al nal de la misma. Obtenemos entonces las siguientes
salidas.

(a) Vertical (b) Horizontal

Figura 3.5: Filtro Sobel 3.3.7

Como comentamos anteriormente, los saltos de píxeles producen una reduc-


ción en la salida de la convolución. Si suponemos que tenemos una convolución
cuya entrada tiene dimensión i, si añadimos P las de ceros en ambas direc-
ciones y tomamamos los ltros saltando S píxeles. La salida de la convolución
tendrá dimensiones o, donde:

 
i + 2p − k
o= +1
s
Donde los corchetes denotan a la operación oor, que asigna a la entrada el
mayor entero menor que el valor introducido.
Por ejemplo, si tomamos una
imagen cuyas dimensiones son 8×
8, a la que además añadimos una
zero-padding de tamaño 1 y apli-
camos en la misma un ltro de ta-
maño 3×3 que salta 2 píxeles en
cada desplazamiento nuestras di-
mensiones en la salida serían 4×4.
Una convolución viene segui-
da de una función de activación,
generalmente se suele usar la fun-
ción RELU. Estas actúan de una
forma similar a como lo hacían con las redes neuronales multicapa. Se aplica
sobre valores de todos los canales justo después de haberse realizado una con-
volución. Así, al aplicar una función de activación RELU no se cambian las
dimensiones de salida. Se pueden usar otras funciones de activación aunque se
debe tener cuidado si las mismas tienen un coste computacional elevado.
Basándose de nuevo en principios biológicos, muchas redes neuronales con-
volucionales usan en su estructura una normalización en las diferentes salidas
de los ltros de la convolución que les permite comparar entre diversos ltros

Introducción a las redes neuronales articiales 40


en las capas posteriores. Esta normalización puede aplicarse a todos los ltros
mediante la fórmula:

ai
bi = i = 1, . . . , N
(k + α i a2i )β
P

Donde i denota el ltro, ai la salida original del mismo en una posición (x, y), bi
la salida normalizada y k, α, β son hiperparámetros que variarán según la red. En
los último años han surgido normalizaciones que dividen los ltros en lotes, no
obstante, en las redes neuronales convolucionales que usaremos no intervienen
este tipo de normalizaciones.

3.3.3. Pooling
La última de las operaciones de
las redes neuronales convolucionales
es el pooling. Esta operación va to-
mando regiones de tamaño Pq × Pq
en todos los canales de forma inde-
pendiente y recorriendo toda la entra-
da de forma similar a como lo hacían
los ltros en las convoluciones. Solo
que en lugar de calcular el produc-
Figura 3.6: Max-pooling con desplaza-
to interno, esta operación devolverá el
miento de 2
máximo de todos los píxeles en dicha
región(max-pooling) o la media de los
mismos(Average-pooling). Aquí toman mayor protagonismo los desplazamien-
tos entre aplicaciones del ltro anteriormente denidos pues ayudan a reducir
redundancias. Estos cambios se aplican a cada canal de forma independiente,
por tanto, los pooling no modican la profundidad de la entrada.
La estructura que suelen tomar las redes neuronales convolucionales es ir
iterando convoluciones y funciones de activación RELU. Intercalando cada cierto
número de combinaciones una capa de pooling para reducir así el coste y eliminar
redundancias.
Las redes neuronales convolucionales utilizan un aprendizaje jerarquizado
en su estructura. Las primeras capas de convolución se encargan de detectar
pequeños elementos como líneas, círculos o cruces. Mientras que las capas con-
volcionales posteriores se encargan de combinar esta información para procesar
estructuras más complejas como puede ser una rueda, una cara o un perro.
Al nal de la red se ponen una serie de capas con neuronas completamente
conectadas entre sí de la misma forma que se vio en el perceptrón multicapa.
El número de capas completamente conectadas dependerá del problema que
queramos resolver y se usarán para obtener una salida que se pueda interpretar
en la red. La última de estas capas suele ser una capa softmax para problemas
con respuestas categóricas y cuyo número de neuronas viene determinado por
el número de categorías. Para conectar estas capas con las capas nales de las
convoluciones se enlazan todas las salidas de la última convolución con todas

Introducción a las redes neuronales articiales 41


las neuronas de la primera de las capas totalmente conectadas. Debido a esto,
la última parte de las redes convolucionales suele tener una gran cantidad de
parámetros a entrenar, pero estos se pueden entrenar mediante el método de
Backpropagation visto en 2.6.
Para entrenar los parámetros de los ltros de las convoluciones se usará de
igual forma el algoritmo Backpropagation pero teniendo en cuenta una serie de
particularidades que veremos seguidamente.

3.3.4. Entrenamiento
Para el entrenamiento de las redes neuronales convolucionales se usará el
algoritmo Backpropagation explicado anteriormente. Esto plantea una serie de
cuestiones, se sabe como aplicar este algoritmo en el perceptrón multicapa, no
obstante, en las redes convolucionales entran en juego nuevas operaciones como
es el pooling y la convolución.
Al aplicar el algoritmo Backpropagation en el pooling debemos tener en
cuenta como propagar el error hacia atrás en esta operación, es decir, cuales
fueron las neuronas de la capa i que generaron esa salida en la capa i+1 al
introducir los datos. En el caso del max-pooling
7 , si no tenemos solapamiento
se establece la propagación del error en 0 para aquellos elementos en la región
del ltro de la capa i que no coincidan con el valor máximo asignado en la capa
i + 1, propagando así el error en aquellos que sean iguales al máximo solo.
Solo queda establecer la forma en la que determinar el error producido en las
convoluciones. Para ello denimos la convolución de forma matricial, suponga-
mos que tenemos una convolución con desplazamiento de 1 y sin zero-padding.
Cuya entrada tiene dimensiones Lq × Bq y un solo canal, el ltro tiene dimen-
siones Fq × Fq . Suponemos también que tenemos solo un canal en la salida, en
caso de considerar más, simplemente repetimos el proceso siguiente para todos
los ltros. La salida tendrá dimensiones (Lq − Fq + 1) × (Bq − Fq + 1) × 1. En
primer lugar tenemos que transformar la matriz de entrada
8 en un vector de
longitud A0 = Lq × Bq al que llamaremos f, para ello proyectamos cada la en
orden descendente. Aplicar un ltro en una posición determinada corresponderá
T
a multiplicar f por la izquierda por un vector de dimensión A0 con ceros en
todas sus posiciones salvo en las que se esté aplicando el ltro. Si tomamos todas
las posibles posiciones del ltro tendremos A1 = (Lq − Fq + 1) × (Bq − Fq + 1)
vectores con los que formaremos la matriz de la convolución a la que llamaremos
C que tendrá dimensiones A1 × A0 . El resultado será un vector de A1 elementos
que corresponderán a la salida de la convolución para ese ltro.

7 La mayoría de las estructuras predenidas usan max-pooling en lugar de average-pooling


8 Este proceso se aplica para cada ltro en caso de tener varios

Introducción a las redes neuronales articiales 42


 
1 2 3
Por ejemplo, si tenemos la matriz 4 5 6 como entrada, esta se trans-
7 8 9
formará en el vector f = (1, 2, 3, 4, 5, 6, 7, 8, 9), si queremos ahora aplicarle el
 
a b
ltro a todas las posiciones posibles en las condiciones denidas antes
c d  
a b 0 c d 0 0 0 0
 0 a b 0 c d 0 0 0
debemos de usar la matriz C = 
0 0 0 a b 0 c d 0. Para aplicar

0 0 0 0 a b 0 c d
la convolución multiplicamos:

 
1
2
 
  3  
a b 0 c d 0 0 0 0 4
 a + 2b + 4c + 5d
0 a b 0 c d 0 0 0
T
 5 = 2a + 3b + 5c + 6d
   
C ∗f =
0 0 0 a b 0 c d 0  
    4a + 5b + 7c + 8d
6
0 0 0 0 a b 0 c d  
 5a + 6b + 8c + 9d
7
8
9

Para entrenar los parámetros de los ltros mediante Backpropagation debe-


mos tomar como entrada el vector de dimensiones A1 siguiendo con la notación
anterior, a este vector lo llamaremos g . Para propagar el error hacia atrás debe-
mos tener en cuenta en cuantos lugares intervino la celda cuando se ejecutó de
forma normal, esto se obtiene multiplicando a g por CT por la izquierda
9 . En
el caso de tener una profundidad en la salida mayor a 1, realizamos el proceso
anterior en cada capa y sumamos:

d
X
CkT g Tk
k=1

Donde CkT es la matriz asociada al ltro k-ésimo de la convolución y gk es la


salida que produjo.

9 Puede encontrarse un desarrollo más extenso de como usar Backpropagation en convolu-


cion en [3]

Introducción a las redes neuronales articiales 43


3.3.5. Redes pre-entrenadas
Aunque es posible elaborar y entrenar una red neuronal convolucional, el en-
trenamiento de las mismas suele ser bastante lento y costoso debido a la cantidad
de parámetros que existen. Cuantas más capas tenga la red neuronal articial
más costará entrenarla [15], [25]. No obstante, existe una serie de arquitecturas
para redes neuronales convolucionales creadas y que han sido entrenadas en el
reconocimiento de una gran variedad de objetos a través de imágenes. Estas
redes surgen como propuestas de solución a los problemas de la competición
ILSVRC
10 que se organiza anualmente. Esta competición provee de amplios
datasets de imágenes que deben ser clasicados según una serie de clases. Los
métodos que mejores soluciones han obtenido en dicha competencia en los últi-
mos años han sido precisamente las redes neuronales convolucionales.
A continuación se presenta una de las redes neuronales convolucionales pre-
entrenadas. Esta red adquirió el mejor porcentaje de acierto en la competencia
de 2012 del ILSVRC. Dicha estructura recibió el nombre de Alexnet [10] y
aunque en los últimos años se han presentado otras estructuras con mejores
resultados, el impacto que tuvo Alexnet en el desarrollo de las redes neuronales
convolucionales fue bastante notable y su estructura relativamente sencilla la
hace perfecta para presentarla como una aproximación a este tipo de redes
pre-entrenadas. Para acceder a ella hacemos uso del paquete DeepToolbox de
Matlab que permite entre otras cosas importar redes pre-entrenadas.

3.3.6. Alexnet
Esta red recibe imágenes en formato RGB , es decir, que su entrada tendrá
3 canales, está diseñada para imágenes de dimensiones 227 × 227 × 3. Como
vemos en la imagen, se compone de 8 capas en total, 5 convoluciones con sus
respectivas capas de activación RELU así como algún max-pooling y alguna
normalización en algunas de ellas. La primera convolución aplica 96 ltros de
tamaño 11×11×3 y con un stride11 de 4, luego se aplica una función de activación
RELU y una normalización
12 . Seguido a esto se realiza un max-pooling de
tamaño 3×3 y stride de 2, por tanto este tendrá solapamiento. La segunda
convolución aplica 256 ltros de tamaño 5 × 5 × 96 viene seguida también de
una función de activación RELU y una normalización, así como un max-pooling
de tamaño 3×3 y stride 2. La tercera y cuarta capa convolucional vienen solo
seguidas por una función de activación RELU y aplican 384 ltros de tamaño
3 × 3 × 256 y 384 de tamaño 3 × 3 × 384 respectivamente. La quinta y última de
las convoluciones utiliza 256 ltros de tamaño 3×3×384 y viene seguida por una
función de activación RELU y un último max-pooling de tamaño 3 × 3 y stride
2. A continuación vienen 3 capas totalmente conectadas, donde las 2 primeras
tienen 4096 neuronas en total y vienen seguidas por una función de activación
RELU. La última de las capas totalmente conectadas tiene 1000 neuronas que

10 ImageNet Large Scale Visual Recognition Challenge


11 Forma inglesa de referirse al número de píxeles que salta el ltro
12 Las normalizaciones en Alexnet tienen como hiperparámetros k = 1, β = 0,75, α = 0,0001

Introducción a las redes neuronales articiales 44


corresponden a las 1000 clases diferentes en las que es capaz de clasicar Alexnet,
viene seguida de una función de activación Softmax que otorgará la probabilidad
de pertenencia de cada clase.

Figura 3.7: Estrucura de Alexnet

3.3.7. Ejemplo:Alexnet
En el siguiente ejemplo haremos uso de la red pre-entrenada Alexnet para
clasicar las siguiente imágenes
13

En este ejemplo simplemente deberemos importar la red con los valores de los
pesos entrenados, escalar las imágenes para que tengan dimensiones 227×227×3
y pasarlas por la red para ver si las clasica correctamente así como el grado de
especicación que tiene Alexnet. Al usar pesos pre-entrenados de antemano el

13 Sacadas de Unsplash.

Introducción a las redes neuronales articiales 45


coste computacional del programa será considerablemente más bajo que el que
tendríamos si entrenáramos la red para este ejemplo.
Vemos los resultados de la clasicación por parte de la red neuronal convo-
lucional articial Alexnet:

La red no solo fue capaz de clasicar el perro y la or como tal, sino que
pudo identicar la raza de perro y el tipo de or que se mostraban en la imagen.
En concreto Alexnet es capaz de diferenciar con bastante exactitud un total de
1000 clases distintas.
Podemos encontrar el código para importar la red y realizar la clasicación
en 3.3.7 haciendo uso de la herramienta Deeptoolbox de Matlab, que permite
importar y manejar redes pre-entrenadas de una forma sencilla y con una interfaz
clara. Además Matlab cuenta con una guía de usuario para este paquete que es
actualizada anualmente [1]. Destacar, del mismo modo, algunos paquetes que
permiten elaborar modelos de redes neuronales articiales en Python[4] como
son Keras o Tensorow[26].
En el anexo [3.3.7], podemos encontrar un ejemplo haciendo uso de la red
diseñada por Google donde se puede apreciar como actuan las distintas capas
convolucionales a lo largo de la red.
Bibliografía

[1] Mark Hudson Beale, Martin T Hagan, and Howard B Demuth. Neural
network toolbox. User's Guide, MathWorks, 2:7781, 2010.
[2] Eduardo Francisco Caicedo Bravo and Jesús Alfonso López Sotelo. Una
aproximación práctica a las redes neuronales articiales. Programa Edito-
rial UNIVALLE, 2009.

[3] C Aggarwal Charu. Neural Networks and Deep Learning. 2018.

[4] Joshua Eckroth. Python articial intelligence projects for beginners: Get
up and running with articial intelligence using 8 smart and exciting AI
applications. Packt Publishing Ltd, 2018.
[5] Kris Hauser. b553 lecture 4: Gradient descent, 2012.

[6] Donald Olding Hebb. The organization of behavior; a neuropsycholocigal


theory. A Wiley Book in Clinical Psychology, 62:78, 1949.
[7] José Ramón Hilera González, Víctor José Martínez Hernando, et al. Redes
neuronales articiales: fundamentos, modelos y aplicaciones. 2000.

[8] John J Hopeld and David W Tank. neural computation of decisions in


optimization problems. Biological cybernetics, 52(3):141152, 1985.
[9] Been Kim, Martin Wattenberg, Justin Gilmer, Carrie Cai, James Wexler,
Fernanda Viegas, et al. Interpretability beyond feature attribution: Quan-
In International
titative testing with concept activation vectors (tcav).
conference on machine learning, pages 26682677. PMLR, 2018.
[10] Alex Krizhevsky, Ilya Sutskever, and Georey E Hinton. Imagenet clas-
sication with deep convolutional neural networks. Advances in neural
information processing systems, 25:10971105, 2012.
[11] G.P. Martinsanz, P.J.H. Caro, and E.B. Portas. Aprendizaje profundo. RC
Libros, 2021. ISBN 9788412106985.

[12] Minsky Marvin and A Papert Seymour. Perceptrons, 1969.

47
[13] Damián Jorge Matich. Redes neuronales: Conceptos básicos y aplicaciones.
Universidad Tecnológica Nacional, México, 41:1216, 2001.
[14] James L McClelland, David E Rumelhart, PDP Research Group, et al. Pa-
rallel Distributed Processing, Volume 2: Explorations in the Microstructure
of Cognition: Psychological and Biological Models, volume 2. MIT press,
1987.

[15] Umberto Michelucci. Advanced applied deep learning: convolutional neural


networks and object detection. Springer, 2019.
[16] Michael A Nielsen. Neural networks and deep learning, volume 25. Deter-
mination press San Francisco, CA, USA, 2015.

[17] Nikolay Nikolaev and Hitoshi Iba. Adaptive learning of polynomial net-
works: genetic programming, backpropagation and Bayesian methods. Sprin-
ger Science & Business Media, 2006.

[18] IVAN NUNES and HERNANE SPATTI DA SILVA. Articial neural net-
works: a practical course. Springer, 2018.

[19] Cathy Oñeil. Weapons of math destruction: How big data increases inequa-
lity and threatens democracy. Broadway Books, 2016.
[20] Kevin L Priddy and Paul E Keller. Articial neural networks: an introduc-
tion, volume 68. SPIE press, 2005.

[21] Frank Rosenblatt. The perceptron: a probabilistic model for information


storage and organization in the brain. Psychological review, 65(6):386, 1958.
[22] David E Rumelhart, Georey E Hinton, and Ronald J Williams. Lear-
ning representations by back-propagating errors. nature, 323(6088):533
536, 1986.

[23] I Sobel and G Feldman. An isotropic 3x3 image gradient operator. presen-
tation at stanford ai project, 1968.

[24] Pedro Isasi Viñuela and Inés M Galván León. Redes de neuronas articia-
les: un enfoque práctico. Pearson Prentice Hall, 2003.

[25] Steven Walczak and Narciso Cerpa. Heuristic principles for the design
of articial neural networks. Information and software technology, 41(2):
107117, 1999.

[26] Giancarlo Zaccone, Md Rezaul Karim, and Ahmed Menshawy. Deep lear-
ning with TensorFlow. Packt Publishing Ltd, 2017.
Referencias Web

1. https://www.youtube.com/watch?v=Uz7ucmqjZ08&ab_channel=DotCSV
2. https://www.youtube.com/watch?v=90QDe6DQXF4&ab_channel=DotCSV
3. https://www.youtube.com/watch?v=gicnvDwdDxY&list=WL&index=65&
t=344s&ab_channel=HackeandoTec
4. https://towardsdatascience.com/history-of-the-first-ai-winter-6f8c2186f80b

49
Anexo:GoogleNet

Introducción
La red GoogleNet fue desarrollada por el equipo de investigadores de Goo-
gle. Obtuvo el mejor resultado en la competición ILSVRC en el año 2014. Sus
aplicaciones abarcan desde la detección de objetos en sistemas de conducción
autónoma hasta reconocimiento facial a través de imágenes.
Esta estructura de red está compuesta por 20 capas entre las que se incluyen
capas Inception. Las capas Inception surgen bajo el objetivo de aumentar la
anchura en las capas de las redes convolucionales sin disparar el coste compu-
tacional de las mismas. Como vimos anteriormente, este coste es bastante ele-
vado sobre todo cuando empezamos a trabajar con estructuras de redes más
complejas.

Capas Inception
Las capas Inception, a diferencia de las capas convolucionales explicadas
hasta ahora, aplican varias convoluciones de forma paralela con ltros de distinto
tamaño. Suponemos que la entrada tiene dimensiones m × n × p, donde p es el
número de mapas de características o canales de la entrada y m, n la altura y
anchura. La capa Inception aplicará convoluciones de distinto tamaño de forma
paralela en esta entrada para luego juntar todas estas salidas concatenando el
total de ltros usados.
En concreto, las capas Inception usadas en
la red GoogleNet aplican 4 convoluciones de
forma paralela en al entrada. La primera de
ellas tiene como tamaño de ltro k = 1, las 2
siguientes aplican 2 convoluciones seguidas de
tamaño k = 3 y k = 5 respectivamente. La úl-
tima de las convoluciones paralelas(k = 1) se
aplica tras haber realizado un Max-Pooling de
tamaño k = 3. Todas las convoluciones tienen
en su salida una función de activación RELU.
Gracias a la computación paralela en una mis-
ma capa conseguimos una mayor anchura en Capa Inception usada en Goo-

la salida, lo cual se traduce en un aprendizaje gleNet

50
mejor para la red.
Existen versiones más avanzadas de capas Inception que utilizan ltros no
cuadrados y normalización, no obstante estas capas no son usadas en la red
GoogleNet por lo que no las trataremos. Puede encontrarse más información
sobre las capas Inception en [11].

Red GoogleNet
Pasamos ahora a analizar la estructura de la red GoogleNet, como comenta-
mos antes esta red está formada por 20 capas en total. De esas 20 capas, 9 son
capas Inception cuya estructura comentamos en el apartado anterior. Esta red
obtuvo el mejor resultado en la competición ILSVRC en el año 2014 con una
tasa de error del 6 %, muy cercana al nivel humano.
La red recibe imágenes de tama-
ño 224 × 224 en RGB, luego el nú-
mero de canales iniciales será p = 3.
Aplica una primera convolución
14 con
k=7 y 64 ltros en total seguida de
un Max-Pooling cuyo tamaño de ltro
es k = 3. Luego aplica una normaliza-
ción como la vista en la red Alexnet.
A continuación aplica otras 2 convolu-
ciones ambas con k = 3 pero con 64 y
192 ltros cada una. Una última nor-
malización y un Max-Pooling(k = 3)
se hace antes de pasar a ejecutar las 9
capas Inception de forma secuencial.
Entre la segunda y tercera capa In-
ception se realiza un Max-Pooling con
k = 3, así como entre la séptima y
la octava. Tras ejecutar todas las ca-
pas Inception se realiza un Average-
Pooling(k = 3). Ya en último lugar te-
nemos una capa totalmente conecta-
da con 1000 neuronas y con una fun-
ción de activación Softmax que nos
devolverá la probabilidad de perte-
nencia de la imagen en las 1000 clases
en las que es capaz de clasicar la red
GoogleNet.
Recordemos que después de cada
convolución se aplica una función de
activación, en concreto la función de Estructura red GoogleNet

activación RELU.

14 Seguida de una función de activación RELU


Ejemplo: Red GoogleNet
En el siguiente ejemplo (Código en [3.3.7]) usaremos la red GoogleNet para
clasicar la siguiente imagen:

Chow(96 %)

Esta imagen ya fue clasicada haciendo uso de la red Alexnet en un ejemplo


anterior. En este ejemplo visualizaremos la salida obtenida por las convoluciones
a lo largo de la red GoogleNet, de esta forma podremos ver como trabajan
las redes neuronales convolucionales a lo largo del proceso de clasicación de
imágenes.
Mostrar todos los ltros de todas las convoluciones llevaría un alto coste
computacional así como generaría una cantidad enorme de imágenes. Por tanto,
mostraremos algunos ltros de cada convolución así como el ltro que mayor
valor ha dado en la salida. Las imágenes resultantes se pasan a imágenes en blan-
co y negro donde el color blanco indica una fuerte activación en la convolución
mientras que el color negro indica una baja activación.
A continuación vemos 64 ltros de la primera de las convoluciones que se
aplican en esta red. Estas primeras convoluciones suelen emplearse para detectar
elementos básicos como son los bordes, las líneas o los contrastes en el la imagen.

Filtros primera convolucion

Si mostramos el ltro que obtuvo una mayor activación vemos que este está
centrado en la detección de bordes en la imagen. A este nivel en la red convolu-
cional todavía no se ha distorsionado la imagen.

Resultado con mayor activación

Veamos ahora los resultados de 64 ltros de una convolución situada en


la parte media de la red. La imagen ya comienza a ser distorsionada por la
aplicación consecutiva de ltros.

Filtros convolución

Filtro con mayor activación

Si miramos el ltro que obtuvo una mayor activación en la convolución vemos


como este se centra en la detección de ojos en la gura.
Los ltros de las últimas convoluciones buscan guras más complejas median-
te la combinación de los mapas de características obtenidos hasta el momento.
El resultado al observas su desempeño son imágenes bastante distorsionadas con
zonas grandes donde se activan estas convoluciones.

Filtros convolución

Filtro con mayor activación

El ltro con mayor activación en esta convolución nal muestra el enfoque


que realiza la red en la parte del morro y los ojos del perro para identicarlo así
como una ligera atención en la parte del pelaje.
Anexo:Códigos

Código en Python descenso de gradiente

import numpy as np
import scipy as sc
import matplotlib . pyplot as plt

#Funcion anonima en python


func = lambda th : np . s i n ( 1 / 2 * th [ 0 ] ** 2
= 1/4 * th [ 1 ] ** 2 + 3 ) * np . c o s ( 2 * th [ 0 ]
+ 1 = np . e ** th [ 1 ] )

r e s = 100
_X = np . l i n s p a c e ( = 2 , 2, res )
_Y = np . l i n s p a c e ( = 2 , 2, res )

#Evaluaremos en e s o s 100 x100 puntos


_Z = np . z e r o s ( ( r e s , res ))

for ix , x in enumerate (_X ) :


for iy , y in enumerate (_Y ) :
_Z [ i y , ix ] = func ( [ x , y])

#Graficamos
p l t . c o n t o u r f (_X, _Y, _Z, 100)
plt . colorbar ()

#Generamos un punto a l e a t o r i o
Theta = np . random . r a n d ( 2 ) * 4 = 2

####EMPEZAMOS A APLICAR EL DESCENSO DEL GRADIENTE######

_T = np . c o p y ( Theta )

55
h = 0.001 #Paso de l a d e r i v a d a

lr = 0.001 #Ratio de a p r e n d i z a j e

p l t . p l o t ( Theta [ 0 ] , Theta [ 1 ] , "o" , c=" w h i t e " )

g r a d = np . z e r o s ( 2 )

#Calculamos l a s d e r i v a d a s p a r c i a l e s
for _ in range ( 1 0 0 0 0 ) :
for i t , t h in enumerate ( Theta ) :
_T = np . c o p y ( Theta )

_T[ i t ] = _T[ i t ] + h

d e r i v = ( f u n c (_T) = f u n c ( Theta ) ) / h

grad [ i t ] = deriv

Theta = Theta = lr * grad

i f (_ %100 == 0 ) :
p l t . p l o t ( Theta [ 0 ] , Theta [ 1 ] , ".", c=" r e d " )

p l t . p l o t ( Theta [ 0 ] , Theta [ 1 ] , "o" , c=" g r e e n " )


p l t . show ( )

Código en Matlab descenso de gradiente

res = 100;
X = linspace ( = 3 , 7 , r e s ) ;
Y = linspace ( = 3 , 3 , r e s ) ;
Z = zeros ( r e s , r e s ) ;
for i = 1 : length (X)
item_x = X( i ) ;
for j = 1: length (Y)
item_y = Y( j ) ;
Z ( j , i ) = f u n ( item_x , item_y ) ;
end
end
%Theta = rand ( 1 , 2 ) * 4 = 1
Theta = [0 ,0];
hold on
c o n t o u r f (X, Y, Z , 5 0 )
colorbar
h = 0.001; %Pasos en l a d e r i v a d a
lr = %h i p er p a r am e tr o d e l a p r e n d i z a j e
0.5;
g r a d = zeros ( 2 ) ; %Vector g r a d i e n t e
%Aplicamos d e s c e n s o d e l g r a d i e n t e
for i =1:10000
for j =1: length ( Theta )
T = Theta ;
T( j ) = T( j ) + h ;
d e r i v =( f u n (T ( 1 ) , T( 2 ) ) = f u n ( Theta ( 1 ) , Theta ( 2 ) ) ) / h;
grad ( j ) = d e r i v ;
end
Theta = Theta = lr * grad ;
plot ( Theta ( 1 ) , Theta ( 2 ) , ' r * ' )
end
plot ( Theta ( 1 ) , Theta ( 2 ) , ' g * ' )
function z = fun ( x , y )

z = sin ( 1 / 2 * x^2 = 1/4 * y^2 +3) * cos ( 2 * x + 1 = exp ( y ) ) ;


end

Código en Python problema del viajero

import numpy a s np
from random import randint
from random import uniform

class H o p f i e l d :
def __init__ ( s e l f , cities , d, alpha ) :
self . cities = cities
s e l f . neurons = cities ** 2
self .d = d
s e l f . alpha = alpha

s e l f . w = np . z e r o s ( [ s e l f . n e u r o n s , s e l f . neurons ] )

def f ( self , x):


return 0 . 5 * ( 1 . 0 + np . t a n h ( s e l f . a l p h a * x ) )

def train ( self , u, A, B, C, D, sigma ) :


n = self . cities

for iteration in range ( ( n * * 2 ) ) :


x = randint (0 , n = 1)
i = randint (0 , n = 1)
tmpA = 0
for j in range ( n ) :
if i != j :
tmpA += u [ x ] [ j ]
tmpA *= =A
tmpB = 0
for y in range ( n ) :
if x != y:
tmpB += u [ y ] [ i ]
tmpB *= =B
tmpC = 0
for y in range ( n ) :
for j in range ( n ) :
tmpC += u [ y ] [ j ]
tmpC == ( n+s i g m a )
tmpC *= =C
tmpD = 0
for y in range ( n ) :
if 0 < i < n = 1:
tmpD += s e l f . d [ x ] [ y ] * ( u [ y ] [ i +1] +
u[y ][ i =1])
elif i > 0:
tmpD += self .d[x ] [ y]*(u[y ] [ i =1])
elif i < n = 1:
tmpD += s e l f . d [ x ] [ y ] * ( u [ y ] [ i +1])
tmpD *= =D
u[x ][ i ] = s e l f . f ( tmpA + tmpB + tmpC + tmpD )
return u

def predict ( self , A, B, C, D, sigma , max_iterations ) :


u = np . z e r o s ( [ s e l f . c i t i e s , self . cities ])
for i in range ( s e l f . c i t i e s ) :
for j in range ( s e l f . c i t i e s ) :
u[ i ][ j ] = uniform ( 0 , 0.03)

prev_error = s e l f . calc_error (u , A, B, C, D, sigma )


repeated = 0
max_repeat = 10
for iteration in range ( m a x _ i t e r a t i o n s ) :
u = s e l f . train (u , A, B, C, D, sigma )
error = s e l f . calc_error (u , A, B, C, D, sigma )
if e r r o r == p r e v _ e r r o r :
r e p e a t e d += 1
else :
repeated = 0

if r e p e a t e d > max_repeat :
break
prev_error = e r r o r
return u

def calc_error ( self , u, A, B, C, D, sigma ) :


tmpA = 0
n = self . cities
for x in range ( n ) :
for i in range ( n ) :
for j in range ( n ) :
i f i != j :
tmpA += u [ x ] [ i ] * u [ x ] [ j ]
tmpA *= (A/ 2 . 0 )

tmpB = 0
for i in range ( n ) :
for x in range ( n ) :
for y in range ( n ) :
i f x != y :
tmpB += u [ x ] [ i ] * u[y ][ i ]
tmpB *= (B / 2 . 0 )

tmpC = 0
for x in range ( n ) :
for i in range ( n ) :
tmpC += u [ x ] [ i ]
tmpC == ( ( n+s i g m a ) * * 2 )
tmpC *= (C / 2 . 0 )

tmpD = 0
for x in range ( n ) :
for y in range ( n ) :
for i in range ( n ) :
if 0 < i < n = 1:
tmpD += self .d[x ][ y]
*u [ x ] [ i ] * ( u [ y ] [ i +1]+u [ y ] [ i =1])
elif i > 0:
tmpD += self .d[x ][ y]
*u [ x ] [ i ]*(u[y ] [ i =1])
elif i < n = 1:
tmpD += self .d[x ][ y]
*u [ x ] [ i ] * ( u [ y ] [ i +1])
tmpD *= (D/ 2 . 0 )
return tmpA+tmpB+tmpC+tmpD

def calc_d ( c i t i e s ) :
n = c i t i e s . shape [ 0 ]
d = np . z e r o s ( [ n , n])
for i in range ( n ) :
for j in range ( n ) :
d[ i ][ j ] = np . s q r t (
np . s q u a r e ( c i t i e s [ i ] [ 0 ] =
cities [ j ][0]) +
np . s q u a r e ( c i t i e s [ i ] [ 1 ]
= cities [ j ][1]))
return d

city [0] = (0.25 , 0.16)


city [1] = (0.85 , 0.35)
city [2] = (0.65 , 0.24)
city [3] = (0.70 , 0.50)
city [4] = (0.15 , 0.22)
city [5] = (0.25 , 0.78)
city [6] = (0.40 , 0.45)
city [7] = (0.90 , 0.65)
city [8] = (0.55 , 0.90)
city [9] = (0.60 , 0.25)

d = calc_d ( c i t y )

hp = H o p f i e l d ( n , d, 50.0)
v = hp . p r e d i c t (A= 1 0 0 . 0 , B= 1 0 0 . 0 , C= 9 0 . 0 , D= 1 0 0 . 0 ,
s i g m a =1 , m a x _ i t e r a t i o n s =1000)
print ( v )

Código en Python decodicación con red ADALINE

import numpy as np
import matplotlib . pyplot as plt

class ADALINE ( ) :

# Constructor
def __init__ ( s e l f , d, xi , n_muestras , wi , fac_ap ,
epochs , precision , w_ajustado ) :
self .d = d
s e l f . xi = xi
s e l f . n_muestras = n_muestras
s e l f . wi = wi
s e l f . fac_ap = fac_ap
s e l f . epochs = epochs
self . precision = precision
s e l f . w_ajustado = w_ajustado
self .y = 0 # S a l i d a de l a red

def Entrenamiento ( s e l f ) :
E = 1 # Error de s a l i d a
E_ac = 0 # Error t o t a l
E r r o r _ p r e v = 0 # Error a n t e r i o r
Ew = 0 # Error c u a d r a t i c o medio
E_red = [ ] # Error de l a red
E _ t o t a l = 0 # Error t o t a l

while np . abs (E) > self . precision :


E r r o r _ p r e v = Ew
for i in range ( s e l f . n _ m u e s t r a s ) :
#C a l c u l o s a l i d a de l a red
self .y = sum ( s e l f . x i [ i , : ] * s e l f . wi )
# Calculo del error
E_ac = ( s e l f . d [ i ] = s e l f . y)
# Reajuste pesos
s e l f . wi += s e l f . f a c _ a p * E_ac * s e l f . x i [ i , :]
E _ t o t a l = E _ t o t a l + ( E_ac * * 2 )

print ( ' P e s o s= ' , s e l f . wi )

# C a l c u l o e r r o r c u a d r a t i c o medio
Ew = ( ( 1 / s e l f . n _ m u e s t r a s ) * E_total )
E = (Ew = #Error de l a red
Error_prev )
E_red . append ( np . abs (E ) ) # Almacenamos e r r o r e s
s e l f . e p o c h s += 1
print ( ' e r r o r= ' , E)
return s e l f . wi , s e l f . e p o c h s , E_red

def F_operacion ( s e l f ) :
salida = []
for j in range ( s e l f . n _ m u e s t r a s ) :
s e l f . y = sum ( s e l f . x i [ j , : ] * s e l f . w_ajustado )
s a l i d a . append ( s e l f . y )
return salida
# Ciclo principal
if __name__=="__main__" :
# Datos de entrada
x i = np . a r r a y ( [ [ 0 , 0 , 0 ] , [ 0 , 0, 1] , [0 , 1, 0] ,
[0 , 1, 1] , [1 , 0, 0] , [1 , 0, 1] , [1 , 1, 0] ,
[1 , 1, 1]])

# Salidas esperadas
d = np . a r r a y ( [ [ 0 ] , [ 1 ] , [2] , [3] , [4] , [5] , [6] , [7]])

# Longitud
n_muestras = len ( d )
# Establecemos l o s p e s o s
w i = np . a r r a y ( [ 3 . 1 2 , 2.0 , 1.86])

# Factor de a p r e n d i z a j e
fac_ap = 0 . 3

# Epocas
epochs = 0

# Precision
precision = 0.001

w_ajustado = []

# I n i c i a l i z a r l a red ADALINE
r e d = ADALINE( d , x i , n_muestras , wi , fac_ap , e p o c h s ,
p r e c i s i o n , w_ajustado )
w _a j us t ad o , epocas , e r r o r = red . Entrenamiento ( )
# Grafica
p l t . y l a b e l ( ' Error ' )
p l t . x l a b e l ( ' Epocas ' )
p l t . t i t l e ( 'ADALINE , Regla Delta ' )
x = np . a r a n g e ( e p o c a s )
plt . plot (x , error , 'm=> ' , l a b e l =" E r r o r cuadratico ")
p l t . l e g e n d ( l o c= ' u p p e r right ' )
p l t . show ( )
print ( " P e s o s ajustados " , w_ajustado )
Código en Matlab clasicación perceptrón

clear a l l
clc
TABLA_DATOS=[
0 0 1 1 0 2;
0 1 0 1 2 2;
0 0 0 1 0 1];

ENTRADA=[TABLA_DATOS ( 1 , : ) ; TABLA_DATOS ( 2 , : ) ] ;
SALIDA=[TABLA_DATOS ( 3 , : ) ] ;

hold on
p l o t p v (ENTRADA, SALIDA )
hold off
clf
MI_RED=newp ( minmax (ENTRADA) , 1 ) ;
view (MI_RED)
MI_RED . iw { 1 , 1 } = [ 1 1];
MI_RED . b { 1 } = = 0 . 7 5 ;

hold on
p l o t p v (ENTRADA, SALIDA )
p l o t p c (MI_RED . i w { 1 , 1 } ,MI_RED . b { 1 } )
hold off
clf
MI_RED=t r a i n (MI_RED,ENTRADA, SALIDA ) ;
p l o t p c (MI_RED . i w { 1 , 1 } ,MI_RED . b { 1 } )

xrojo =[];
yrojo =[];
xazul = [ ] ;
yazul = [ ] ;
for k=0:0.05:2
for j =0:0.05:2
x p u n t o=k ;
y p u n t o=j ;
v a l o r _ s a l i d a=s i m (MI_RED, [ x p u n t o ; y p u n t o ] ) ;
if v a l o r _ s a l i d a ==0
x r o j o =[ x r o j o , x p u n t o ] ;
y r o j o =[ y r o j o , y p u n t o ] ;
end
i f v a l o r _ s a l i d a ==1
x a z u l =[ x a z u l , x p u n t o ] ;
y a z u l =[ y a z u l , y p u n t o ] ;
end
end
hold on
plot ( x r o j o , y r o j o , ' r . ' )
plot ( x a z u l , y a z u l , ' g . ' )
p l o t p v (ENTRADA, SALIDA )
p l o t p c (MI_RED . i w { 1 , 1 } ,MI_RED . b { 1 } )
hold off
end

Código en Python aplicación ltros Sobel

import matplotlib . pyplot as plt


import m a t p l o t l i b . image as mpimg
import cv2
import numpy as np

i m a g e = mpimg . i m r e a d ( ' f o t o . j p g ' )


p l t . imshow ( i m a g e )
p l t . show ( )

g r a y = c v 2 . c v t C o l o r ( image , c v 2 .COLOR_RGB2GRAY)
p l t . imshow ( g r a y , cmap= ' g r a y ' )
p l t . show ( )

# horizontal
s o b e l _ y = np . a r r a y ( [ [ =1 , =2 , = 1 ] ,
[ 0, 0, 0] ,
[ 1, 2, 1]])
# vertical
s o b e l _ x = np . a r r a y ( [ [ =1 , 0, 1] ,
[ =2 , 0, 2] ,
[ =1 , 0, 1]])

f i l t e r e d _ i m a g e 1 = cv2 . f i l t e r 2 D ( gray , =1 , sobel_x )


f i l t e r e d _ i m a g e 2 = cv2 . f i l t e r 2 D ( gray , =1 , sobel_y )
f , ax = p l t . s u b p l o t s ( 1 , 2, f i g s i z e =(15 , 4))
ax [ 0 ] . s e t _ t i t l e ( ' D e t e c c i o n borde horizontal ' )
ax [ 0 ] . imshow ( f i l t e r e d _ i m a g e 1 , cmap= ' g r a y ' )
ax [ 1 ] . s e t _ t i t l e ( ' D e t e c c i o n borde vertical ')
ax [ 1 ] . imshow ( f i l t e r e d _ i m a g e 2 , cmap= ' g r a y ' )
p l t . show ( )

Código Imágenes Alexnet

net = a le xn et ;

Img1 = i m r e a d ( ' r u t a ' )


imshow ( Img1 )
Img_r1 = i m r e s i z e ( Img1 , [ 2 2 7 , 2 2 7 ] )
label1 = c l a s s i f y ( n e t , Img_r1 ) ;
imshow ( Img_r1 )
title ( string ( label1 ))
Img2 = i m r e a d ( ' r u t a ' )
imshow ( Img2 )
Img_r2 = i m r e s i z e ( Img2 , [ 2 2 7 , 2 2 7 ] )
label2 = c l a s s i f y ( n e t , Img_r2 ) ;
imshow ( Img_r2 )
title ( string ( label2 ))
Img3 = i m r e a d ( ' r u t a ' )
imshow ( Img3 )
Img_r3 = i m r e s i z e ( Img3 , [ 2 2 7 , 2 2 7 ] )
label3 = c l a s s i f y ( n e t , Img_r3 ) ;
imshow ( Img_r3 )
title ( string ( label3 ))

Código Ejercicio Perceptrón Multicapa:Clasicación

import numpy a s np
import p a n d a s a s pd
from numpy import random
import m a t p l o t l i b . p y p l o t as plt

class MLP ( ) :
# Constructor
def __init__ ( s e l f , xi , d, w_1 , w_2 , us , uoc , precision
, epocas , fac_ap , n_ocultas , n_entradas , n_salida ) :
s e l f . x i = np . t r a n s p o s e ( x i )
self .d = d
s e l f . w1 = w_1
s e l f . w2 = w_2
s e l f . us = us
s e l f . uoc = uoc
self . precision = precision
s e l f . epocas = epocas
s e l f . fac_ap = fac_ap
s e l f . n_entradas = n_entradas
s e l f . n_ocultas = n_ocultas
s e l f . n_salida = n_salida
# V a r a i b l e s de a p r e n d i z a j e
s e l f . d i = 0 # S a l i d a deseada en l a
iteracion actual
s e l f . error_red = 1 # Error t o t a l
de la red en un conjunto de entrenamiento
s e l f . Ew = 0 # Error c u a d r a t i c o medio
self . E r r o r _ p r e v = 0 # Error a n t e r i o r
s e l f . Errores = []
s e l f . E r r o r _ a c t u a l = np . z e r o s ( ( len ( d ) ) )
s e l f . E n t r a d a s = np . z e r o s ( ( 1 , n _ e n t r a d a s ) )
s e l f . un = np . z e r o s ( ( n _ o c u l t a s , 1 ) )
s e l f . gu = np . z e r o s ( ( n _ o c u l t a s , 1 ) )
s e l f .Y = 0 . 0
s e l f . y = 0.0
s e l f . epochs = 0
# V a r a i b l e s de r e t r o p r o p a g a c i o n
s e l f . error_real = 0
s e l f . ds = 0 . 0 # D e l t a de s a l i d a
s e l f . d o c u = np . z e r o s ( ( n _ o c u l t a s , 1))
def Operacion ( s e l f ) :
len ( s e l f . d ) ,
r e s p u e s t a = np . z e r o s ( ( 1))
for p in range ( len ( s e l f . d ) ) :
s e l f . Entradas = s e l f . xi [ : , p]
s e l f . Propagar ( )
respuesta [ p , :] = self .y
return respuesta . t o l i s t ()

def Aprendizaje ( s e l f ) :
Errores = [] # Almacenamos l o s e r r o r e s
while np . abs ( s e l f . e r r o r _ r e d ) > self . precision :
for i in range ( len ( d ) ) :
s e l f . Entradas = s e l f . xi [ : , i ]
s e l f . di = self .d[ i ]
s e l f . Propagar ( )
s e l f . Backpropagation ( )
s e l f . Propagar ( )
s e l f . Error_actual [ i ] = (0.5)
* (( s e l f . di = s e l f . y )**2)
# Error g l o b a l de l a red
s e l f . Error ( )
E r r o r e s . append ( s e l f . e r r o r _ r e d )
s e l f . e p o c h s += 1
# Si se a l c a n z a un numero mayor de epocas
if s e l f . epochs > s e l f . epocas :
break
# Regresar
return s e l f . epochs , s e l f . w1 , s e l f . w2 ,
s e l f . us , s e l f . uoc , Errores

def Propagar ( s e l f ) :
# Operaciones en l a primera capa
for a in range ( s e l f . n _ o c u l t a s ) :
s e l f . un [ a , :] = np . d o t ( s e l f . w1 [ a , :] ,
s e l f . Entradas ) + s e l f . uoc [ a , :]

# C a l c u l a r l a a c t i v a c i o n de l a s neuronas de
la capa oculta
for o in range ( s e l f . n _ o c u l t a s ) :
s e l f . gu [ o , :] = t a n h ( s e l f . un [ o , :])

# C a l c u l a r Y p o t e n c i a l de a c t i v a c i o n de
las neuronas de salida
s e l f . Y = ( np . d o t ( s e l f . w2 , s e l f . gu ) + s e l f . us )

# C a l c u l a r l a s a l i d a de l a neurona de s a l i d a
s e l f . y = t a n h ( s e l f . Y)

def Backpropagation ( s e l f ) :
# Calcular el error
s e l f . error_real = ( s e l f . di = s e l f . y)
# Calculamos ds ( d e l s t a de s a l i d a )
s e l f . d s = ( d t a n h ( s e l f . Y) * s e l f . error_real )
# Ajustamos p e s o s s i n a p t i c o s w2
s e l f . w2 = s e l f . w2 + ( np . t r a n s p o s e ( s e l f . gu )
* s e l f . fac_ap * s e l f . ds )
# Ajustamos umbral us
s e l f . us = s e l f . us + ( s e l f . fac_ap * s e l f . ds )
# C a l c u l a r docu
s e l f . d o c u = d t a n h ( s e l f . un ) * np . t r a n s p o s e ( s e l f . w2 )
* s e l f . ds
# A j u s t a r l o s p e s o s w1
for j in range ( s e l f . n _ o c u l t a s ) :
s e l f . w1 [ j , :] = s e l f . w1 [ j , :]
+ ( ( s e l f . docu [ j , :]) * s e l f . Entradas
* s e l f . fac_ap )

# A j u s t a r e l umbral en l a s neuronas o c u l t a s
for g in range ( s e l f . n _ o c u l t a s ) :
s e l f . uoc [ g , :] = s e l f . uoc [ g , :] +
( s e l f . fac_ap * s e l f . docu [ g , :])

def Error ( s e l f ) :
# Error c u a d r a t i c o medio
s e l f . Ew = ( ( 1 / len ( d ) ) * ( sum ( s e l f . E r r o r _ a c t u a l ) ) )
s e l f . e r r o r _ r e d = ( s e l f . Ew = s e l f . Error_prev )

# Funcion para l a tanh


def tanh ( x ) :
return np . t a n h ( x )

# Funcion para l a d e r i v a d a de l a tanh


def dtanh ( x ) :
return 1.0 = np . t a n h ( x ) * * 2

# Funcion Sigmoide
def sigmoide (x ) :
return 1/(1+ np . e x p (= x ) )

# Funcion para o b t e n e r l a d e r i v a d a de l a f u n c i o n
def dsigmoide ( x ) :
s = 1/(1+ np . e x p (= x ) )
return s * (1 = s )

def Datos_entrenamiento ( matriz , x1 , xn ) :


x i n = m a t r i z [ : , x1 : xn +1]
return xin

def Datos_validacion ( matriz , xji , xjn ) :


xjn = matriz [ : , x j i : x j n +1]
return xjn
# Programa p r i n c i p a l
if "__main__" == __name__ :
x l s = pd . E x c e l F i l e ( 'XOR. x l s x ' )
d a t o s = x l s . p a r s e ( ' Hoja1 ' )
m a t r i x _ d a t a = np . a r r a y ( d a t o s )
# Datos entrada
x_inicio = 0
x_n = 1
# Datos de v a l i d a c i o n
xj_inicio = 3
xj_n = 4
# Crear v e c t o r de entrada x i
x i = ( Datos_entrenamiento ( matrix_data
, x_inicio , x_n ) )
d = matrix_data [ : , x_n+1]
# Crear v e c t o r de v a l i d a c i o n
x j = ( D a t o s _ v a l i d a c i o n ( matrix_data ,
xj_inicio , xj_n ) )
# Parametros de l a red
f , c = x i . shape
fac_ap = 0 . 2
precision = 0.000001
e p o c a s = 10000
epochs = 0
# A r q u i t e c t u r a de l a red
n _ e n t r a d a s = c # Numero de e n t r a d a s
c a p _ o c u l t a s = 1 # 1 Capa o c u l t a
n _ o c u l t a s = 5 # Numero de neuronas
en la capa oculta
n_salida = 1 # Numero de neuronas
en la capa de salida
# Valor de umbral o b i a s
u s = 0 . 1 # Bias neurona s a l i d a
u o c = np . o n e s ( ( n _ o c u l t a s , 1) , float )
# Matriz de p e s o s s i n a p t i c o s
random . s e e d ( 0 )
w_1 = random . r a n d ( n _ o c u l t a s , n_entradas )
w_2 = random . r a n d ( n _ s a l i d a , n_ocultas )

# I n i c i a l i z a m o s l a red PMC
r e d = MLP( x i , d, w_1 , w_2 , us , uoc ,
precision , epocas , fac_ap , n_ocultas ,
n_entradas , n_salida )
epochs , w1_a , w2_a , us_a , uoc_a , E =
red . Aprendizaje ( )
# Graficar e l error
plt . grid ()
p l t . y l a b e l ( " Error de la red " )
p l t . x l a b e l ( " Epocas " )
p l t . t i t l e ( " Perceptron Multicapa " )
x = np . a r a n g e ( e p o c h s )
plt . plot (x , E, 'b ' , label = " Error Global " )
plt . legend ( loc = ' upper right ' )
p l t . show ( )

# Validacion
r e d = MLP( x j , d, w1_a , w2_a , us_a , uoc_a ,
precision , epocas , fac_ap , n_ocultas , n_entradas ,
n_salida )
salidas = red . Operacion ( )
print ( " S a l i d a s : " , salidas )

Código Ejercicio Perceptrón Multicapa:Funciones 2

clear a l l
x =0:200;
xx = 2 0 1 : 3 0 0 ;

%d a t o s o r i g i n a l e s
d a t a T r a i n= sin ( x / 1 0 ) ;
d a t a T e s t= sin ( xx / 1 0 ) ;
%media
mu = mean ( d a t a T r a i n ) ;
sig = std ( d a t a T r a i n ) ;
%d a t o s e s t a n d a r i z a d o s
dataTrainStandardized = ( dataTrain = mu) / sig ;
dataTestStandardized = ( dataTest = mu) / sig ;
XTest = d a t a T e s t S t a n d a r d i z e d ( 1 : end = 1 ) ;
%p r e p a r a r l o s d a t o s para l a p r e d i c c i o n
XTrain = d a t a T r a i n S t a n d a r d i z e d ( 1 : end = 1 ) ;
YTrain = d a t a T r a i n S t a n d a r d i z e d ( 2 : end ) ;
%d e f i n i m o s y ponemos a e n t r e n a r l a red
%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%PARAMETROS DE ENTRENAMIENTO
numFeatures = 1 ;
numResponses = 1 ;
numHiddenUnits = 2 0 0 ;
layers = [
s e q u e n c e I n p u t L a y e r ( numFeatures )
l s t m L a y e r ( numHiddenUnits )
f u l l y C o n n e c t e d L a y e r ( numResponses )
regressionLayer ] ;
o p t i o n s = t r a i n i n g O p t i o n s ( ' adam ' , ...
' MaxEpochs ' , 2 5 0 , ...
' GradientThreshold ' ,1 , ...
' InitialLearnRate ' ,0.005 , ...
' LearnRateSchedule ' , ' p i e c e w i s e ' , ...
' LearnRateDropPeriod ' , 1 2 5 , ...
' LearnRateDropFactor ' , 0 . 2 , ...
' Verbose ' , 0 , ...
' P l o t s ' , ' t r a i n i n g =p r o g r e s s ' ) ;

%entrenamiento de l a red
n e t = t r a i n N e t w o r k ( XTrain , YTrain , l a y e r s , o p t i o n s ) ;

analyzeNetwork ( net )

%p r e d i c c i o n e s
n e t = p r e d i c t A n d U p d a t e S t a t e ( n e t , XTrain ) ;
[ n e t , YPred ] = p r e d i c t A n d U p d a t e S t a t e ( n e t , YTrain ( end ) ) ;
numTimeStepsTest = numel ( XTest ) ;
for i = 2 : numTimeStepsTest
[ n e t , YPred ( : , i ) ] = predictAndUpdateState ( net ,
YPred ( : , i =1) , ' ExecutionEnvironment ' , ' cpu ' ) ;
end
%d e s e s t a n d a r i z a m o s
YPred = sig * YPred + mu ;

%e r r o r e s
YTest = d a t a T e s t ( 2 : end ) ;
rmse = sqrt ( mean ( ( YPred=YTest ) . ^ 2 ) )
figure
subplot ( 2 , 1 , 1 )
plot ( YTest )
hold on
plot ( YPred , ' . = ' )
hold o f f
legend ( [ " O b s e r v e d " " Forecast " ] )
ylabel ( " C a s e s " )
t i t l e (" Forecast ")
subplot ( 2 , 1 , 2 )
stem ( YPred = YTest )
xlabel ( " Month " )
ylabel ( " E r r o r " )
t i t l e ( "RMSE = " + r m s e )

Código en Matlab GoogleNet

%Cargamos l a red
net = googlenet ;

%Cargamos l a Imagen
im = i m r e a d ( 'D: \ C o s a s Juan \ A p u n t e s 4 \TFG\NEURALNETWORK\
Versiones \ Perro . jpg ' ) ;
imshow ( im )
%A l t u r a y Anchura de l a imagen
imgSize = size ( im ) ;
imgSize = imgSize ( 1 : 2 ) ;

%Analizamos a l red
analyzeNetwork ( net )

%Primera c o n v o l u c i o n
a c t 1 = a c t i v a t i o n s ( n e t , im , ' c o n v 1 =7x7_s2 ' ) ;

%Mostramos l o s r e s u l t a d o s de 64 f i l t r o s
sz = size ( a c t 1 ) ;
act1 = reshape ( a c t 1 , [ sz (1) sz (2) 1 sz ( 3 ) ] ) ;
I = i m t i l e ( mat2gray ( a c t 1 ) , ' G r i d S i z e ' , [ 8 8]);
imshow ( I )
%Vemos e l f i l t r o 17
act1ch17 = act1 ( : , : , : , 1 7 ) ;
a c t 1 c h 1 7 = mat2gray ( a c t 1 c h 1 7 ) ;
act1ch17 = i m r e s i z e ( act1ch17 , imgSize ) ;
I = i m t i l e ( { im , a c t 1 c h 1 7 } ) ;
imshow ( I )

%Encontramos e l f i l t r o cuya s a l i d a es mayor


[ maxValue , m a x V a l u e I n d e x ] = max(max(max( a c t 1 ) ) ) ;
act1chMax = a c t 1 ( : , : , : , m a x V a l u e I n d e x ) ;
act1chMax = m a t 2 g r a y ( act1chMax ) ;
act1chMax = i m r e s i z e ( act1chMax , i m g S i z e ) ;
I = i m t i l e ( { im , act1chMax } ) ;
imshow ( I )
%Vemos una c o n v o l u c i o n p o s t e r i o r
a c t 6 = a c t i v a t i o n s ( n e t , im , ' i n c e p t i o n _ 3 b =3x3 ' ) ;
sz = size ( a c t 6 ) ;
act6 = reshape ( a c t 6 , [ sz (1) sz (2) 1 sz ( 3 ) ] ) ;
I = i m t i l e ( i m r e s i z e ( mat2gray ( a c t 6 ) , [ 6 4 64]) ,
' GridSize ' ,[6 8]);
imshow ( I )
%Mostramos l a mas p o t e n t e
[ maxValue6 , m a x V a l u e I n d e x 6 ] = max(max(max( a c t 6 ) ) ) ;
act6chMax = a c t 6 ( : , : , : , m a x V a l u e I n d e x 6 ) ;
imshow ( i m r e s i z e ( m a t 2 g r a y ( act6chMax ) , i m g S i z e ) )
%Vemos una c o n v o l u c i o n p o s t e r i o r
a c t 7 = a c t i v a t i o n s ( n e t , im , ' i n c e p t i o n _ 5 b =1x1 ' ) ;
sz = size ( a c t 7 ) ;
act7 = reshape ( a c t 7 , [ sz (1) sz (2) 1 sz ( 3 ) ] ) ;
I = i m t i l e ( i m r e s i z e ( mat2gray ( a c t 7 ) , [ 6 4 64]) ,
' GridSize ' ,[6 8]);
imshow ( I )
%Mostramos l a mas p o t e n t e
[ maxValue6 , m a x V a l u e I n d e x 6 ] = max(max(max( a c t 7 ) ) ) ;
act6chMax = a c t 7 ( : , : , : , m a x V a l u e I n d e x 6 ) ;
imshow ( i m r e s i z e ( m a t 2 g r a y ( act6chMax ) , i m g S i z e ) )

También podría gustarte