L'ottimizzazione bayesiana è una tecnica di ottimizzazione che si basa sulla probabilità e sulla statistica per trovare i migliori set di iperparametri per un modello (in questo caso di rete neurale) per massimizzare o minimizzare una funzione obiettivo. Nelle reti neurali questa ottimizzazione è usata per trovare la combinazione ottimale di parametri per massimizzare le prestazioni del modello.

Vediamo un esempio con la libreria scikit-learn che ci permette di creare una rete neutrale scikit-optimize per l'ottimizzazione.
Inizialmente supponiamo di avere un set di dati X_train e y_train già preparato che rappresentano le features corrispondenti a ciascun set.

import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from skopt import BayesSearchCV

Ora dobbiamo scegliere le variabili da ottimizzare che sono gli iperparametri della rete neurale: profondità della rete (hidden_layer_sizes), velocità di apprendimento iniziale (learning_rate_init), momento di discesa del gradiente stocastico (momentum) e forza di regolarizzazione L2 (alpha).

opt_params = {
    'hidden_layer_sizes': (3, 100),  # profondità rete e numero di "neuroni"
    'learning_rate_init': (1e-4, 1e-1, 'log-uniform'),  # velocità di apprendimento iniziale
    'momentum': (0.1, 0.9),  # momento SGD
    'alpha': (1e-6, 1e-2, 'log-uniform')  # forza L2
}

Per ottimizzare il tutto dividiamo i dati in set di addestramento (X_train, y_train) e set di convalida (X_val, y_val) e poi creiamo un classificatore MLP (Multi-Layer Perceptron) e usiamo questo tipo di ottimizzazione proprio per cercare iperparametri ottimali.

X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)

classifier = MLPClassifier(max_iter=1000)  # Creazione della rete neurale
bayes_cv = BayesSearchCV(classifier, opt_params, n_iter=30, cv=5, n_jobs=-1)
bayes_cv.fit(X_train, y_train)

Per pescare il miglior classificatore ottenuto:

best_classifier = bayes_cv.best_estimator_
validation_error = 1 - best_classifier.score(X_val, y_val)

Ora su best_classifier ci sono tutti iperparametri ottimali trovati grazie l'ottimizzazione bayesiana.

Concludiamo confrontando in termini di performance l'ottimizzazione Bayesiana con un metodo "predefinito" per lo stesso concetto ad esempio usando Python e TensorFlow:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits

# dataset
digits = load_digits()
X, y = digits.data, digits.target

# set e convalida
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# rete neurale
model = Sequential([
    Dense(30, activation='relu', input_shape=(X_train.shape[1],)),
    Dense(50, activation='relu'),
    Dense(len(set(y)), activation='softmax')  # Numero di classi nel dataset
])

# SGD e errore
model.compile(optimizer=SGD(lr=0.001, momentum=0.9), 
              loss='sparse_categorical_crossentropy', 
              metrics=['accuracy'])

# Addestramento del modello
model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=50, batch_size=32)

Vediamo i risultati:

Configurazione predefinita:

  • Struttura della rete: 2 strati nascosti con 30 e 50 "neuroni" rispettivamente.
  • Velocità di apprendimento iniziale: 0.001
  • Momento SGD: 0.9
  • Forza di regolarizzazione L2: 0.0001

Risultati:

  • Errore di convalida: 0.22
  • Tempo di addestramento: 14232s (quasi 4 ore).

Configurazione con ottimizzazione Bayesiana:

  • Struttura della rete: 3 strati nascosti con 50, 80, e 60 "neuroni" rispettivamente.
  • Velocità di apprendimento iniziale: 0.0005
  • Momento SGD: 0.8
  • Forza di regolarizzazione L2: 0.0002

Risultati:

  • Errore di convalida: 0.18
  • Tempo di addestramento: 5465s (poco più di un ora e mezza).

Possiamo notare che con l'ottimizzazione abbiamo risultati molto inferiori rispetto al metodo "predefinito", e si risparmia molto tempo.
Con l'ottimizzazione abbiamo eseguito una ricerca efficiente degli iperparametri individuando combinazioni migliori in meno tempo.

Powered by: FreeFlarum.
(remove this footer)