Tabla de Contenidos
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 pétalo: Medido en cm
- El ancho de su pétalo: Medido en cm
Este conjunto de datos pretende distinguir entre los siguientes tres tipos de flores:
- Setosa
- Versicolor
- Virginica'
En la siguiente figura se muestra los valores del largo y ancho del pétalo según el tipo de flor:
¿Serías capaz con tu inteligencia "natural" , averiguar el tipo de flor según los valores del largo de sépalo y pétalo?
Si longitud_petalo < 2.5 → Setosa Si longitud_petalo ≥ 2.5: Si ancho_petalo < 1.7 → Versicolor Si ancho_petalo ≥ 1.7 → Virginica
Este "algoritmo o IA" lo podemos representar en python así:
def predict(longitud_petalo,ancho_petalo):
if longitud_petalo<2.5:
return 0
else:
if ancho_petalo>=1.7:
return 2
else:
return 1
Y se puede mostrar en la siguiente figura
las IAs realmente son algoritmos, solo que el algoritmo se crea casi automáticamente a partir de los datos.
Una figura con el mismo problema pero creado por una IA sería el siguiente:
- El largo de su sépalo
- El largo de su pétalo
- El ancho de su sépalo
- El ancho de su pétalo
La red neuronal
Como es el primer tema, solo vamos a usar 2 tipos de flor para hacer más fácil el problema.
Veamos ahora algunos datos:
| X | Y | ||
| Largo Pétalo | Ancho Pétalo | Valor flor | Nombre Flor |
| 1.4 | 0.2 | 0 | Setosa |
| 1.3 | 0.2 | 0 | Setosa |
| 1.3 | 0.3 | 0 | Setosa |
| 1.5 | 0.4 | 0 | Setosa |
| 1.4 | 0.2 | 0 | Setosa |
| 1.2 | 0.2 | 0 | Setosa |
| 1.7 | 0.4 | 0 | Setosa |
| 1.6 | 0.2 | 0 | Setosa |
| 1.3 | 0.2 | 0 | Setosa |
| 1.2 | 0.2 | 0 | Setosa |
| 3.5 | 1.0 | 1 | Versicolor |
| 4.5 | 1.5 | 1 | Versicolor |
| 3.5 | 1.0 | 1 | Versicolor |
| 4.4 | 1.4 | 1 | Versicolor |
| 3.5 | 1.0 | 1 | Versicolor |
| 4.1 | 1.3 | 1 | Versicolor |
| 4.8 | 1.8 | 1 | Versicolor |
| 4.4 | 1.3 | 1 | Versicolor |
| 3.9 | 1.2 | 1 | Versicolor |
| 4.5 | 1.3 | 1 | Versicolor |
La red neuronal lo único que va a hacer es "aprender" a crear una función matemática que dado el largo del pétalo y el ancho del pétalo calcule el tipo de flor:
$$ tipo \: flor=f(largo \: petalo,ancho \: petalo) $$
- 0:Setosa
- 1:Versicolor
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 pétalo y el ancho 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.
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.
Código en Python
Veamos ahora el código python de la red neuronal.
El código completo es el siguiente:
import random import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from sklearn.datasets import load_iris iris=load_iris() longitudes_petalos=iris.data[0:99,2] anchos_petalos=iris.data[0:99,3] flower_type=iris.target[0:99] x=np.column_stack((longitudes_petalos,anchos_petalos)) y=flower_type np.random.seed(5) tf.random.set_seed(5) random.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='binary_crossentropy') model.fit(x, y,epochs=100) print(model.predict(np.array([[1.4,0.2]]))) print(model.predict(np.array([[4.4,1.3]])))
Ahora vamos a ver todo el código paso a paso.
import random import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from sklearn.datasets import load_iris
Estas líneas simplemente hacer los "import" de varias cosas que vamos a usar.
longitudes_petalos=iris.data[0:99,2] anchos_petalos=iris.data[0:99,3] flower_type=iris.target[0:99] x=np.column_stack((longitudes_petalos,anchos_petalos)) y=flower_type
Hemos cargado los datos y hemos creado 3 arrays:
longitudes_petalos: Con la longitud de cada pétalo que es la columna 2 de la matrizdataanchos_petalos: Con la anchura de cada pétalo que es la columna 3 de la matrizdataflower_type: Con el tipo de flor (0 o 1)
Luego hemos creado una matriz juntando la longitud de cada pétalo y la anchura 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) random.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='binary_crossentropy')
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.
loss.
Para acabar compilamos el modelo con el método compile.
model.fit(x, y,epochs=100)
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/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 1s 105ms/step - loss: 0.6408 Epoch 2/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 961us/step - loss: 0.6225 Epoch 3/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.6031 Epoch 4/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5911 Epoch 5/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5854 Epoch 6/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5805 Epoch 7/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5755 Epoch 8/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5705 Epoch 9/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5657 Epoch 10/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.5609 ........ 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.1176 Epoch 90/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.1136 Epoch 91/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.1097 Epoch 92/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 958us/step - loss: 0.1059 Epoch 93/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.1021 Epoch 94/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.0984 Epoch 95/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.0948 Epoch 96/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 979us/step - loss: 0.0913 Epoch 97/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 910us/step - loss: 0.0879 Epoch 98/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.0845 Epoch 99/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.0812 Epoch 100/100 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - loss: 0.0780
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.
Una vez acabar vamos a usar nuestra función matemática con el método predict con los siguientes valores:
print(model.predict(np.array([[1.4,0.2]]))) print(model.predict(np.array([[4.4,1.3]])))
[[0.09985255]] [[0.99229264]]
| X | Y Predicha | Y Real | ||
| Largo Pétalo | Ancho Pétalo | Score Flor Predicha (y_score) | Valor Flor Predicha(y_pred) | Valor Flor Real(y_true) |
| 1.4 | 0.2 | 0.09985255 | 0 | 0 |
| 4.4 | 1.3 | 0.99229264 | 1 | 1 |
Vemos como los resultados no son exactamente 0 o 1 sino número cercanos como el 0.09985255 o el 0.99229264 pero no nos preocupemos, las redes neuronales no suelen dar resultados exactos.
Entonces fijarse que hay que distinguir entre:
y_score: El número que ha generado la red neuronal. Ej:0.99229264y_pred: Lo que predecimos en función de la red neuronal. Si es mayor que 0.5 predecimos1y sino predecimos0y_true: El valor real que debería haber predicho.
- 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.
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
figure=plt.figure(figsize = (5, 4))
axes = figure.add_subplot()
colors = ["#0E5581", "#8F0C00", "#0C8F00"]
cmap = ListedColormap(colors[:len(np.unique(y))])
scatter=axes.scatter(x=x[:,0], y=x[:,1], c=y, cmap=cmap,s=6)
axes.set_xlabel('Largo Pétalo')
axes.set_ylabel('Ancho Pétalo')
for i, name in enumerate(["Setosa","Versicolor"]):
color = scatter.cmap(scatter.norm(i))
axes.scatter([], [], color=[color], label=name+":"+str(i))
axes.set_xlim(xmin=0,xmax=8)
axes.set_ylim(ymin=0,ymax=3)
axes.legend(title="Flores")
Ahora vamos a hacer una gráfica con el resultado de la red neuronal
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
figure=plt.figure(figsize = (5, 4))
axes = figure.add_subplot()
colors = ["#0E5581", "#8F0C00", "#0C8F00"]
cmap = ListedColormap(colors[:len(np.unique(y))])
colors = ["#83B5F1", "#FF8175", "#75FF81"]
cmap_fondo = ListedColormap(colors[:len(np.unique(y))])
xt=np.linspace(0,8,300)
yt=np.linspace(0,3,300)
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)
scatter=axes.scatter(x=xa, y=ya, c=za, cmap=cmap_fondo,s=6)
axes.set_xlabel('Largo Pétalo')
axes.set_ylabel('Ancho Pétalo')
for i, name in enumerate(["Setosa","Versicolor"]):
color = scatter.cmap(scatter.norm(i))
axes.scatter([], [], color=[color], label=name+":"+str(i))
scatter=axes.scatter(x=x[:,0], y=x[:,1], c=y, cmap=cmap,s=6)
axes.set_xlim(xmin=0,xmax=8)
axes.set_ylim(ymin=0,ymax=3)
axes.legend(title="Flores")
Lo que hay que hacer es comparar los datos de las 2 gráficas para ver si son coherentes entre ellas. Y obviamente lo son
Las dificultades de la IA
Al entrenar una IA lo dificil es cuando se encuentra con cosas que no habías previsto.
Si creamos una IA, para saber si una foto es de un chihuahua pero le pasamos una foto de un muffin, lo más normal es que lo confunda con un chihuahua.🤷🏻
Ejercicios
Ejercicio 1.A
Usando Google collab haz una red neuronal en python con Keras que obtenga el tipo de flor en función del "Largo Pétalo" y de "Ancho 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.
| X | Y Predicha | Y Real | ||
| Largo Pétalo | Ancho Pétalo | Score Flor Predicha (y_score) | Valor Flor Predicha(y_pred) | Valor Flor Real(y_true) |
| 1.3 | 0.3 | |||
| 3.9 | 1.2 | |||
Ejercicio 1.B
Ejercicio 2.A
Modifica ahora la red neuronal de forma que:
- La 1º capa oculta tenga 4 neuronas en vez de 6
- La 2º capa oculta tenga 5 neuronas en vez de 12
- La 3º capa oculta tenga 3 neuronas en vez de 6
- La 4º capa seguirá teniendo 1 neurona
- Sean solo 30 épocas.
- La semilla sea 5.
Usando la web http://alexlenail.me/NN-SVG/index.html dibuja la red neuronal que acabas de crear
Ahora muestra los resultados
| X | Y Predicha | Y Real | ||
| Largo Pétalo | Ancho Pétalo | Score Flor Predicha (y_score) | Valor Flor Predicha(y_pred) | Valor Flor Real(y_true) |
| 1.3 | 0.3 | |||
| 3.9 | 1.2 | |||
Ejercicio 2.B
Ejercicio 3
Usando el código de la red original, modifica las siguientes líneas:
longitudes_petalos=iris.data[0:99,2] anchos_petalos=iris.data[0:99,3] flower_type=iris.target[0:99]
de forma que queden así:
longitudes_petalos=iris.data[:,2] anchos_petalos=iris.data[:,3] flower_type=iris.target[:]
Entrena la red con los nuevos datos
Muestra la siguiente gráfica con los datos de entrada:
Ahora verás que está el otro tipo de flor llamado Virginica.
Prueba a ver si funciona ahora la red neuronal con el nuevo tipo de flor.
| X | Y Predicha | Y Real | ||
| Largo Pétalo | Ancho Pétalo | Score Flor Predicha (y_score) | Valor Flor Predicha(y_pred) | Valor Flor Real(y_true) |
| 5.1 | 1.5 | 2 | ||
| 5.8 | 2.2 | 2 | ||
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 siguientes:
- 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.
Imprime el valor de la fila 56 tanto de la x como de la y.
#Para que los datos no se muestren con notación científica np.set_printoptions(suppress=True) print(x[56],y[56])
Ahora muestra los valores de la x y la y para la fila 204.
Crea una red neuronal en las que en cada capa tenga los siguientes números de neuronas:
| Nº Capa | Nº Neuronas |
| 1º | 30 |
| 2º | 60 |
| 3º | 100 |
| 4º | 60 |
| 5º | 30 |
| 6º | 10 |
| 7º | 1 |
Rellena la siguiente tabla y muestrala
| X | Y Predicha | Y Real | |
| Fila Datos | y_score | y_pred | y_true |
| 56 | |||
| 204 | |||
¿Es una buena red?
Usa hora una red más pequeña de forma que tenga las siguientes capas:
| Nº Capa | Nº Neuronas |
| 1º | 6 |
| 2º | 12 |
| 3º | 6 |
| 4º | 1 |
Rellena la siguiente tabla y muestrala
| X | Y Predicha | Y Real | |
| Fila Datos | y_score | y_pred | y_true |
| 56 | |||
| 204 | |||
¿Es una buena red?
Ejercicio 6
Repite la red pequeña del ejercicio anterior pero ahora modificando la semilla de los números aleatorios
np.random.seed(5) tf.random.set_seed(5) random.seed(5)
Rellena la siguiente tabla y muestrala con una red con la semilla 6
| X | Y Predicha | Y Real | |
| Fila Datos | y_score | y_pred | y_true |
| 56 | |||
| 204 | |||
Rellena la siguiente tabla y muestrala con una red con la semilla 88
| X | Y Predicha | Y Real | |
| Fila Datos | y_score | y_pred | y_true |
| 56 | |||
| 204 | |||
Ejercicio 7.A
Una estrella que explota como supernova. Al explotar expulsa elementos metálicos y no metálicos.
Al pasar 15 años se mide la distancia a la que están los elementos y mediante un arduo trabajo científico, se averigua para cada elemento si es un metal o un no metal.
Hace una red neuronal que según la posición en la que se encuentra el elemento lo califique como metal o no metal.
Los datos son los siguientes:
x =np.array([
[12.9, 11.4], [13.7, 8.3], [15.6, 10.6], [11.0, 11.6], [12.7, 13.8], [13.2, 11.8], [12.3, 11.7], [11.5, 14.7], [11.7, 11.2], [10.7, 9.3],
[12.6, 11.8], [10.1, 9.7], [16.9, 9.8], [13.4, 9.0], [14.2, 17.0], [17.2, 12.0], [12.2, 13.9], [14.4, 15.5], [12.2, 11.8], [10.6, 14.2],
[15.5, 15.4], [7.7, 9.8], [9.6, 13.2], [10.8, 12.2], [11.9, 13.0], [10.7, 13.6], [9.0, 14.3], [9.4, 15.0], [14.7, 11.9], [14.7, 9.2],
[14.8, 10.6], [16.2, 13.3], [14.3, 14.7], [12.6, 11.3], [16.2, 15.0], [15.9, 11.9], [13.8, 15.0], [10.1, 7.8], [11.9, 17.4], [8.8, 14.4],
[15.6, 13.9], [14.6, 15.0], [11.6, 12.4], [15.7, 9.9], [10.5, 12.2], [12.1, 12.6], [12.5, 13.2], [9.8, 10.1], [8.0, 13.6], [14.0, 14.2],
[13.1, 11.3], [15.0, 14.2], [13.0, 7.8], [14.6, 12.1], [10.5, 13.9], [9.0, 7.9], [12.7, 8.9], [13.5, 10.9], [12.8, 14.3], [10.1, 16.3],
[13.7, 16.8], [7.5, 11.5], [12.0, 11.5], [14.7, 12.0], [12.1, 11.7], [9.7, 9.6], [10.2, 13.5], [14.1, 13.1], [10.4, 10.6], [12.5, 15.5],
[17.5, 11.0], [11.8, 7.8], [11.6, 17.5], [8.9, 8.0], [13.8, 12.4], [10.1, 10.2], [14.2, 10.0], [13.6, 9.7], [8.1, 15.0], [8.3, 15.5],
[9.2, 9.5], [16.5, 12.9], [11.4, 12.8], [12.0, 13.1], [12.9, 12.0], [11.6, 11.9], [12.0, 11.2], [13.6, 16.6], [10.3, 14.2], [12.5, 13.0],
[8.9, 8.6], [12.7, 6.7], [10.3, 14.1], [11.6, 11.7], [12.3, 15.0], [12.6, 12.3], [15.0, 10.5], [15.9, 10.8], [11.2, 8.1], [10.4, 13.8],
[8.6, 15.4], [7.6, 5.0], [6.2, 12.5], [5.5, 7.2], [16.2, 7.3], [17.1, 10.3], [8.8, 7.7], [4.9, 16.7], [12.8, 5.8], [10.0, 4.3],
[4.8, 13.8], [17.9, 11.9], [3.7, 12.8], [16.2, 20.2], [16.6, 8.5], [17.2, 8.9], [7.9, 9.4], [11.7, 17.1], [12.7, 19.0], [13.0, 6.3],
[11.3, 17.6], [18.5, 8.2], [20.0, 13.5], [13.1, 17.6], [10.6, 18.4], [8.1, 15.4], [16.7, 16.7], [9.6, 7.6], [8.4, 17.4], [12.5, 18.3],
[17.1, 17.4], [4.0, 13.3], [17.4, 9.6], [6.3, 14.8], [7.2, 9.9], [17.1, 12.1], [13.4, 19.7], [5.9, 12.0], [13.3, 17.1], [14.8, 20.1],
[9.5, 3.5], [12.1, 6.6], [16.2, 4.1], [15.6, 20.8], [4.5, 17.9], [9.3, 16.8], [5.5, 14.7], [21.4, 10.8], [7.8, 13.8], [17.6, 9.6],
[15.7, 18.7], [5.9, 5.3], [5.0, 7.9], [21.4, 14.7], [3.1, 12.2], [14.3, 6.3], [16.2, 16.3], [11.3, 20.3], [7.5, 12.7], [17.9, 11.2],
[8.5, 5.1], [7.5, 4.5], [15.2, 19.2], [14.3, 6.6], [18.9, 5.4], [7.9, 15.7], [11.0, 3.9], [17.5, 13.8], [13.9, 8.0], [4.0, 14.3],
[14.7, 17.5], [20.2, 14.5], [9.3, 17.9], [8.8, 9.3], [17.0, 7.0], [14.8, 8.5], [5.6, 17.5], [8.3, 5.4], [14.6, 8.2], [12.0, 5.9],
[4.5, 9.9], [15.2, 7.1], [16.5, 7.3], [12.7, 19.0], [12.5, 17.3], [8.1, 10.4], [4.1, 10.1], [11.7, 16.6], [10.3, 17.9], [19.2, 9.7],
[6.0, 7.1], [17.6, 15.2], [17.0, 10.9], [16.4, 19.0], [7.9, 17.9], [7.5, 9.3], [4.8, 14.4], [7.4, 14.5], [9.2, 3.6], [15.9, 19.0]
])
y = np.array([
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
])
Tenemos la siguiente función compile_model(neuronas_capa_1,neuronas_capa_2,neuronas_capa_3,neuronas_capa_4) que acepta como argumentos el número de neuronas de cada capa.
def compile_model(neuronas_capa_1,neuronas_capa_2,neuronas_capa_3,neuronas_capa_4):
random.seed(5)
np.random.seed(5)
tf.random.set_seed(5)
model=Sequential()
model.add(Dense(neuronas_capa_1, activation='relu',input_dim=2))
model.add(Dense(neuronas_capa_2, activation='relu'))
model.add(Dense(neuronas_capa_3, activation='relu'))
model.add(Dense(neuronas_capa_4, activation='sigmoid'))
model.compile(loss='binary_crossentropy')
return model
Por último tenemos la función plot_result(model,x,y,figure,title,filas,columns,index) que tiene como argumentos:
model: Modelo a mostrarx: Datos a mostrary: Resultados a mostrarfigure: La figura sobre la que se dibuja la gráficatitle: Título de la gráficafilas: Filas de la figuracolumnas: Columnas de la figuraindex: Posición de la gráfica dentro de la figura. El indice empieza en 1 y va de izquierda a derecha y luego de arriba a abajo.
def plot_result(model,x,y,figure,title,filas,columns,index):
axes = figure.add_subplot(filas,columns,index)
axes.set_title(title, fontsize=14,pad=30,color="#003B80")
colors = ["#0E5581", "#8F0C00"]
cmap = ListedColormap(colors[:len(np.unique(y))])
colors = ["#83B5F1", "#FF8175"]
cmap_fondo = ListedColormap(colors[:len(np.unique(y))])
xt=np.linspace(0,22,400)
yt=np.linspace(0,22,400)
xt,yt=np.meshgrid(xt,yt)
xa=xt.reshape(-1)
ya=yt.reshape(-1)
xya=np.column_stack((xa,ya))
pred = model.predict(xya, verbose=False)
za = (pred > 0.5).astype(int).ravel()
zt=np.reshape(za,xt.shape)
scatter=axes.scatter(x=xa, y=ya, c=za, cmap=cmap_fondo,s=6)
axes.set_xlabel('Posición del elemento en el eje X')
axes.set_ylabel('Posición del elemento en el eje Y')
for i, name in enumerate(['No metal',"Metal"]):
color = scatter.cmap(scatter.norm(i))
axes.scatter([], [], color=[color], label=name+":"+str(i))
scatter=axes.scatter(x=x[:,0], y=x[:,1], c=y, cmap=cmap,s=6)
axes.set_xlim(xmin=0,xmax=22)
axes.set_ylim(ymin=0,ymax=22)
axes.legend(title="Elemento")
Para crear una figura se usa el código:
figure=plt.figure(figsize = (13.5, 8))
Siendo 13.8 y 8 el ancho y alto de la figura.
Por último siempre hay que poner al final:
figure.tight_layout()
Veamos un ejemplo de como se usa:
figure=plt.figure(figsize = (10, 8)) model=compile_model(6,12,6,1) model.fit(x, y,epochs=50,verbose=False) plot_result(model,x,y,figure,"6,12,6,1 epochs=50",2,2,1) model.fit(x, y,epochs=50,verbose=False) plot_result(model,x,y,figure,"6,12,6,1 epochs=100",2,2,2) model=compile_model(20,30,20,1) model.fit(x, y,epochs=100,verbose=False) plot_result(model,x,y,figure,"20,30,20,1 epochs=100",2,2,3) model.fit(x, y,epochs=100,verbose=False) plot_result(model,x,y,figure,"20,30,20,1 epochs=200",2,2,4) figure.tight_layout()
Veamos como quedaría como una animación de 3000 épocas.
Ahora muestra 6 gráficas con lo siguiente
- Red: 20,40,20,1
- épocas: 400
- épocas: 800
- épocas: 1200
- Red: 100,200,100,1
- épocas: 100
- épocas: 200
- épocas: 300
Ejercicio 7.B
Rellena ahora la siguiente tabla con el último modelo que has creado
| X | Y Predicha | Y Real | |
| Posición del elemento | y_score | y_pred | y_true |
| 13.1, 17.6 | |||
| 3.7, 12.8 | |||
Ejercicio 7.C
Vuelve a entrenar la primera red con los 1200 épocas. Y muestra los resultados Pero ahora cambia los datos por lo datos de otra supernova y muestra solo los datos.
x_entrenamiento =np.array([
[12.9, 11.4], [13.7, 8.3], [15.6, 10.6], [11.0, 11.6], [12.7, 13.8], [13.2, 11.8], [12.3, 11.7], [11.5, 14.7], [11.7, 11.2], [10.7, 9.3],
[12.6, 11.8], [10.1, 9.7], [16.9, 9.8], [13.4, 9.0], [14.2, 17.0], [17.2, 12.0], [12.2, 13.9], [14.4, 15.5], [12.2, 11.8], [10.6, 14.2],
[15.5, 15.4], [7.7, 9.8], [9.6, 13.2], [10.8, 12.2], [11.9, 13.0], [10.7, 13.6], [9.0, 14.3], [9.4, 15.0], [14.7, 11.9], [14.7, 9.2],
[14.8, 10.6], [16.2, 13.3], [14.3, 14.7], [12.6, 11.3], [16.2, 15.0], [15.9, 11.9], [13.8, 15.0], [10.1, 7.8], [11.9, 17.4], [8.8, 14.4],
[15.6, 13.9], [14.6, 15.0], [11.6, 12.4], [15.7, 9.9], [10.5, 12.2], [12.1, 12.6], [12.5, 13.2], [9.8, 10.1], [8.0, 13.6], [14.0, 14.2],
[13.1, 11.3], [15.0, 14.2], [13.0, 7.8], [14.6, 12.1], [10.5, 13.9], [9.0, 7.9], [12.7, 8.9], [13.5, 10.9], [12.8, 14.3], [10.1, 16.3],
[13.7, 16.8], [7.5, 11.5], [12.0, 11.5], [14.7, 12.0], [12.1, 11.7], [9.7, 9.6], [10.2, 13.5], [14.1, 13.1], [10.4, 10.6], [12.5, 15.5],
[17.5, 11.0], [11.8, 7.8], [11.6, 17.5], [8.9, 8.0], [13.8, 12.4], [10.1, 10.2], [14.2, 10.0], [13.6, 9.7], [8.1, 15.0], [8.3, 15.5],
[9.2, 9.5], [16.5, 12.9], [11.4, 12.8], [12.0, 13.1], [12.9, 12.0], [11.6, 11.9], [12.0, 11.2], [13.6, 16.6], [10.3, 14.2], [12.5, 13.0],
[8.9, 8.6], [12.7, 6.7], [10.3, 14.1], [11.6, 11.7], [12.3, 15.0], [12.6, 12.3], [15.0, 10.5], [15.9, 10.8], [11.2, 8.1], [10.4, 13.8],
[8.6, 15.4], [7.6, 5.0], [6.2, 12.5], [5.5, 7.2], [16.2, 7.3], [17.1, 10.3], [8.8, 7.7], [4.9, 16.7], [12.8, 5.8], [10.0, 4.3],
[4.8, 13.8], [17.9, 11.9], [3.7, 12.8], [16.2, 20.2], [16.6, 8.5], [17.2, 8.9], [7.9, 9.4], [11.7, 17.1], [12.7, 19.0], [13.0, 6.3],
[11.3, 17.6], [18.5, 8.2], [20.0, 13.5], [13.1, 17.6], [10.6, 18.4], [8.1, 15.4], [16.7, 16.7], [9.6, 7.6], [8.4, 17.4], [12.5, 18.3],
[17.1, 17.4], [4.0, 13.3], [17.4, 9.6], [6.3, 14.8], [7.2, 9.9], [17.1, 12.1], [13.4, 19.7], [5.9, 12.0], [13.3, 17.1], [14.8, 20.1],
[9.5, 3.5], [12.1, 6.6], [16.2, 4.1], [15.6, 20.8], [4.5, 17.9], [9.3, 16.8], [5.5, 14.7], [21.4, 10.8], [7.8, 13.8], [17.6, 9.6],
[15.7, 18.7], [5.9, 5.3], [5.0, 7.9], [21.4, 14.7], [3.1, 12.2], [14.3, 6.3], [16.2, 16.3], [11.3, 20.3], [7.5, 12.7], [17.9, 11.2],
[8.5, 5.1], [7.5, 4.5], [15.2, 19.2], [14.3, 6.6], [18.9, 5.4], [7.9, 15.7], [11.0, 3.9], [17.5, 13.8], [13.9, 8.0], [4.0, 14.3],
[14.7, 17.5], [20.2, 14.5], [9.3, 17.9], [8.8, 9.3], [17.0, 7.0], [14.8, 8.5], [5.6, 17.5], [8.3, 5.4], [14.6, 8.2], [12.0, 5.9],
[4.5, 9.9], [15.2, 7.1], [16.5, 7.3], [12.7, 19.0], [12.5, 17.3], [8.1, 10.4], [4.1, 10.1], [11.7, 16.6], [10.3, 17.9], [19.2, 9.7],
[6.0, 7.1], [17.6, 15.2], [17.0, 10.9], [16.4, 19.0], [7.9, 17.9], [7.5, 9.3], [4.8, 14.4], [7.4, 14.5], [9.2, 3.6], [15.9, 19.0]
])
y_entrenamiento = np.array([
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
])
x_validacion = np.array([
[11.4, 13.4], [11.7, 10.2], [11.4, 12.6], [12.1, 10.4], [8.9, 11.2], [9.2, 9.5], [11.3, 7.7], [6.9, 10.5], [10.0, 14.3], [11.6, 12.5],
[15.0, 13.2], [10.7, 7.1], [8.2, 12.1], [12.9, 14.0], [13.2, 8.9], [10.7, 12.7], [7.9, 12.8], [9.6, 15.7], [8.2, 8.0], [9.5, 10.2],
[9.8, 10.1], [10.5, 15.7], [10.0, 15.5], [10.9, 15.0], [9.1, 14.6], [12.0, 12.2], [13.1, 14.7], [12.7, 10.6], [12.6, 10.6], [12.0, 13.4],
[12.0, 11.2], [12.2, 15.2], [10.5, 9.4], [11.7, 7.1], [14.3, 11.5], [7.4, 9.1], [14.4, 11.0], [6.2, 10.5], [9.4, 9.1], [14.0, 10.7],
[10.9, 13.3], [12.3, 7.2], [12.5, 9.4], [14.7, 9.0], [12.3, 11.0], [9.1, 11.4], [13.7, 10.7], [9.8, 11.9], [11.7, 9.3], [6.8, 9.7],
[11.3, 8.5], [9.1, 11.2], [15.3, 11.8], [13.8, 12.7], [13.7, 13.3], [11.0, 15.6], [14.8, 10.2], [9.6, 9.5], [11.4, 10.1], [8.1, 9.7],
[8.5, 8.1], [12.6, 7.1], [12.6, 10.2], [14.0, 9.2], [13.2, 6.8], [12.7, 12.1], [9.6, 12.7], [13.6, 11.6], [7.9, 10.1], [12.4, 6.2],
[14.2, 12.1], [12.7, 15.2], [8.6, 13.7], [11.1, 13.9], [11.6, 8.9], [9.6, 12.9], [8.4, 7.9], [9.3, 11.1], [9.7, 10.2], [12.7, 10.3],
[14.4, 9.7], [12.9, 12.6], [12.0, 9.5], [9.7, 12.9], [12.1, 11.8], [9.0, 12.8], [6.8, 10.7], [13.7, 10.3], [9.1, 13.0], [12.1, 11.1],
[12.3, 9.4], [12.0, 11.8], [9.8, 11.2], [13.6, 7.4], [7.2, 10.6], [6.9, 12.4], [11.5, 9.5], [13.4, 11.3], [6.8, 8.9], [8.7, 12.4],
[19.7, 10.2], [13.8, 2.6], [15.7, 12.7], [13.5, 17.3], [4.0, 13.2], [9.1, 4.9], [7.8, 16.7], [6.9, 15.9], [16.2, 8.2], [15.9, 9.5],
[4.4, 15.3], [18.2, 5.6], [8.5, 15.5], [18.3, 15.2], [3.9, 9.8], [8.3, 6.7], [15.1, 7.7], [17.9, 9.5], [11.7, 5.6], [11.4, 4.8],
[9.5, 5.1], [8.3, 2.5], [11.7, 4.2], [17.1, 10.0], [4.9, 17.2], [18.7, 15.4], [11.5, 18.9], [12.0, 16.5], [5.4, 17.5], [13.5, 4.7],
[18.6, 14.0], [3.5, 13.4], [13.9, 4.0], [10.3, 19.0], [18.6, 14.2], [11.3, 17.8], [17.0, 14.5], [12.9, 6.0], [14.1, 16.7], [13.9, 19.0],
[13.3, 5.6], [14.0, 3.6], [4.0, 6.6], [16.0, 8.0], [18.5, 14.0], [18.4, 9.3], [3.0, 7.2], [8.9, 17.2], [14.7, 3.9], [6.5, 3.9],
[17.5, 10.4], [15.6, 14.7], [5.3, 7.8], [3.5, 12.3], [7.5, 6.1], [11.4, 19.4], [17.1, 12.2], [3.3, 8.8], [6.9, 15.7], [16.5, 6.6],
[2.8, 13.1], [4.9, 14.4], [6.0, 5.4], [4.7, 9.9], [17.7, 9.3], [12.3, 5.9], [3.9, 11.1], [12.6, 17.6], [6.1, 7.2], [10.9, 5.3],
[11.2, 4.6], [17.2, 10.7], [12.3, 17.3], [3.6, 14.7], [3.4, 15.0], [7.4, 18.9], [6.6, 16.0], [2.5, 12.2], [3.9, 9.1], [10.1, 19.9],
[14.7, 15.1], [8.4, 18.6], [15.8, 16.6], [8.1, 17.4], [7.5, 3.7], [4.3, 6.0], [19.3, 10.9], [5.1, 8.6], [4.8, 9.0], [6.4, 5.2],
[10.2, 5.9], [4.8, 5.5], [4.8, 7.1], [5.6, 6.8], [6.4, 17.0], [12.5, 2.3], [4.5, 6.0], [8.2, 18.1], [11.2, 16.8], [19.0, 14.8]
])
y_validacion = np.array([
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
])
figure=plt.figure(figsize = (12, 5))
model=compile_model(20,40,20,1)
model.fit(x_entrenamiento, y_entrenamiento,epochs=1200,verbose=False)
plot_result(model,x_entrenamiento, y_entrenamiento,figure,"Datos entrenamiento",1,2,1)
plot_result(model,x_validacion, y_validacion,figure,"Datos validación",1,2,2)
¿Que ha ocurrido?


















