En aquest tema, explorarem dos conceptes fonamentals en el funcionament de les xarxes neuronals: la propagació cap endavant (forward propagation) i la propagació cap enrere (backward propagation). Aquests processos són essencials per entrenar una xarxa neuronal i ajustar els seus pesos per obtenir prediccions acurades.

Propagació cap endavant

Què és la propagació cap endavant?

La propagació cap endavant és el procés mitjançant el qual les dades d'entrada passen a través de la xarxa neuronal, capa per capa, fins a arribar a la sortida. Aquest procés implica calcular les sortides de cada neurona en cada capa utilitzant els pesos i les funcions d'activació.

Passos de la propagació cap endavant

  1. Entrada de dades: Les dades d'entrada es presenten a la capa d'entrada de la xarxa neuronal.

  2. Càlcul de les sortides de les neurones: Per a cada capa, es calcula la sortida de cada neurona utilitzant la fórmula: \[ z = W \cdot x + b \] on:

    • \( z \) és la sortida de la neurona abans d'aplicar la funció d'activació.
    • \( W \) són els pesos de les connexions.
    • \( x \) és el vector d'entrada.
    • \( b \) és el biaix (bias).
  3. Aplicació de la funció d'activació: La sortida \( z \) es passa a través d'una funció d'activació \( \sigma \) per obtenir la sortida final de la neurona: \[ a = \sigma(z) \]

  4. Repetició per a totes les capes: Aquest procés es repeteix per a totes les capes de la xarxa fins a arribar a la capa de sortida.

Exemple de codi

import numpy as np

# Funció d'activació sigmoide
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# Propagació cap endavant
def forward_propagation(X, W, b):
    z = np.dot(W, X) + b
    a = sigmoid(z)
    return a

# Exemple d'ús
X = np.array([0.5, 0.2, 0.1])  # Entrada
W = np.array([0.4, 0.3, 0.2])  # Pesos
b = 0.1  # Biaix

output = forward_propagation(X, W, b)
print("Sortida de la neurona:", output)

Propagació cap enrere

Què és la propagació cap enrere?

La propagació cap enrere és el procés mitjançant el qual es calcula el gradient de la funció de pèrdua respecte als pesos de la xarxa neuronal. Aquest procés permet ajustar els pesos per minimitzar l'error de predicció.

Passos de la propagació cap enrere

  1. Càlcul de l'error de sortida: Es calcula l'error de la sortida de la xarxa comparant la sortida prevista amb la sortida desitjada (etiqueta). \[ \delta = \hat{y} - y \] on:

    • \( \delta \) és l'error de la sortida.
    • \( \hat{y} \) és la sortida prevista.
    • \( y \) és la sortida desitjada.
  2. Càlcul del gradient: Es calcula el gradient de l'error respecte als pesos utilitzant la regla de la cadena. \[ \frac{\partial L}{\partial W} = \delta \cdot \frac{\partial \hat{y}}{\partial z} \cdot \frac{\partial z}{\partial W} \]

  3. Actualització dels pesos: Els pesos es modifiquen en la direcció oposada al gradient per minimitzar l'error. \[ W = W - \eta \cdot \frac{\partial L}{\partial W} \] on:

    • \( \eta \) és la taxa d'aprenentatge.

Exemple de codi

# Funció de derivada de la sigmoide
def sigmoid_derivative(z):
    return sigmoid(z) * (1 - sigmoid(z))

# Propagació cap enrere
def backward_propagation(X, y, W, b, output, learning_rate):
    error = output - y
    dW = error * sigmoid_derivative(output) * X
    db = error * sigmoid_derivative(output)
    
    # Actualització dels pesos i el biaix
    W = W - learning_rate * dW
    b = b - learning_rate * db
    
    return W, b

# Exemple d'ús
y = 0.6  # Sortida desitjada
learning_rate = 0.01

W, b = backward_propagation(X, y, W, b, output, learning_rate)
print("Pesos actualitzats:", W)
print("Biaix actualitzat:", b)

Exercici pràctic

Exercici

Implementa una xarxa neuronal simple amb una capa d'entrada, una capa oculta i una capa de sortida. Utilitza la propagació cap endavant i cap enrere per entrenar la xarxa amb un conjunt de dades d'exemple.

Solució

import numpy as np

# Funcions d'activació i les seves derivades
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def sigmoid_derivative(z):
    return sigmoid(z) * (1 - sigmoid(z))

# Propagació cap endavant
def forward_propagation(X, W1, b1, W2, b2):
    z1 = np.dot(W1, X) + b1
    a1 = sigmoid(z1)
    z2 = np.dot(W2, a1) + b2
    a2 = sigmoid(z2)
    return a1, a2

# Propagació cap enrere
def backward_propagation(X, y, W1, b1, W2, b2, a1, a2, learning_rate):
    error_output = a2 - y
    dW2 = error_output * sigmoid_derivative(a2) * a1
    db2 = error_output * sigmoid_derivative(a2)
    
    error_hidden = np.dot(W2.T, error_output) * sigmoid_derivative(a1)
    dW1 = error_hidden * X
    db1 = error_hidden
    
    # Actualització dels pesos i els biaixos
    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2
    
    return W1, b1, W2, b2

# Inicialització dels pesos i els biaixos
np.random.seed(42)
W1 = np.random.rand(3, 3)
b1 = np.random.rand(3)
W2 = np.random.rand(1, 3)
b2 = np.random.rand(1)

# Dades d'exemple
X = np.array([0.5, 0.2, 0.1])
y = np.array([0.6])
learning_rate = 0.01

# Entrenament de la xarxa
for epoch in range(1000):
    a1, a2 = forward_propagation(X, W1, b1, W2, b2)
    W1, b1, W2, b2 = backward_propagation(X, y, W1, b1, W2, b2, a1, a2, learning_rate)

print("Pesos i biaixos actualitzats:")
print("W1:", W1)
print("b1:", b1)
print("W2:", W2)
print("b2:", b2)

Resum

En aquesta secció, hem après sobre la propagació cap endavant i cap enrere, dos processos essencials per entrenar xarxes neuronals. La propagació cap endavant implica el càlcul de les sortides de les neurones a través de la xarxa, mentre que la propagació cap enrere calcula els gradients per ajustar els pesos i minimitzar l'error de predicció. Hem vist exemples de codi per implementar aquests processos i hem practicat amb un exercici pràctic per consolidar els conceptes apresos.

© Copyright 2024. Tots els drets reservats