Herramientas de usuario

Herramientas del sitio


clase:iabd:pia:1eval:tema01

1. Introducción a las redes neuronales

Es este tema vamos a ver un ejemplo concreto de una red neuronal.

Definición del problema

Vamos a ver un ejemplo muy sencillo de red neuronal que averigüe el tipo de una flor. Para ello vamos a usar un conjunto de datos que se llaman el Conjunto de datos flor iris.

Para ello vamos a usar las siguientes variables de entrada:

  • El largo de su sépalo: Medido en cm
  • El largo de su pétalo: Medido en cm

Este conjunto de datos pretende distinguir entre los siguientes dos tipos de flores:

  • Setosa
  • Versicolor

Veamos ahora algunos datos:

X Y
Largo Sépalo Largo Pétalo Tipo de Flor
5.1 1.4 Setosa
4.9 1.4 Setosa
4.7 1.3 Setosa
4.6 1.5 Setosa
5.0 1.4 Setosa
5.4 1.7 Setosa
5.1 1.9 Setosa
4.8 1.4 Setosa
5.3 1.5 Setosa
5.0 1.4 Setosa
7.0 4.7 Versicolor
6.4 4.5 Versicolor
6.9 4.9 Versicolor
5.5 4.0 Versicolor
6.2 4.5 Versicolor
5.6 3.9 Versicolor
5.9 4.8 Versicolor
6.1 4.0 Versicolor
6.3 4.9 Versicolor
6.3 4.4 Versicolor
5.6 4.1 Versicolor
5.7 4.2 Versicolor
5.7 4.2 Versicolor
6.2 4.3 Versicolor
5.1 3.0 Versicolor
Realmente el Conjunto de datos flor iris tiene 4 datos de entrada:
  • El largo de su sépalo
  • El largo de su pétalo
  • El ancho de su sépalo
  • El ancho de su pétalo

Y distingue entre 3 tipos de flores:

  • Setosa
  • Versicolor
  • Virginica

Pero por simplificar hemos usado solo el largo del sépalo y pétalo y dos tipos de flores.

La red neuronal lo único que va a hacer es "aprender" a crear una función matemática que dado el largo del sépalo y el largo del pétalo calcule el tipo de flor:

$$ tipo \: flor=f(largo \: sépalo,largo \: pétalo) $$

Debido a que las redes neuronales solo trabajan con números usaremos los siguientes números para los tipos de flor:
  • 0:Setosa
  • 1:Versicolor

La red neuronal

Vamos a hacer la siguiente red neuronal:

Esta red neuronal, consta de una serie de neuronas (ya contaremos mas adelante que es una neurona) que se pasan valores de unas a otras. Son cada uno de los círculos. Las neuronas se organiza en capas:

  • Capa de entrada (Círculos amarillos): Es una única capa por donde entran los datos de entrada. Es decir los valores del largo del sépalo y el largo del pétalo. Por lo tanto en este caso debe haber 2 neuronas , una por cada valor de entrada.
  • Capas ocultas (Círculos verdes): Son varias capas, las cuales calculan de que tipo es cada flor. La primera capa oculta consta de 6 neuronas. La segunda capa oculta consta de 12 neuronas . La última capa oculta consta de 6 neuronas.
  • Capa de salida (Círculos rojos): Es una única capa que es la que genera el resultado de la red neuronal. Como la red genera un único número la capa tiene solo 1 neurona.

La siguiente imagen es una animación de una red neuronal que calcula si una foto es un perro:

Google Colaboratory

Google Colaboratory es un IDE para programar en Python. El formato del IDE sige lo que se llaman "Jupyter Notebooks" que son ficheros con extensión "ipynb". Estos ficheros se pueden abrir desde VS Code u otros IDEs.

Ves a la página de Google Colaboratory, pincha en "Nuevo Cuaderno" y ya puedes empezar a programar en Python.

Una explicación completa de Google Colab la puedes ver en video Introducción a Google Colab, una noble y completa guía.

En otro tema veremos como usar Jupyter Notebooks en VS Code.

Código en Python

Veamos ahora el código python de la red neuronal.

El código completo es el siguiente:

import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from sklearn.datasets import load_iris
from matplotlib.colors import LightSource

iris=load_iris()

sepal_length=iris.data[0:99,0]
petal_length=iris.data[0:99,2]
flower_type=iris.target[0:99]

x=np.column_stack((sepal_length,petal_length))
y=flower_type


np.random.seed(5)
tf.random.set_seed(5)


model=Sequential()
model.add(Dense(6, activation='relu',input_dim=2))
model.add(Dense(12, activation='relu'))
model.add(Dense(6, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error')


model.fit(x, y,epochs=40) 


print(model.predict([[4.9,1.4]]))
print(model.predict([[6.3,4.9]]))

Ahora vamos a ver todo el código paso a paso.

import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from sklearn.datasets import load_iris
from matplotlib.colors import LightSource

Estas líneas simplemente hacer los "import" de varias cosas que vamos a usar.

iris=load_iris()

sepal_length=iris.data[0:99,0]
petal_length=iris.data[0:99,2]
flower_type=iris.target[0:99]

x=np.column_stack((sepal_length,petal_length))
y=flower_type

Hemos cargado los datos y hemos creado 3 arrays:

  • sepal_length: Con la longitud de cada sépalo que es la columna 0 de la matriz data
  • petal_length: Con la longitud de cada pétalo que es la columna 2 de la matriz data
  • flower_type: Con el tipo de flor (0 o 1)

Luego hemos creado una matriz juntando la longitud de cada sépalo y la longitud de cada pétalo, es lo que llamaremos x y luego hemos creado la y que es el tipo de flor.

Es decir que vamos a entrenar a red neuronal con los valores de x e y para que cree la función matemática capaz de calcular el tipo de flor en función de las longitudes.

np.random.seed(5)
tf.random.set_seed(5)

Para a siempre nos salgan los mismos resultados, hemos inicializado los generadores de números aleatorios.

model=Sequential()
model.add(Dense(6, activation='relu',input_dim=2))
model.add(Dense(12, activation='relu'))
model.add(Dense(6, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error')

Hemos creado el la estructura de la red neuronal. Excepto la capa de entrada, cada capa se especifica por un objeto de tipo Dense y el primer número especifica el Nº de neuronas de esa capa.

En la primera capa también hemos indicado la propiedad input_dim con el valor 2 que indica el Nº de valores de entrada , es decir que estamos diciendo el tamaño de la capa de entrada.

Comprueba que los tamaños de cada capa coinciden con los del esquema de la red y no te preocupes ahora por el Nº de capas o del Nº de neuronas por capa o de que es la activación (función de activación) o la propiedad loss.

Para acabar compilamos el modelo con el método compile.

model.fit(x, y,epochs=40) 

Ahora vemos a entrenar con el método fit la red neuronal para que ella internamente genere la función matemática. Fíjate como le pasamos la matriz con los datos de entrada x y el vector con el resultado que debe dar y.

Por último le decimos cuantas veces tiene que entrenar la red con el parámetro epochs. Cuanto más lo entrenemos , en general mejor será la red (Esta frase tiene muchos matices pero ya lo iremos viendo a lo largo del curso).

Epoch 1/40
4/4 [==============================] - 1s 9ms/step - loss: 0.2036
Epoch 2/40
4/4 [==============================] - 0s 5ms/step - loss: 0.1879
Epoch 3/40
4/4 [==============================] - 0s 5ms/step - loss: 0.1885
Epoch 4/40
4/4 [==============================] - 0s 3ms/step - loss: 0.1734
Epoch 5/40
4/4 [==============================] - 0s 7ms/step - loss: 0.1743

................


Epoch 35/40
4/4 [==============================] - 0s 3ms/step - loss: 0.0110
Epoch 36/40
4/4 [==============================] - 0s 3ms/step - loss: 0.0101
Epoch 37/40
4/4 [==============================] - 0s 3ms/step - loss: 0.0085
Epoch 38/40
4/4 [==============================] - 0s 3ms/step - loss: 0.0085
Epoch 39/40
4/4 [==============================] - 0s 2ms/step - loss: 0.0070
Epoch 40/40
4/4 [==============================] - 0s 6ms/step - loss: 0.0066

Ahora vemos el resultado del entrenamiento para cada una de las épocas, fíjate en loss , es lo que nos dice como de buena es nuestra red. Cuanto más pequeño sea ese valor, mejor es la red.

print(model.predict([[4.9,1.4]]))
print(model.predict([[6.3,4.9]]))

Una vez acabar vamos a usar nuestra función matemática con el método predict con los siguientes valores:

X Y
Largo Sépalo Largo Pétalo Tipo de Flor
4.9 1.4 Setosa
6.3 4.9 Versicolor

[[0.06094426]]
[[0.9634158]]

Vemos como los resultados no son exactamente 0 o 1 sino número cercanos como el 0.0609 o el 0.9634158 pero no nos preocupemos, las redes neuronales no suelen dar resultados exactos al 100%.

Para crear redes neuronales de Python existen 3 librerías
  • TensorFlow: Es una librería de Google. El problema es que es de muy bajo nivel. Fue de las primeras.

  • Keras: Es un API que está por encima de TensorFlow haciendo que sea muy sencillo crear redes neuronales.

  • Pytorch: Es la alternativa a Keras, está hecha por Facebook. Se usa mucho en proyectos de investigación.

Durante el curso vamos a usar Keras y algo de TensorFlow

Gráficas

La mayoría de veces para una mayor comprensión de los datos queremos también ver gráficos de éstos.

El siguiente código Python muestra la siguiente gráfica con cada una de las flores de los datos.

figure=plt.figure(figsize = (10, 7))
axes = figure.add_subplot()

scatter=axes.scatter(x=x[:,0], y=x[:,1], c=y, cmap=plt.cm.brg)
figure.colorbar(scatter,ax=axes)
axes.set_xlabel('Largo Sépalo')  
axes.set_ylabel('Largo Pétalo')

Ahora vamos a hacer una gráfica con el resultado de la red neuronal

figure=plt.figure(figsize=(8,8))
axes = figure.add_subplot(projection='3d')
 
xt=np.linspace(4,7,100)
yt=np.linspace(1,5.5,100)
xt,yt=np.meshgrid(xt,yt)

xa=xt.reshape(-1)
ya=yt.reshape(-1)
xya=np.column_stack((xa,ya))

za=model.predict([xya])

zt=np.reshape(za,xt.shape)

light_source = LightSource()
facecolors = light_source.shade(zt,plt.cm.brg, blend_mode='soft')
 
surface=axes.plot_surface(xt,yt,zt,facecolors=facecolors)
figure.colorbar(plt.cm.ScalarMappable(cmap=plt.cm.brg),ax=axes, shrink = 0.5)
axes.set_xlabel('Largo sépalo')  
axes.set_ylabel('Largo pétalo')
axes.set_zlabel('Tipo de flor')

Lo que hay que hacer es comparar los datos de las 2 gráficas para si son coherentes entre ellas. Y obviamente lo son

Ejercicios

Ejercicio 1

Usando Google collab haz una red neuronal en python con Keras que obtenga el tipo de flor en función del "Largo Sépalo" y de "Largo Pétalo".

Obtén el resultado de la red neuronal para las siguientes entradas e indica el tipo de flor que ha calcula la red neuronal.

Largo Sépalo Largo Pétalo Resultado red neuronal Tipo de Flor(0 o 1)
5.4 1.7
5.5 4.0

Ejercicio 2

Vamos a ver como se comportan las predicciones haciendo distintos cambios en nuestra red neuronal.

Los cambios son los siguientes:

  • No random seed

Deberás eliminar las siguientes líneas:

np.random.seed(5)
tf.random.set_seed(5)

  • 2 épocas

En el método fit cambia el número de épocas para que sea solo 2

  • Red neuronal pequeña

Modifica el código python de la red neuronal original de forma que:

  • La 1º capa oculta tenga 4 capas en vez de 6
  • La 2º capa oculta tenga 6 capas en vez de 12
  • La 3º capa oculta tenga 4 capas en vez de 6

Usando la web http://alexlenail.me/NN-SVG/index.html dibuja la red neuronal que acabas de crear

Ahora muestra los resultados en la siguiente tabla

Largo Sépalo Largo Pétalo Resultado red neuronal Original No random seed 2 épocas Red neuronal pequeña Tipo de Flor(0 o 1)
5.4 1.7
5.5 4.0

Ejercicio 3

Usando el código de la red original, modifica las siguientes líneas:

sepal_length=iris.data[0:99,0]
petal_length=iris.data[0:99,2]
flower_type=iris.target[0:99]

de forma que queden así:

sepal_length=iris.data[:,0]
petal_length=iris.data[:,2]
flower_type=iris.target[:]

Muestra la gráfica con los datos de entrada usando el código:

figure=plt.figure(figsize = (10, 7))
axes = figure.add_subplot()
 
scatter=axes.scatter(x=x[:,0], y=x[:,1], c=y, cmap=plt.cm.brg)
figure.colorbar(scatter,ax=axes)
axes.set_xlabel('Largo Sépalo')  
axes.set_ylabel('Largo Pétalo')

Ahora verás que hay otro tipo de flor llamado Virginica.

Prueba a ver si funciona ahora la red neuronal con el nuevo tipo de flor.

Largo Sépalo Largo Pétalo Resultado red neuronal Tipo de Flor
6.9 5.1
7.7 6.1

Ejercicio 4

Piensa al menos 3 problemas que se podrían resolver con una red neuronal similar a la que has usado.

Ejercicio 5

Vamos a ver ahora otro conjunto de datos relativo a la detección de cáncer de mama.

Los datos se obtienen de la siguiente forma:

from sklearn.datasets import load_breast_cancer

breast_cancer=load_breast_cancer()

x=breast_cancer.data
y=breast_cancer.target

Este conjunto de datos tiene 30 variable de entrada, que son las siguentes:

  • mean radius
  • mean texture
  • mean perimeter
  • mean area
  • mean smoothness
  • mean compactness
  • mean concavity
  • mean concave points
  • mean symmetry
  • mean fractal dimension
  • radius error
  • texture error
  • perimeter error
  • area error
  • smoothness error
  • compactness error
  • concavity error
  • concave points error
  • symmetry error
  • fractal dimension error
  • worst radius
  • worst texture
  • worst perimeter
  • worst area
  • worst smoothness
  • worst compactness
  • worst concavity
  • worst concave points
  • worst symmetry
  • worst fractal dimension

Esto datos son relativos a imágenes de núcleos celulares como los siguientes:

Y los histogramas de todos los datos son los siguientes:

Podemos ven en los histogramas que no hay una forma fácil de saber si una célula es o no cancerígena.

En vez de incluir todos los datos en la red neuronal , habría que hacer un Análisis exploratorio de datos (EDA) y por ejemplo eliminar las columnas que están relacionadas.

Deberás hacer 3 redes neuronales distintas ( llamadas A, B y C) y comprobar las predicciones con 4 conjuntos de datos distintos (llamados , , y ).

Usando la web http://alexlenail.me/NN-SVG/index.html también deberás dibujar cada una de las redes neuronales que acabas de crear

Datos Resultado red neuronal A Resultado red neuronal B Resultado red neuronal C Resultado Real

Para ver los datos junto a su predicción puedes usar las siguientes líneas:

np.set_printoptions(threshold=np.inf)
np.set_printoptions(suppress=True)
np.column_stack((x,y))

Y mostrará algo simular a ésto:

array([[  17.99     ,   10.38     ,  122.8      , 1001.       ,
           0.1184   ,    0.2776   ,    0.3001   ,    0.1471   ,
           0.2419   ,    0.07871  ,    1.095    ,    0.9053   ,
           8.589    ,  153.4      ,    0.006399 ,    0.04904  ,
           0.05373  ,    0.01587  ,    0.03003  ,    0.006193 ,
          25.38     ,   17.33     ,  184.6      , 2019.       ,
           0.1622   ,    0.6656   ,    0.7119   ,    0.2654   ,
           0.4601   ,    0.1189   ,    0.       ],
       [  20.57     ,   17.77     ,  132.9      , 1326.       ,
           0.08474  ,    0.07864  ,    0.0869   ,    0.07017  ,
           0.1812   ,    0.05667  ,    0.5435   ,    0.7339   ,
           3.398    ,   74.08     ,    0.005225 ,    0.01308  ,
           0.0186   ,    0.0134   ,    0.01389  ,    0.003532 ,
          24.99     ,   23.41     ,  158.8      , 1956.       ,
           0.1238   ,    0.1866   ,    0.2416   ,    0.186    ,
           0.275    ,    0.08902  ,    0.       ],
           
           
    .....................
    
    
       [  20.6      ,   29.33     ,  140.1      , 1265.       ,
           0.1178   ,    0.277    ,    0.3514   ,    0.152    ,
           0.2397   ,    0.07016  ,    0.726    ,    1.595    ,
           5.772    ,   86.22     ,    0.006522 ,    0.06158  ,
           0.07117  ,    0.01664  ,    0.02324  ,    0.006185 ,
          25.74     ,   39.42     ,  184.6      , 1821.       ,
           0.165    ,    0.8681   ,    0.9387   ,    0.265    ,
           0.4087   ,    0.124    ,    0.       ],
       [   7.76     ,   24.54     ,   47.92     ,  181.       ,
           0.05263  ,    0.04362  ,    0.       ,    0.       ,
           0.1587   ,    0.05884  ,    0.3857   ,    1.428    ,
           2.548    ,   19.15     ,    0.007189 ,    0.00466  ,
           0.       ,    0.       ,    0.02676  ,    0.002783 ,
           9.456    ,   30.37     ,   59.16     ,  268.6      ,
           0.08996  ,    0.06444  ,    0.       ,    0.       ,
           0.2871   ,    0.07039  ,    1.       ]])

Siendo la última columna es resultado que debe dar. Y las 30 primeras columnas la entrada al método predict

Ejercicio 6

En este caso, vamos a utilizar un conjunto de datos para clasificar tipos de vino.

Los datos se obtienen de la siguiente forma:

from sklearn.datasets import load_wine

wine=load_wine()

x = wine.data
y = wine.target

Igual que el ejercicio anterior, deberás hacer 3 redes neuronales distintas ( llamadas A, B y C) y comprobar las predicciones con 4 conjuntos de datos distintos (llamados , , y ).

Datos Resultado red neuronal A Resultado red neuronal B Resultado red neuronal C Resultado Real
clase/iabd/pia/1eval/tema01.txt · Última modificación: 2021/10/18 09:09 por cesar