En este artículo os reproduciré un ejemplo simple de cómo se implementa un algoritmo de red neuronal en Python usando numpy (sin necesidad de librerías de aprendizaje automático como TensorFlow o PyTorch). Este ejemplo será para una red neuronal feedforward básica de una sola capa oculta, y se utilizará para un problema de regresión.
La red neuronal tendrá:
- Una capa de entrada con 2 neuronas (para 2 características de entrada).
- Una capa oculta con 2 neuronas.
- Una capa de salida con 1 neurona.
Algoritmo de Red Neuronal: Ejemplo en Python
import numpy as np
# Paso 1: Inicialización de parámetros
# Definimos el número de neuronas en cada capa
input_layer_size = 2 # 2 características de entrada
hidden_layer_size = 2 # 2 neuronas en la capa oculta
output_layer_size = 1 # 1 neurona en la capa de salida
# Inicialización aleatoria de los pesos y sesgos
np.random.seed(42) # Fijamos una semilla para reproducibilidad
weights_input_hidden = np.random.randn(input_layer_size, hidden_layer_size) # Pesos de la capa de entrada a la capa oculta
bias_hidden = np.random.randn(1, hidden_layer_size) # Sesgos para la capa oculta
weights_hidden_output = np.random.randn(hidden_layer_size, output_layer_size) # Pesos de la capa oculta a la capa de salida
bias_output = np.random.randn(1, output_layer_size) # Sesgos para la capa de salida
# Paso 2: Definir la función de activación (ReLU para la capa oculta y sigmoide para la capa de salida)
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return np.where(x > 0, 1, 0)
# Paso 3: Propagación hacia adelante (Forward Propagation)
def forward_propagation(X):
# Capa oculta
z_hidden = np.dot(X, weights_input_hidden) + bias_hidden
a_hidden = relu(z_hidden) # Activación de la capa oculta
# Capa de salida
z_output = np.dot(a_hidden, weights_hidden_output) + bias_output
a_output = sigmoid(z_output) # Activación de la capa de salida
return a_output, a_hidden
# Paso 4: Retropropagación (Backpropagation)
def backward_propagation(X, y, a_output, a_hidden, learning_rate=0.1):
# Cálculo del error en la capa de salida
error_output = y - a_output # Diferencia entre salida esperada y salida predicha
d_output = error_output * sigmoid_derivative(a_output) # Gradiente de la capa de salida
# Cálculo del error en la capa oculta
error_hidden = d_output.dot(weights_hidden_output.T)
d_hidden = error_hidden * relu_derivative(a_hidden) # Gradiente de la capa oculta
# Actualización de los pesos y sesgos
weights_hidden_output += a_hidden.T.dot(d_output) * learning_rate
bias_output += np.sum(d_output, axis=0, keepdims=True) * learning_rate
weights_input_hidden += X.T.dot(d_hidden) * learning_rate
bias_hidden += np.sum(d_hidden, axis=0, keepdims=True) * learning_rate
# Paso 5: Entrenamiento del modelo
def train(X, y, epochs=10000, learning_rate=0.1):
for epoch in range(epochs):
# Propagación hacia adelante
a_output, a_hidden = forward_propagation(X)
# Retropropagación
backward_propagation(X, y, a_output, a_hidden, learning_rate)
# Cada cierto número de épocas, imprimimos el error para ver cómo disminuye
if epoch % 1000 == 0:
loss = np.mean(np.square(y - a_output)) # Error cuadrático medio (MSE)
print(f"Epoch {epoch}/{epochs}, Loss: {loss}")
# Paso 6: Probar la red neuronal
def predict(X):
a_output, _ = forward_propagation(X)
return a_output
# Datos de entrada (X) y salida esperada (y) para entrenamiento
# X son las características de entrada, y es el valor esperado
X_train = np.array([[0, 0],
[0, 1],
[1, 0],
[1, 1]]) # Ejemplo de datos para una operación lógica
y_train = np.array([[0], # Salida esperada para 0 AND 0
[0], # Salida esperada para 0 AND 1
[0], # Salida esperada para 1 AND 0
[1]]) # Salida esperada para 1 AND 1
# Entrenamos la red neuronal
train(X_train, y_train)
# Hacemos una predicción después del entrenamiento
print("\nPredicciones después del entrenamiento:")
print(predict(np.array([[0, 0]]))) # Predicción para entrada [0, 0]
print(predict(np.array([[0, 1]]))) # Predicción para entrada [0, 1]
print(predict(np.array([[1, 0]]))) # Predicción para entrada [1, 0]
print(predict(np.array([[1, 1]]))) # Predicción para entrada [1, 1]
Explicación del código:
- Inicialización:
- Definimos el tamaño de las capas de entrada, oculta y salida.
- Inicializamos los pesos y sesgos aleatoriamente para cada capa de la red neuronal.
- Funciones de Activación:
- Usamos ReLU para la capa oculta porque es buena para introducir no linealidades.
- Usamos sigmoide en la capa de salida, ya que la salida está en el rango (0, 1), ideal para problemas de clasificación o regresión con valores entre 0 y 1.
- Propagación hacia adelante:
- Calculamos las salidas de las capas ocultas y de salida. Primero, las entradas pasan por la capa oculta, luego por la capa de salida.
- Retropropagación:
- Calculamos el error entre la salida predicha y la salida real.
- Retropropagamos este error para ajustar los pesos y sesgos utilizando el gradiente descendente.
- Entrenamiento:
- Entrenamos la red con el algoritmo de retropropagación, y en cada época, actualizamos los pesos y sesgos para reducir el error.
- Predicciones:
- Después de entrenar, hacemos predicciones con entradas que no han sido vistas para comprobar el funcionamiento de la red.
Salida Esperada:
Al ejecutar el código, deberías ver una reducción en el error (pérdida) a medida que se entrenan las épocas, y finalmente, las predicciones deben ser cercanas a los valores esperados:
Epoch 0/10000, Loss: 0.28950632772032997
Epoch 1000/10000, Loss: 0.03868588393150106
Epoch 2000/10000, Loss: 0.022606473339225327
Epoch 3000/10000, Loss: 0.016220257878795697
...
Predicciones después del entrenamiento:
[[0.0180578]]
[[0.97369339]]
[[0.97381397]]
[[0.98883593]]
Aquí puedes ver cómo la red neuronal aprende a hacer predicciones correctas (en este caso, una operación lógica AND).
¡¡OJO!!:
- Este ejemplo es muy básico y se puede ampliar con redes más profundas (más capas ocultas), diferentes funciones de activación, y usando técnicas de optimización más avanzadas.
-
El uso de librerías como TensorFlow o PyTorch facilita mucho el proceso de entrenamiento y la implementación de redes neuronales más complejas.
¡Muy Interesante!
Esperando a que nos hables sobre DeepSeek.
Un saludo!