"""
Se trata de una sencilla red neuronal, ya resuelta en otro ejercicio,
utilizando la librería keras. Ahora lo planteamos de nuevo, utilizando
solamente las librerias numpy y matplotlib.
Se trataba de una red neuronal con este esquema:
input_size = 1
hidden_layer1_size = 8
hidden_layer2_size = 8
output_size = 1
Una neurona de entrada, con dos capas ocultas intermedias de 8 neuronas
cada una, y 1 neurona de salida.
Los datos generales y sencillos de la idea son los siguientes:
Se trata de cinco hermanos que a los 30 años median lo siguiente:
Antonio 1,70 cm. Pedrito 1,75. Juanito 1,78 . Carlitos 1,69. Ignacio 1,87.
Ramón 1,79.
Hace 6 meses ha nacido Santiaguito.
Cuales son las previsiones de estatura
cuando también tenga 30 años. Haremos graficas de salida de columnas.
También haremos gráficas de costos MSE, con salida imprimida por consola
de los valores de los mismos por cada iteración.
También se imprime en la salida la previsión que hace la red neuronal
de la estatura futura
Los hiperparámetros que adoptamos, son los siguientes:
learning_rate = 0.01
epochs = 40
Se puede jugar con los mismos con el fin de afinar los
resultados.
*************************************************************
Este ejercicio ha sido realizado en una plataforma Linux.
Ubuntu 20.04.6 LTS.
Se utiliza el editor Sublime text
*********************************************************
Ejecucion bajo consola linux con el comando:
python3 Aula_18_B.py
"""
from numpy.lib.function_base import append
import numpy as np
import matplotlib.pyplot as plt
# Datos de entrada (edad en años)
edades = np.array([30, 30, 30, 30, 30, 30])
# Datos de salida (estatura en cm)
estaturas = np.array([170, 175, 178, 169, 187, 179])
# Normalizar las edades y estaturas (opcional, pero puede ayudar en el entrenamiento)
edades_norm = edades / np.max(edades)
estaturas_norm = estaturas / np.max(estaturas)
# Número de neuronas en cada capa
input_size = 1
hidden_layer1_size = 8
hidden_layer2_size = 8
output_size = 1
# Inicialización de pesos y sesgos
np.random.seed(42)
weights_input_hidden1 = np.random.randn(input_size, hidden_layer1_size)
biases_hidden1 = np.zeros((1, hidden_layer1_size))
weights_hidden1_hidden2 = np.random.randn(hidden_layer1_size, hidden_layer2_size)
biases_hidden2 = np.zeros((1, hidden_layer2_size))
weights_hidden2_output = np.random.randn(hidden_layer2_size, output_size)
biases_output = np.zeros((1, output_size))
# Hiperparámetros
learning_rate = 0.01
epochs = 40
# Función de activación ReLU
def relu(x):
return np.maximum(0, x)
# Derivada de la función de activación ReLU
def relu_derivative(x):
return np.where(x > 0, 1, 0)
costo_historia = []
# Entrenamiento de la red neuronal
for epoch in range(epochs):
# Propagación hacia adelante
hidden1_input = np.dot(edades_norm.reshape(-1, 1), weights_input_hidden1) + biases_hidden1
hidden1_output = relu(hidden1_input)
hidden2_input = np.dot(hidden1_output, weights_hidden1_hidden2) + biases_hidden2
hidden2_output = relu(hidden2_input)
output = np.dot(hidden2_output, weights_hidden2_output) + biases_output
# Calcular la pérdida
loss = np.mean((output - estaturas_norm.reshape(-1, 1)) ** 2)
costo_historia.append(loss)
# Propagación hacia atrás
output_gradient = 2 * (output - estaturas_norm.reshape(-1, 1)) / len(estaturas_norm)
hidden2_gradient = output_gradient.dot(weights_hidden2_output.T) * relu_derivative(hidden2_input)
hidden1_gradient = hidden2_gradient.dot(weights_hidden1_hidden2.T) * relu_derivative(hidden1_input)
# Actualización de pesos y sesgos
weights_hidden2_output -= learning_rate * hidden2_output.T.dot(output_gradient)
biases_output -= learning_rate * np.sum(output_gradient, axis=0, keepdims=True)
weights_hidden1_hidden2 -= learning_rate * hidden1_output.T.dot(hidden2_gradient)
biases_hidden2 -= learning_rate * np.sum(hidden2_gradient, axis=0, keepdims=True)
weights_input_hidden1 -= learning_rate * edades_norm.reshape(-1, 1).T.dot(hidden1_gradient)
biases_hidden1 -= learning_rate * np.sum(hidden1_gradient, axis=0, keepdims=True)
# Predecir la estatura de Santiago a los 30 años (Santiaguito)
santiaguito_edad = np.array([30])
santiaguito_edad_norm = santiaguito_edad / np.max(edades)
hidden1_input = np.dot(santiaguito_edad_norm.reshape(-1, 1), weights_input_hidden1) + biases_hidden1
hidden1_output = relu(hidden1_input)
hidden2_input = np.dot(hidden1_output, weights_hidden1_hidden2) + biases_hidden2
hidden2_output = relu(hidden2_input)
santiaguito_estatura_norm = np.dot(hidden2_output, weights_hidden2_output) + biases_output
# Desnormalizar la estatura de Santiaguito
santiaguito_estatura = santiaguito_estatura_norm * np.max(estaturas)
#print("La previsión de estatura de Santiaguito a los 30 años es:", santiaguito_estatura[0][0], "cm")
# Datos para la gráfica de columnas
nombres = ['Antonio', 'Pedrito', 'Juanito', 'Carlitos', 'Ignacio', 'Ramón', 'Santiago con 30 años']
estaturas_todos = np.append(estaturas, santiaguito_estatura[0][0])
colores = ['blue'] * len(estaturas) + ['red']
# Ajustar el ancho de las columnas
ancho_columnas = 0.5
print("*******************************")
print("Historial de Costo:")
for index, misxvalues in enumerate(costo_historia):
print(f'Iteración {index} valores de x:{misxvalues}')
print("*******************************")
print("La previsión de estatura de Santiaguito a los 30 años es:", santiaguito_estatura[0][0], "cm")
print("*******************************")
# Graficar la gráfica de columnas
plt.bar(np.arange(len(nombres)), estaturas_todos, color=colores, width=ancho_columnas)
plt.xticks(np.arange(len(nombres)), nombres, rotation=45, ha='right')
plt.title('Estaturas a los 30 años')
plt.xlabel('Nombre')
plt.ylabel('Estatura (cm)')
plt.tight_layout()
plt.show()
plt.plot(range(epochs), costo_historia, color='black',marker='o',markerfacecolor='red')
plt.xlabel('Época')
plt.ylabel('Costo (MSE)')
plt.title('Costo MSE en el Descenso de Gradiente')
plt.show()
Comentarios sobre la versión: V-0 (0)
No hay comentarios