Introducció

Les xarxes neuronals són la base del Deep Learning. Aquestes estructures matemàtiques estan inspirades en el funcionament del cervell humà i són capaces d'aprendre i generalitzar a partir de dades. En aquesta secció, explorarem els conceptes bàsics que conformen una xarxa neuronal.

Components d'una Xarxa Neuronal

  1. Neurona Artificial

Una neurona artificial és la unitat bàsica d'una xarxa neuronal. Cada neurona rep una o més entrades, les processa i produeix una sortida.

  • Entrades (Inputs): Són els valors que la neurona rep. Poden ser dades d'entrada o sortides d'altres neurones.
  • Peses (Weights): Cada entrada està associada a un pes que determina la seva importància.
  • Biaix (Bias): Un valor addicional que ajuda a ajustar la sortida de la neurona.
  • Funció d'Activació: Una funció que transforma la suma ponderada de les entrades i el biaix en la sortida de la neurona.

  1. Capes de la Xarxa

Les xarxes neuronals estan formades per capes de neurones.

  • Capa d'Entrada: La primera capa que rep les dades d'entrada.
  • Capes Ocultes: Capes intermèdies entre la capa d'entrada i la capa de sortida. Aquestes capes realitzen la major part del processament.
  • Capa de Sortida: L'última capa que produeix la sortida final de la xarxa.

  1. Arquitectura de la Xarxa

L'arquitectura d'una xarxa neuronal es refereix a la seva estructura, incloent el nombre de capes i el nombre de neurones per capa.

Funcionament d'una Xarxa Neuronal

  1. Propagació cap Endavant (Forward Propagation)

És el procés pel qual les dades d'entrada es propaguen a través de la xarxa per produir una sortida.

  1. Càlcul de la Sortida de cada Neurona: \[ z = \sum_{i=1}^{n} (w_i \cdot x_i) + b \] \[ a = \text{funció d'activació}(z) \] On:
    • \( w_i \) són els pesos.
    • \( x_i \) són les entrades.
    • \( b \) és el biaix.
    • \( z \) és la suma ponderada.
    • \( a \) és la sortida després d'aplicar la funció d'activació.

  1. Funció de Pèrdua (Loss Function)

Mesura la discrepància entre la sortida prevista per la xarxa i la sortida desitjada. Algunes funcions de pèrdua comunes són l'error quadràtic mitjà (MSE) i l'entropia creuada.

  1. Propagació cap Enrere (Backpropagation)

És el procés d'ajustar els pesos i els biaixos de la xarxa per minimitzar la funció de pèrdua.

  1. Càlcul del Gradient: Es calcula el gradient de la funció de pèrdua respecte als pesos i biaixos.
  2. Actualització dels Pesos: Els pesos es modifiquen en la direcció oposada al gradient per reduir la pèrdua. \[ w = w - \eta \cdot \frac{\partial L}{\partial w} \] On:
    • \( \eta \) és la taxa d'aprenentatge.
    • \( \frac{\partial L}{\partial w} \) és el gradient de la funció de pèrdua respecte al pes.

Exemple Pràctic

Implementació d'una Neurona Simple en Python

import numpy as np

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

# Derivada de la funció sigmoide
def sigmoid_derivative(x):
    return x * (1 - x)

# Entrades
inputs = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])

# Sortides esperades
expected_output = np.array([[0], [1], [1], [0]])

# Inicialització de pesos i biaix
inputLayerNeurons, hiddenLayerNeurons, outputLayerNeurons = 2, 2, 1
hidden_weights = np.random.uniform(size=(inputLayerNeurons, hiddenLayerNeurons))
hidden_bias = np.random.uniform(size=(1, hiddenLayerNeurons))
output_weights = np.random.uniform(size=(hiddenLayerNeurons, outputLayerNeurons))
output_bias = np.random.uniform(size=(1, outputLayerNeurons))

# Taxa d'aprenentatge
learning_rate = 0.1

# Entrenament
for _ in range(10000):
    # Propagació cap endavant
    hidden_layer_activation = np.dot(inputs, hidden_weights)
    hidden_layer_activation += hidden_bias
    hidden_layer_output = sigmoid(hidden_layer_activation)

    output_layer_activation = np.dot(hidden_layer_output, output_weights)
    output_layer_activation += output_bias
    predicted_output = sigmoid(output_layer_activation)

    # Càlcul de l'error
    error = expected_output - predicted_output

    # Propagació cap enrere
    d_predicted_output = error * sigmoid_derivative(predicted_output)
    error_hidden_layer = d_predicted_output.dot(output_weights.T)
    d_hidden_layer = error_hidden_layer * sigmoid_derivative(hidden_layer_output)

    # Actualització dels pesos i biaixos
    output_weights += hidden_layer_output.T.dot(d_predicted_output) * learning_rate
    output_bias += np.sum(d_predicted_output, axis=0, keepdims=True) * learning_rate
    hidden_weights += inputs.T.dot(d_hidden_layer) * learning_rate
    hidden_bias += np.sum(d_hidden_layer, axis=0, keepdims=True) * learning_rate

print("Sortida prevista després de l'entrenament:")
print(predicted_output)

Explicació del Codi

  1. Inicialització: Es defineixen les entrades, sortides esperades, pesos i biaixos inicials.
  2. Propagació cap Endavant: Es calcula la sortida de cada capa aplicant la funció d'activació.
  3. Càlcul de l'Error: Es calcula la diferència entre la sortida prevista i la sortida esperada.
  4. Propagació cap Enrere: Es calcula el gradient de l'error i s'ajusten els pesos i biaixos.
  5. Actualització: Els pesos i biaixos es modifiquen per reduir l'error.

Exercici Pràctic

Exercici 1: Implementar una Neurona amb Funció d'Activació ReLU

  1. Implementa una neurona artificial amb la funció d'activació ReLU.
  2. Entrena la neurona amb un conjunt de dades d'exemple.
  3. Compara els resultats amb la funció d'activació sigmoide.

Solució

import numpy as np

# Funció d'activació (ReLU)
def relu(x):
    return np.maximum(0, x)

# Derivada de la funció ReLU
def relu_derivative(x):
    return np.where(x > 0, 1, 0)

# Entrades
inputs = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])

# Sortides esperades
expected_output = np.array([[0], [1], [1], [0]])

# Inicialització de pesos i biaix
inputLayerNeurons, hiddenLayerNeurons, outputLayerNeurons = 2, 2, 1
hidden_weights = np.random.uniform(size=(inputLayerNeurons, hiddenLayerNeurons))
hidden_bias = np.random.uniform(size=(1, hiddenLayerNeurons))
output_weights = np.random.uniform(size=(hiddenLayerNeurons, outputLayerNeurons))
output_bias = np.random.uniform(size=(1, outputLayerNeurons))

# Taxa d'aprenentatge
learning_rate = 0.1

# Entrenament
for _ in range(10000):
    # Propagació cap endavant
    hidden_layer_activation = np.dot(inputs, hidden_weights)
    hidden_layer_activation += hidden_bias
    hidden_layer_output = relu(hidden_layer_activation)

    output_layer_activation = np.dot(hidden_layer_output, output_weights)
    output_layer_activation += output_bias
    predicted_output = relu(output_layer_activation)

    # Càlcul de l'error
    error = expected_output - predicted_output

    # Propagació cap enrere
    d_predicted_output = error * relu_derivative(predicted_output)
    error_hidden_layer = d_predicted_output.dot(output_weights.T)
    d_hidden_layer = error_hidden_layer * relu_derivative(hidden_layer_output)

    # Actualització dels pesos i biaixos
    output_weights += hidden_layer_output.T.dot(d_predicted_output) * learning_rate
    output_bias += np.sum(d_predicted_output, axis=0, keepdims=True) * learning_rate
    hidden_weights += inputs.T.dot(d_hidden_layer) * learning_rate
    hidden_bias += np.sum(d_hidden_layer, axis=0, keepdims=True) * learning_rate

print("Sortida prevista després de l'entrenament:")
print(predicted_output)

Resum

En aquesta secció, hem explorat els conceptes bàsics de les xarxes neuronals, incloent les seves components principals, el funcionament de la propagació cap endavant i cap enrere, i hem implementat una neurona simple en Python. Aquests fonaments són essencials per comprendre i construir xarxes neuronals més complexes en els següents mòduls.

© Copyright 2024. Tots els drets reservats