Zusammenfassungen

Universitätsnotizen im Markdown-Format aus Obsidian.

Creare Rete Neurale da Zero

download MD herunterladen

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()