Resúmenes

Apuntes universitarios en formato Markdown desde Obsidian.

Creare Rete Neurale da Zero

download Descargar MD

Costruzione di una Rete Neurale (Feedforward)

Implementiamo una semplice rete neurale feedforward con uno strato nascosto utilizzando Python e NumPy.

Classe SimpleNeuralNetwork

import matplotlib.pyplot as plt
import numpy as np

class SimpleNeuralNetwork:
    def __init__(self, n_input=2, n_hidden=3, n_output=1):
        # Inizializzazione pesi e bias
        self.W1 = np.random.rand(n_input, n_hidden)
        self.W2 = np.random.rand(n_hidden, n_output)
        self.B1 = np.zeros(n_hidden)
        self.B2 = np.zeros(n_output)

    def loss(self, out, out_pred):
        # Mean Absolute Error (o simile)
        return np.mean(np.sqrt(np.abs(out - out_pred)))

    def activationFunction(self, A):
        # Sigmoide
        return 1. / (1. + np.exp(-A))

    def gradActFuction(self, out):
        # Derivata della Sigmoide
        return out * (1 - out)

    def forward(self, input_data):
        self.Z0 = input_data

        # Layer 1
        self.A1 = np.dot(self.Z0, self.W1) + self.B1
        self.Z1 = self.activationFunction(self.A1)

        # Layer 2 (Output)
        self.A2 = np.dot(self.Z1, self.W2) + self.B2
        self.Z2 = self.activationFunction(self.A2)

        return self.Z2

    def grad(self, input_data, output, output_pred, learning_rate):
        # Backpropagation
        m = input_data.shape[0] # o shape[1] a seconda di come sono passati i dati

        # Calcolo gradienti Output Layer
        self.delta2 = (output_pred - output) * self.gradActFuction(output_pred)
        self.dW2 = np.matmul(self.Z1.T, self.delta2)
        self.dB2 = np.sum(self.delta2, axis=0)

        # Calcolo gradienti Hidden Layer
        self.delta1 = np.matmul(self.delta2, self.W2.T) * self.gradActFuction(self.Z1)
        self.dW1 = np.matmul(self.Z0.T, self.delta1)
        self.dB1 = np.sum(self.delta1, axis=0)

        # Aggiornamento pesi
        self.W1 -= learning_rate * self.dW1
        self.W2 -= learning_rate * self.dW2
        self.B1 -= learning_rate * self.dB1
        self.B2 -= learning_rate * self.dB2

    def fit(self, input_data, output, epochs=1, learning_rate=0.05):
        history = []
        for epoch in range(epochs):
            output_pred = self.forward(input_data)
            loss_val = self.loss(output, output_pred)
            history.append(loss_val)

            self.grad(input_data, output, output_pred, learning_rate)

        self.plot_loss(history)

    def predict(self, input_data):
        return np.array(self.forward(input_data))

    def plot_loss(self, loss):
        plt.plot(loss)
        plt.xlabel('Epochs')
        plt.ylabel('Loss')
        plt.show()

Esempio di Utilizzo (Classificazione Malattia)

Supponiamo di voler prevedere se una persona è malata basandoci su età e reddito.

import pandas as pd
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import scale

# Caricamento e preparazione dati (ipotetico)
# df = pd.read_csv("dataset.csv")
# df.Illness = pd.Categorical(df.Illness).codes
# data = np.array(df.drop(columns='Illness'))
# labels = np.array(df['Illness']).reshape(-1, 1)

# data = scale(data)
# x_train, x_val, y_train, y_val = train_test_split(data, labels, random_state=0)

# Training
# net = SimpleNeuralNetwork()
# net.fit(x_train, y_train, epochs=2000)

# Valutazione
# y_pred_val = net.predict(x_val)
# y_pred_bin_val = (y_pred_val >= 0.5).astype("int")
# print("Validation accuracy", accuracy_score(y_pred_bin_val, y_val))

Visualizzazione Funzioni di Attivazione

Ecco come visualizzare le principali funzioni di attivazione con Python.

Sigmoid

def sigmoid(x):
    return 1. / (1. + np.exp(-x))

x = np.linspace(-10, 10, 100)
plt.plot(x, sigmoid(x))
plt.title('Sigmoid Function')
plt.show()

Tanh

def tanh(x):
    return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))

plt.plot(x, tanh(x))
plt.title('Tanh Function')
plt.show()

ReLU

def relu(x):
    return np.maximum(0, x)

plt.plot(x, relu(x))
plt.title('ReLU Function')
plt.show()