Introducción a Keras Sequential y API Funcional
Contents
Introducción a Keras Sequential y API Funcional#
Introducción a TensorFlow#
La mejor introducción a esta biblioteca fundamental de inteligencia artificial es entrando a la documentación oficial
Introducción a Keras#
Keras no es más que una API funcionando sobre algún motor tensorial (Por ejemplo, TensorFlow).
Igual que antes, no hay nada mejor que ir a los sitios oficiales y chequear por sí mismxs la documentación oficial:
¿Por qué elegir Keras?#
Preguntémosle a dios Google:
Importando Librerías Necesarias#
Como siempre, lo primero que debemos hacer es importar las librerías necesarias:
# Librería para manejo de tensores
import tensorflow as tf
# API para AI sobre motor de tensores
from tensorflow import keras
# Manejo de arreglos
import numpy as np
# Dibujitos
import matplotlib.pyplot as plt
Simulando Datos #
En esta ocasión y por ser la introducción, mostraremos que el proceso de optimización visto en clase (usando JAX), es equivalente a construir una red neuronal artificial.
Para esto, simulemos unos datos de prueba:
# Genera datos espaciados uniformemente
x=np.linspace(-10,10,50)
# Modelo generado a partir de las entradas
y=2*x**2+3*x+5*np.random.normal(0,4,size=len(x))
Observemos algo de los datos simulados:
print(x)
[-10. -9.59183673 -9.18367347 -8.7755102 -8.36734694
-7.95918367 -7.55102041 -7.14285714 -6.73469388 -6.32653061
-5.91836735 -5.51020408 -5.10204082 -4.69387755 -4.28571429
-3.87755102 -3.46938776 -3.06122449 -2.65306122 -2.24489796
-1.83673469 -1.42857143 -1.02040816 -0.6122449 -0.20408163
0.20408163 0.6122449 1.02040816 1.42857143 1.83673469
2.24489796 2.65306122 3.06122449 3.46938776 3.87755102
4.28571429 4.69387755 5.10204082 5.51020408 5.91836735
6.32653061 6.73469388 7.14285714 7.55102041 7.95918367
8.36734694 8.7755102 9.18367347 9.59183673 10. ]
print(y)
[217.99355623 142.68741022 146.31621191 128.13479406 111.73941384
89.47685489 105.11836081 81.19732541 41.91156847 66.78121834
30.2499299 32.93817221 66.38013768 11.53944667 39.74005336
43.18997134 13.49564781 -2.55456125 12.85486119 8.49065364
10.54997947 -3.52320593 -23.10728138 5.28466635 5.13328338
-30.04973645 5.07860833 -9.28112974 30.58987377 -8.71957095
10.0410125 38.08053443 48.66118723 40.10339338 67.65755535
51.50627849 57.20230928 85.52521727 64.79352386 123.02358686
80.40731023 103.25935165 127.73747174 99.3556638 158.00346775
159.85390715 173.74514933 175.63960935 165.48174042 199.00324966]
Visualizando Datos#
En lo posible, trate de visualizar datos para tener una intuición sobre lo que está pasando. Es claro que no siempre es posible hacerlo, pero existen, por ejemplo, técnicas de reducción de dimensión para dar una idea vaga de lo que está pasando.
# Generar Lienzo
plt.figure(figsize=(15,8))
#Titulo del lienzo
plt.title("Visualización de Datos",fontsize=15)
#Dibujar datos
plt.plot(x,y,'o')
# Leyenda de los datos
plt.legend(["Datos"],fontsize=15)
# Nombrar Ejes
plt.xlabel("$Tiempo$",fontsize=15)
plt.ylabel("$Valor$",fontsize=15)
# Poner cuadrícula
plt.grid()
# Mostrar imagen
plt.show()
Construyendo Red Neuronal (Diseño)#
Para construir nuestra primera red Neuronal, recuerde el siguiente dibujo:
Vemos que el dibujo opera de izquierda a derecha (\(\rightarrow\)), por lo que tiene sentido llamarlo Modelo Secuencial.
En este caso, usaremos una neurona (units
) y la dimensión de entrada es unidimensional (input_shape
)
model = keras.Sequential(
keras.layers.Dense(units=1,input_shape=(1,))
)
Compilando Red Neuronal (Forma de Optimizar)#
Ahora que tenemos nuestra maqueta de las ecuaciones del modelo, elegimos una función de pérdida adecuada a nuestro problema y un optimizador para minimizar dicha pérdida:
model.compile(optimizer='sgd', loss='mean_squared_error')
Resumen de la Red Neuronal#
El modelo creado y compilado tiene muchos otros métodos interesantes.
Por ejemplo, podemos ver el resumen de lo que tiene la red.
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 1) 2
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
_________________________________________________________________
También es posible visualizar los modelos en forma de grafo, lo cual es muy útil para tener control global de la arquitectura del modelo:
from tensorflow.keras.utils import plot_model
plot_model(model,show_shapes=True)
You must install pydot (`pip install pydot`) and install graphviz (see instructions at https://graphviz.gitlab.io/download/) for plot_model/model_to_dot to work.
Entrenando Red Neuronal (Fancy para «Ajustar los datos»)#
model.fit(x, y, epochs=10,verbose=1)
Epoch 1/10
1/2 [==============>...............] - ETA: 0s - loss: 6596.0742
2/2 [==============================] - 1s 8ms/step - loss: 8620.6582
Epoch 2/10
1/2 [==============>...............] - ETA: 0s - loss: 8898.5801
2/2 [==============================] - 0s 8ms/step - loss: 8100.7305
Epoch 3/10
1/2 [==============>...............] - ETA: 0s - loss: 7838.4111
2/2 [==============================] - 0s 0s/step - loss: 8003.3955
Epoch 4/10
1/2 [==============>...............] - ETA: 0s - loss: 9316.4707
2/2 [==============================] - 0s 0s/step - loss: 7479.1870
Epoch 5/10
1/2 [==============>...............] - ETA: 0s - loss: 7585.7280
2/2 [==============================] - 0s 8ms/step - loss: 7672.4448
Epoch 6/10
1/2 [==============>...............] - ETA: 0s - loss: 5066.2114
2/2 [==============================] - 0s 8ms/step - loss: 7128.1436
Epoch 7/10
1/2 [==============>...............] - ETA: 0s - loss: 5780.6123
2/2 [==============================] - 0s 8ms/step - loss: 7198.5161
Epoch 8/10
1/2 [==============>...............] - ETA: 0s - loss: 5357.8721
2/2 [==============================] - 0s 0s/step - loss: 6663.5493
Epoch 9/10
1/2 [==============>...............] - ETA: 0s - loss: 7064.5449
2/2 [==============================] - 0s 8ms/step - loss: 6941.7188
Epoch 10/10
1/2 [==============>...............] - ETA: 0s - loss: 5028.7676
2/2 [==============================] - 0s 8ms/step - loss: 6354.8145
<keras.callbacks.History at 0x19f58a4fbb0>
Visualizar Resultados de la Red #
#Obtener Pesos de la Red
w=model.get_weights();
print(w)
#Imprimir resultados
print("\nObjeto Pesos:",w)
print('\nNumber of Weights -> '+ str(len(w)))
print('\nw = ' + str(w[0][0]) +'(Weight)')
print('b = ' + str(w[1])+'("Weight"->Bias)')
[array([[-0.24988794]], dtype=float32), array([23.104277], dtype=float32)]
Objeto Pesos: [array([[-0.24988794]], dtype=float32), array([23.104277], dtype=float32)]
Number of Weights -> 2
w = [-0.24988794](Weight)
b = [23.104277]("Weight"->Bias)
Predecir valores dentro de los datos (Ver Regresión)#
predecir=model.predict(x)
#print(predecir)
#np.vstack((predecir.reshape(-1,),y)).T
1/2 [==============>...............] - ETA: 0s
2/2 [==============================] - 0s 8ms/step
Visualizar Resultados#
plt.figure(figsize=(15,8))
plt.plot(x,predecir,'r-',label='Model: y={:.2f}*x+{:.2f}'.format(w[0].item(),w[1].item()))
plt.plot(x,y,'o', label='Data')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
Mejorando Red Neuronal#
model2 = tf.keras.Sequential([
keras.layers.Dense(units=5,input_shape=(1,),activation='softplus'),
keras.layers.Dense(units=10,activation='softplus'),
keras.layers.Dense(units=20,activation='softplus'),
keras.layers.Dense(units=1),
])
model2.compile(optimizer='adam', loss='mean_squared_error')
model2.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 5) 10
dense_2 (Dense) (None, 10) 60
dense_3 (Dense) (None, 20) 220
dense_4 (Dense) (None, 1) 21
=================================================================
Total params: 311
Trainable params: 311
Non-trainable params: 0
_________________________________________________________________
history=model2.fit(x, y, epochs=1000,verbose=0)
#Obtener Pesos de la Red
w2=model2.get_weights();
#Imprimir resultados
#print("\nObjeto Pesos:",w2)
#print('\nNumber of Weights -> '+ str(len(w2)))
#print('\nw = ' + str(w[0][0]) +'(Weight)')
#print('b = ' + str(w[1])+'("Weight"->Bias)')
x_test=np.linspace(x[0],x[-1],300)
predecir=model2.predict(x_test)
1/10 [==>...........................] - ETA: 0s
10/10 [==============================] - 0s 2ms/step
plt.figure(figsize=(15,8))
plt.plot(x_test,predecir,label='Model')
plt.plot(x,y,'o', label='Data')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
plt.figure(figsize=(15,8))
plt.plot(history.history['loss'],'r-',label='Loss')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
Datos más retadores#
trend=0.1
time=np.arange(0,100,0.1)
y=trend*time+np.sin(time)+np.random.normal(scale=0.5,size=len(time))
plt.figure(figsize=(15,8))
plt.title("Visualización de Datos",fontsize=15)
plt.plot(time,y,'-')
plt.legend(["Datos"],fontsize=15)
plt.xlabel("$x$",fontsize=15)
plt.ylabel("$y$",fontsize=15)
plt.grid()
plt.show()
model3 = tf.keras.Sequential([
keras.layers.Dense(units=10,input_shape=(1,),activation='elu'),
keras.layers.Dense(units=20,activation='elu'),
keras.layers.Dense(units=30,activation='elu'),
keras.layers.Dense(units=40,activation='elu'),
keras.layers.Dense(units=50,activation='elu'),
keras.layers.Dense(units=60,activation='elu'),
keras.layers.Dense(units=70,activation='elu'),
keras.layers.Dense(units=1)
])
model3.compile(optimizer='adam', loss='mean_squared_error')
model3.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_5 (Dense) (None, 10) 20
dense_6 (Dense) (None, 20) 220
dense_7 (Dense) (None, 30) 630
dense_8 (Dense) (None, 40) 1240
dense_9 (Dense) (None, 50) 2050
dense_10 (Dense) (None, 60) 3060
dense_11 (Dense) (None, 70) 4270
dense_12 (Dense) (None, 1) 71
=================================================================
Total params: 11,561
Trainable params: 11,561
Non-trainable params: 0
_________________________________________________________________
history=model3.fit(time, y, epochs=10000,verbose=0)
#Obtener Pesos de la Red
w3=model3.get_weights();
#Imprimir resultados
#print("\nObjeto Pesos:",w2)
#print('\nNumber of Weights -> '+ str(len(w2)))
#print('\nw = ' + str(w[0][0]) +'(Weight)')
#print('b = ' + str(w[1])+'("Weight"->Bias)')
x_test=np.linspace(time[0],time[-1],3000)
predecir=model3.predict(x_test)
plt.figure(figsize=(15,8))
plt.plot(time,y,'-', label='Data')
plt.plot(x_test,predecir,'r',label='Model')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
plt.figure(figsize=(15,8))
plt.plot(history.history['loss'],'r-',label='Model')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
API Funcional#
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.layers import Activation, Input,Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
trend=0.1
time=np.arange(0,100,0.1)
y=trend*time+np.sin(time)+np.random.normal(scale=0.5,size=len(time))
inputs=Input(shape=(1,))
output=inputs
capas=10
dim=10
output=Activation('elu')(output)
for capa in range(capas):
output=Dense(dim)(output)
output=Activation('elu')(output)
dim+=10
output=Dense(1)(output)
model=Model(inputs,output)
model.compile(loss='mse',optimizer='adam')
model.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 1)] 0
_________________________________________________________________
activation (Activation) (None, 1) 0
_________________________________________________________________
dense_13 (Dense) (None, 10) 20
_________________________________________________________________
activation_1 (Activation) (None, 10) 0
_________________________________________________________________
dense_14 (Dense) (None, 20) 220
_________________________________________________________________
activation_2 (Activation) (None, 20) 0
_________________________________________________________________
dense_15 (Dense) (None, 30) 630
_________________________________________________________________
activation_3 (Activation) (None, 30) 0
_________________________________________________________________
dense_16 (Dense) (None, 40) 1240
_________________________________________________________________
activation_4 (Activation) (None, 40) 0
_________________________________________________________________
dense_17 (Dense) (None, 50) 2050
_________________________________________________________________
activation_5 (Activation) (None, 50) 0
_________________________________________________________________
dense_18 (Dense) (None, 60) 3060
_________________________________________________________________
activation_6 (Activation) (None, 60) 0
_________________________________________________________________
dense_19 (Dense) (None, 70) 4270
_________________________________________________________________
activation_7 (Activation) (None, 70) 0
_________________________________________________________________
dense_20 (Dense) (None, 80) 5680
_________________________________________________________________
activation_8 (Activation) (None, 80) 0
_________________________________________________________________
dense_21 (Dense) (None, 90) 7290
_________________________________________________________________
activation_9 (Activation) (None, 90) 0
_________________________________________________________________
dense_22 (Dense) (None, 100) 9100
_________________________________________________________________
activation_10 (Activation) (None, 100) 0
_________________________________________________________________
dense_23 (Dense) (None, 1) 101
=================================================================
Total params: 33,661
Trainable params: 33,661
Non-trainable params: 0
_________________________________________________________________
history=model.fit(time,y,epochs=500,verbose=0)
x_test=np.linspace(time[0],time[-1],1000)
predecir=model.predict(x_test)
plt.figure(figsize=(15,8))
plt.plot(time[0:300],y[0:300],'-', label='Data')
plt.plot(x_test[0:300],predecir[0:300],'r',label='Model')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()
plt.figure(figsize=(15,8))
plt.plot(history.history['loss'],'r-',label='Model')
plt.title('Plotting Model vs Data')
plt.legend(loc=0)
plt.show()