Sirve 1
Sirve 1
Sirve 1
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
1
Abstract
Keywords
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
3
ÍNDICE 4
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
5
1. Fundamentos
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].
n
X
EntradaN eta =< ~x, w
~ > +w0 = xi wi + w0 = x1 w1 + . . . + xn wn + w0 (1.1)
i=1
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.
α : 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.
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
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].
n
X
y = f( (wi xi ) + w0 )
i=1
ej = dj − yj para j = 1, . . . , P
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.
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:
∂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
∂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
→
−
xt = −
x−→ −−→
t−1 − α 5 f (xt−1 )
|| 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.
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
N N N
1 XX X
E=− wij Si Sj + θi Si
2 i=1 j=1 i=1
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
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:
A:(0.25,0.16)
B:(0.85,0.35)
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)
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
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
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.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
P
1 X
E= Ep
P p=1
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 , θ )))
L−1
∂Ep ∂Ep ∂f ∂N etaip
L
= L−1 L
(2.6)
∂wji ∂f ∂N etaip ∂wji
∂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
∂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
Ep (f L (N etaL−1
ip (f
L−1 L−2
(N etajp L−1
(w1j L−1
, w2j , . . . , wnL−1
0 j )))))
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:
∂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
∂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:
∂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:
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.
32
Entrada A Entrada B Salida
0 0 0
1 0 1
0 1 1
1 1 0
Caso Salida
0 0 0
1 0 1
0 1 1
1 1 0
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
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=−∞
k1 X
X k2
S(i, j) = I(i − m + 1, j − n + 1)K(i, j)
m=1 n=1
k1 X
X k2
S(i, j) = I(i + m − 1, j + n − 1)K(m, n)
m=1 n=1
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
−1 −2 −1
0 0 0
1 2 1
−1 0 1
−2 0 2
−1 2 1
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
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
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.
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
d
X
CkT g Tk
k=1
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
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.
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.
[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.
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.
[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.
[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-
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.
Chow(96 %)
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.
Filtros convolución
Filtros convolución
import numpy as np
import scipy as sc
import matplotlib . pyplot as plt
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 )
#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
_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
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
i f (_ %100 == 0 ) :
p l t . p l o t ( Theta [ 0 ] , Theta [ 1 ] , ".", c=" r e d " )
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 )
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 ] )
if r e p e a t e d > max_repeat :
break
prev_error = e r r o r
return u
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
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 )
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
# 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
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]])
net = a le xn et ;
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 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 )
# 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 )
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 )
%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 )