Come creare un flusso di lavoro per l’addestramento di modelli di Machine Learning

'Creazione di un flusso di lavoro per l'addestramento di modelli di Machine Learning'

Alza le mani se hai mai perso ore a districare script disordinati o ti sei sentito come se stessi cacciando un fantasma mentre cercavi di risolvere quel bug sfuggente, il tutto mentre i tuoi modelli impiegano un’eternità per addestrarsi. Ci siamo passati tutti, vero? Ma ora, immagina una situazione diversa: Codice pulito. Flussi di lavoro efficienti. Addestramento efficiente del modello. Troppo bello per essere vero? Per niente. Infatti, è esattamente ciò di cui stiamo per parlare. Stiamo per imparare come creare un flusso di lavoro di addestramento dei modelli di apprendimento automatico pulito, mantenibile e completamente riproducibile.

In questa guida, ti fornirò un processo passo-passo per la creazione di un flusso di lavoro di addestramento del modello e condividerò soluzioni pratiche e considerazioni per affrontare sfide comuni nell’addestramento del modello, come:

  • 1
    Creazione di un flusso di lavoro versatile adattabile a diversi ambienti, inclusi ambienti di ricerca e universitari come SLURM.
  • 2
    Creazione di una fonte centralizzata di verità per gli esperimenti, favorire la collaborazione e l’organizzazione.
  • 3
    Integrazione senza soluzione di continuità dell’ottimizzazione degli iperparametri (HPO) quando necessario.
Flusso di lavoro completo del flusso di addestramento del modello di apprendimento automatico | Fonte 

Ma prima di immergerci nel flusso di lavoro dell’addestramento del modello passo-passo, è essenziale comprendere le basi, l’architettura, le motivazioni, le sfide associate ai flussi di lavoro di ML e alcuni strumenti con cui dovrai lavorare. Quindi iniziamo con una panoramica rapida di tutto ciò.

Perché abbiamo bisogno di un flusso di lavoro di addestramento del modello?

Ci sono diverse ragioni per creare un flusso di lavoro di addestramento del modello di apprendimento automatico (credimi!):

  • Efficienza: I flussi di lavoro automatizzano compiti ripetitivi, riducendo l’intervento manuale e risparmiando tempo.
  • Coerenza: Definendo un flusso di lavoro fisso, i flussi di lavoro garantiscono che le operazioni di preprocessing e di addestramento del modello rimangano coerenti per tutto il progetto, facilitando la transizione dagli ambienti di sviluppo agli ambienti di produzione.
  • Modularità: I flussi di lavoro consentono l’aggiunta, la rimozione o la modifica semplice dei componenti senza interrompere l’intero flusso di lavoro. 
  • Sperimentazione: Con un flusso di lavoro strutturato, è più facile tracciare gli esperimenti e confrontare modelli o algoritmi diversi. Rende le iterazioni di addestramento veloci e affidabili.
  • Scalabilità: I flussi di lavoro possono essere progettati per ospitare grandi set di dati e crescere insieme al progetto.

Architettura del flusso di lavoro di addestramento del modello di apprendimento automatico

Un flusso di lavoro di addestramento del modello di apprendimento automatico è tipicamente composto da diversi componenti o fasi interconnesse. Queste fasi formano un grafo aciclico diretto (DAG) per rappresentare l’ordine di esecuzione. Un flusso di lavoro tipico può includere:

  1. Ingresso dei dati: Il processo inizia con l’ingestione dei dati grezzi da diverse fonti, come database, file o API. Questo passaggio è fondamentale per garantire che il flusso di lavoro abbia accesso a informazioni rilevanti e aggiornate.
  1. Preelaborazione dei dati: I dati grezzi spesso contengono rumore, valori mancanti o incongruenze. La fase di preelaborazione comporta la pulizia, la trasformazione e la codifica dei dati, rendendoli adatti agli algoritmi di apprendimento automatico. Le attività di preelaborazione comuni includono la gestione dei dati mancanti, la normalizzazione e la codifica categorica.
  1. Ingegneria delle caratteristiche: In questa fase, vengono create nuove caratteristiche dai dati esistenti per migliorare le prestazioni del modello. Sono possibili tecniche come la riduzione della dimensionalità, la selezione delle caratteristiche o l’estrazione delle caratteristiche per identificare e creare le caratteristiche più informative per l’algoritmo di apprendimento automatico. La conoscenza aziendale può essere utile in questa fase del flusso di lavoro.
  1. Addestramento del modello: I dati preelaborati vengono alimentati nell’algoritmo di apprendimento automatico scelto per addestrare il modello. Il processo di addestramento comporta l’aggiustamento dei parametri del modello per ridurre una funzione di perdita predefinita, che misura la differenza tra le previsioni del modello e i valori effettivi.
  1. Convalida del modello: Per valutare le prestazioni del modello, viene utilizzato un set di dati di convalida (una porzione dei dati che il modello non ha mai visto). Metriche come l’accuratezza, la precisione, il richiamo o l’F1-score possono essere impiegate per valutare quanto bene il modello generalizza i nuovi dati (non visti) nei problemi di classificazione.
  1. Regolazione degli iperparametri: Gli iperparametri sono i parametri dell’algoritmo di apprendimento automatico che non vengono appresi durante il processo di addestramento, ma vengono impostati prima dell’inizio dell’addestramento. La regolazione degli iperparametri comporta la ricerca del set ottimale di valori che minimizzano l’errore di convalida e aiutano a ottenere le migliori prestazioni possibili del modello.

Strumenti per il flusso di lavoro di addestramento del modello

Esistono varie opzioni per implementare flussi di lavoro di addestramento, ognuna con le proprie caratteristiche, vantaggi e casi d’uso. Quando si sceglie un’opzione per il flusso di lavoro di addestramento, bisogna considerare fattori come la scala, la complessità e i requisiti del progetto, così come la familiarità con gli strumenti e le tecnologie.

In questa sezione, esploreremo alcune opzioni comuni per i flussi di lavoro, inclusi le librerie integrate, i flussi di lavoro personalizzati e le piattaforme end-to-end.

  1. Librerie integrate: Molte librerie di machine learning offrono il supporto integrato per la creazione di flussi di lavoro. Ad esempio, Scikit-learn, una popolare libreria Python, offre la classe Pipeline per semplificare la pre-elaborazione e l’addestramento del modello. Questa opzione è vantaggiosa per progetti più piccoli o quando si è già familiari con una libreria specifica.
  2. Flussi di lavoro personalizzati: In alcuni casi, potrebbe essere necessario creare un flusso di lavoro personalizzato adattato ai requisiti unici del progetto. Ciò può comportare la scrittura di script Python personalizzati o l’utilizzo di librerie generiche come Kedro o MetaFlow. I flussi di lavoro personalizzati offrono la flessibilità per gestire fonti di dati specifiche, passaggi di pre-elaborazione o scenari di distribuzione specifici.
  3. Piattaforme end-to-end: Per progetti di grandi dimensioni o complessi, le piattaforme di machine learning end-to-end possono essere vantaggiose. Queste piattaforme forniscono soluzioni complete per la creazione, distribuzione e gestione dei flussi di lavoro di machine learning, spesso incorporando funzionalità come la versioning dei dati, il tracciamento degli esperimenti e il monitoraggio del modello. Alcune piattaforme end-to-end popolari includono:
  • TensorFlow Extended (TFX): Una piattaforma end-to-end sviluppata da Google, TFX offre una suite di componenti per la creazione di flussi di lavoro di machine learning pronti per la produzione con TensorFlow.
  • Kubeflow Pipelines: Kubeflow è una piattaforma open-source progettata per essere eseguita su Kubernetes, fornendo flussi di lavoro di machine learning scalabili e riproducibili. Kubeflow Pipelines offre una piattaforma per la creazione, distribuzione e gestione di flussi di lavoro di machine learning complessi con facilità.
  • MLflow: Sviluppato da Databricks, MLflow è una piattaforma open-source che semplifica il ciclo di vita del machine learning. Offre strumenti per la gestione degli esperimenti, la riproducibilità e la distribuzione dei modelli di machine learning.
  • Apache Airflow: Sebbene non sia progettato esclusivamente per il machine learning, Apache Airflow è una piattaforma popolare per la gestione dei flussi di lavoro che può essere utilizzata per creare e gestire flussi di lavoro di machine learning. Airflow offre una soluzione scalabile per orchestrare flussi di lavoro, consentendo di definire compiti, dipendenze e pianificazioni utilizzando script Python.

Anche se esistono varie opzioni per la creazione di un flusso di lavoro, la maggior parte di esse non offre un modo integrato per monitorare il flusso di lavoro/i modelli e registrare gli esperimenti. Per affrontare questo problema, si può considerare di collegare uno strumento flessibile di tracciamento degli esperimenti alla propria configurazione di addestramento del modello esistente. Questo approccio offre una maggiore visibilità e capacità di debug con un minimo sforzo aggiuntivo.

Nella prossima sezione, costruiremo qualcosa di simile a questo.

Sfide nella creazione di flussi di lavoro di addestramento del modello

Nonostante i vantaggi, ci sono alcune sfide nella creazione di un flusso di lavoro di addestramento di modelli di machine learning:

  • Complessità: Progettare un flusso di lavoro richiede la comprensione delle dipendenze tra i componenti e la gestione di flussi di lavoro complessi.
  • Selezione degli strumenti: La scelta degli strumenti e delle librerie giuste può essere difficile a causa del vasto numero di opzioni disponibili.
  • Integrazione: Combinare diversi strumenti e tecnologie può richiedere soluzioni personalizzate o adattatori, che possono richiedere tempo per essere sviluppati.
  • Debugging: Identificare e risolvere problemi all’interno di un flusso di lavoro può essere difficile a causa della natura interconnessa dei componenti.

Come costruire un flusso di lavoro di addestramento di modelli di machine learning?

In questa sezione, illustreremo passo dopo passo un tutorial su come costruire un flusso di lavoro di addestramento di modelli di machine learning. Utilizzeremo Python e il popolare Scikit-learn. Successivamente utilizzeremo Optuna per ottimizzare gli iperparametri del modello e infine utilizzeremo neptune.ai per registrare i tuoi esperimenti.

Per ogni passaggio del tutorial, spiegherò cosa viene fatto e suddividerò il codice per rendere più facile la comprensione. Questo codice seguirà le migliori pratiche di machine learning, il che significa che sarà ottimizzato e completamente riproducibile. Inoltre, in questo esempio, sto utilizzando un dataset statico, quindi non eseguirò alcuna operazione come l’ingestione dei dati e l’ingegneria delle caratteristiche.

Cominciamo!

1. Installa e importa le librerie necessarie.

  • In questo passaggio, vengono installate le librerie necessarie per il progetto, come NumPy, pandas, scikit-learn, Optuna e Neptune. Successivamente, queste librerie vengono importate nello script, rendendo le loro funzioni e classi disponibili per l’uso nel tutorial.

Installa i pacchetti Python richiesti utilizzando pip.

pip install --quiet numpy==1.22.4 optuna==3.1.0 pandas==1.4.4 scikit-learn==1.2.2 neptune-client==0.16.16

Importa le librerie necessarie per la manipolazione dei dati, la preelaborazione, l’addestramento del modello, la valutazione, l’ottimizzazione degli iperparametri e il logging.

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, StratifiedKFold, cross_val_score
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import optuna
from functools import partial
import neptune.new as neptune

2. Inizializza l’esecuzione di Neptune e collegati al tuo progetto.

  • Qui, inizializziamo una nuova esecuzione in Neptune, collegandola a un progetto Neptune. Ciò ci consente di registrare i dati sperimentali e monitorare i tuoi progressi.

Dovrai sostituire i valori segnaposto con il tuo token API e il nome del progetto.

run = neptune.init_run(api_token='tuo_token_api', project='nome_utente/nome_progetto')

3. Carica il dataset.

  • In questo passaggio, carichiamo il dataset del Titanic da un file CSV in un DataFrame di pandas. Questo dataset contiene informazioni sui passeggeri del Titanic, inclusa la loro sopravvivenza.
data = pd.read_csv("train.csv")

4. Esegui una preelaborazione di base, come l’eliminazione delle colonne non necessarie.

  • Qui, eliminiamo le colonne non rilevanti per il modello di apprendimento automatico, come PassengerId, Name, Ticket e Cabin. Ciò semplifica il dataset e riduce il rischio di overfitting.
data = data.drop(["PassengerId", "Name", "Ticket", "Cabin"], axis=1)

5. Suddividi i dati in caratteristiche e etichette.

  • Suddividiamo il dataset in input features (X) e l’etichetta target (y). Le input features sono le variabili indipendenti che il modello utilizzerà per fare previsioni, mentre l’etichetta target è la colonna “Survived”, che indica se un passeggero è sopravvissuto al disastro del Titanic.
X = data.drop("Survived", axis=1)

y = data["Survived"]

6. Suddividi i dati in set di addestramento e di test.

  • Suddividi i dati in set di addestramento e di test utilizzando la funzione train_test_split di scikit-learn. Ciò assicura che tu abbia dati separati per addestrare il modello e valutarne le prestazioni. Il parametro stratify viene utilizzato per mantenere la proporzione delle classi sia nel set di addestramento che in quello di test.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

7. Definisci le operazioni di preelaborazione.

  • Creamo un ColumnTransformer che preelabora separatamente le feature numeriche e categoriche.
  • Le feature numeriche vengono preelaborate utilizzando una pipeline che interpola i valori mancanti con la media e scalano i dati utilizzando la standardizzazione.
  • Le feature categoriche vengono preelaborate utilizzando una pipeline che interpola i valori mancanti con la categoria più frequente e le codifica utilizzando l’one-hot encoding.
numerical_features = ["Age", "Fare"]
categorical_features = ["Pclass", "Sex", "Embarked"]

num_pipeline = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='mean')),
    ('scaler', StandardScaler())
])

cat_pipeline = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('encoder', OneHotEncoder())
])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', num_pipeline, numerical_features),
        ('cat', cat_pipeline, categorical_features)
    ],
    remainder='passthrough'
)

8. Crea il modello di apprendimento automatico.

  • In questo passaggio, creiamo un modello RandomForestClassifier da scikit-learn. Questo è un metodo di apprendimento ensemble che costruisce più alberi decisionali e combina le loro previsioni per migliorare l’accuratezza e ridurre l’overfitting.
model = RandomForestClassifier(random_state=42)

9. Costruire il pipeline.

  • Creamo un oggetto Pipeline che include le operazioni di preprocessing definite al passaggio 7 e il modello creato al passaggio 8.
  • Il pipeline automatizza l’intero processo di preprocessing dei dati e addestramento del modello, rendendo il flusso di lavoro più efficiente e più facile da mantenere.
pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', model)
])

10. Eseguire la cross-validazione utilizzando StratifiedKFold.

  • Eseguiamo la cross-validazione utilizzando il metodo StratifiedKFold, che suddivide i dati di addestramento in K fold, mantenendo la proporzione delle classi in ogni fold.
  • Il modello viene addestrato K volte, utilizzando K-1 fold per l’addestramento e un fold per la validazione. Questo fornisce una stima più robusta delle prestazioni del modello.
  • Salviamo ciascuno dei punteggi e la media nella nostra esecuzione Neptune.
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

cv_scores = cross_val_score(pipeline, X_train, y_train, cv=cv, scoring='accuracy')

run["cross_val_accuracy_scores"] = cv_scores

run["mean_cross_val_accuracy_scores"] = np.mean(cv_scores)

11. Addestrare il pipeline sull’intero set di addestramento.

  • Addestriamo il modello attraverso questo pipeline, utilizzando l’intero set di dati di addestramento.
pipeline.fit(X_train, y_train)

Ecco una panoramica di ciò che abbiamo creato.

Flusso di lavoro del pipeline di addestramento del modello realizzato sull’esempio | Fonte: Autore

12. Valutare il pipeline con più metriche.

  • Valutiamo il pipeline sul set di test utilizzando varie metriche di prestazione, come l’accuratezza, la precisione, il richiamo e il punteggio F1. Queste metriche forniscono una visione completa delle prestazioni del modello e possono aiutare a identificare aree di miglioramento.
  • Salviamo ciascuno dei punteggi nella nostra esecuzione Neptune.
y_pred = pipeline.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

run["accuracy"] = accuracy
run["precision"] = precision
run["recall"] = recall
run["f1"] = f1

13. Definire lo spazio di ricerca degli iperparametri utilizzando Optuna.

  • Creiamo una funzione obiettivo che riceve un trial e addestra e valuta il modello in base agli iperparametri campionati durante il trial.
  • La funzione obiettivo è il cuore del processo di ottimizzazione. Prende l’oggetto trial, che contiene i valori degli iperparametri campionati da Optuna, e addestra il pipeline con questi iperparametri. Il punteggio di accuratezza convalidato incrociato viene quindi restituito come valore obiettivo da ottimizzare.
def objective(X_train, y_train, pipeline, cv, trial: optuna.Trial):
    params = {
        'classifier__n_estimators': trial.suggest_int('classifier__n_estimators', 10, 200),
        'classifier__max_depth': trial.suggest_int('classifier__max_depth', 10, 50),
        'classifier__min_samples_split': trial.suggest_int('classifier__min_samples_split', 2, 10),
        'classifier__min_samples_leaf': trial.suggest_int('classifier__min_samples_leaf', 1, 5),
        'classifier__max_features': trial.suggest_categorical('classifier__max_features', ['auto', 'sqrt'])
    }
    
    pipeline.set_params(**params)
    
    scores = cross_val_score(pipeline, X_train, y_train, cv=cv, scoring='accuracy', n_jobs=-1)
    mean_score = np.mean(scores)
    
    return mean_score

Se hai trovato il codice sopra travolgente, ecco una rapida spiegazione:

  • Definisci gli iperparametri utilizzando i metodi trial.suggest_*. Questi metodi indicano a Optuna lo spazio di ricerca per ciascun iperparametro. Ad esempio, trial.suggest_int(‘classifier__n_estimators’, 10, 200) specifica uno spazio di ricerca intero per il parametro n_estimators, compreso tra 10 e 200.
  • Imposta gli iperparametri del pipeline utilizzando il metodo pipeline.set_params(**params). Questo metodo prende il dizionario params che contiene gli iperparametri campionati e li imposta per il pipeline.
  • Calcola il punteggio di accuratezza con validazione incrociata utilizzando la funzione cross_val_score. Questa funzione addestra ed valuta il pipeline utilizzando la validazione incrociata con l’oggetto cv specificato e la metrica di valutazione (in questo caso, ‘accuratezza’).
  • Calcola la media dei punteggi di validazione incrociata utilizzando np.mean(scores) e restituisce questo valore come valore oggetto da massimizzare da Optuna.

14. Esegui la messa a punto degli iperparametri con Optuna.

  • Creiamo uno studio con una direzione specificata (massimizzare) e un campionatore (campionatore TPE).
  • Successivamente, chiamiamo study.optimize con la funzione oggetto, il numero di prove e qualsiasi altra opzione desiderata.
  • Optuna eseguirà più prove, ognuna con valori di iperparametri diversi, per trovare la migliore combinazione che massimizza la funzione obiettivo (punteggio medio di accuratezza con validazione incrociata).
study = optuna.create_study(direction="massimizzare", sampler=optuna.samplers.TPESampler(seed=42))

study.optimize(partial(objective, X_train, y_train, pipeline, cv), n_trials=50, timeout=None, gc_after_trial=True)

15. Imposta i migliori parametri e addestra il pipeline.

  • Dopo che Optuna ha trovato i migliori iperparametri, impostiamo questi parametri nel pipeline e lo riaddestriamo utilizzando l’intero set di dati di addestramento. Ciò garantisce che il modello venga addestrato con gli iperparametri ottimizzati.
pipeline.set_params(**study.best_trial.params)

pipeline.fit(X_train, y_train)

16. Valuta il miglior modello con più metriche.

  • Valutiamo le prestazioni del modello ottimizzato sul set di test utilizzando le stesse metriche di prestazione di prima (accuratezza, precisione, richiamo e punteggio F1). Ciò consente di confrontare le prestazioni del modello ottimizzato con il modello iniziale.
  • Salviamo ciascuno dei punteggi del modello ottimizzato nella nostra esecuzione Neptune.
y_pred = pipeline.predict(X_test)
accuratezza = accuracy_score(y_test, y_pred)
precisione = precision_score(y_test, y_pred)
richiamo = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

run["accuratezza_ottimizzata"] = accuratezza
run["precisione_ottimizzata"] = precisione
run["richiamo_ottimizzato"] = richiamo
run["f1_ottimizzato"] = f1

  • Se esegui questo codice e guardi solo le prestazioni di queste metriche, potresti pensare che il modello ottimizzato sia peggiore rispetto a prima. Tuttavia, se guardi il punteggio medio con validazione incrociata, un modo più robusto per valutare il tuo modello, ti renderai conto che il modello ottimizzato si comporta bene sull’intero set di dati, rendendolo più affidabile.

17. Registra gli iperparametri, i migliori parametri della prova e il miglior punteggio su Neptune.

  • Registriamo i migliori parametri della prova e il relativo miglior punteggio su Neptune, consentendoti di tenere traccia dei progressi e dei risultati del tuo esperimento.
run['parametri'] = study.best_trial.params
run['migliore_prova'] = study.best_trial.number
run['miglior_punteggio'] = study.best_value

18. Registra il report di classificazione e la matrice di confusione.

  • Registriamo il report di classificazione e la matrice di confusione del modello, fornendo una visione dettagliata delle prestazioni del modello per ogni classe. Ciò può aiutarti a identificare aree in cui il modello potrebbe essere sub-ottimale e a guidare ulteriori miglioramenti.
from sklearn.metrics import classification_report, confusion_matrix

y_pred = pipeline.predict(X_test)

# Registra il report di classificazione
report = classification_report(y_test, y_pred, output_dict=True)
for label, metrics in report.items():
    if isinstance(metrics, dict):
        for metric, value in metrics.items():
            run[f'report_classificazione/{label}/{metric}'] = value
    else:
        run[f'report_classificazione/{label}'] = metrics

# Registra la matrice di confusione
conf_mat = confusion_matrix(y_test, y_pred)
conf_mat_plot = px.imshow(conf_mat, labels=dict(x="Predizione", y="Target"), x=[x+1 for x in range(len(conf_mat[0]))], y=[x+1 for x in range(len(conf_mat[0]))])
run['matrice_confusione'].upload(neptune.types.File.as_html(conf_mat_plot))

19. Registrare il pipeline come file pickle.

  • Salva il pipeline come file pickle e caricalo su Neptune. Ciò ti permette di condividere, riutilizzare e distribuire facilmente il modello addestrato.
import joblib

joblib.dump(pipeline, 'optimized_pipeline.pkl')
run['optimized_pipeline'].upload(neptune.types.File.as_pickle('optimized_pipeline.pkl'))

20. Interrompi l’esecuzione di Neptune.

  • Infine, interrompi l’esecuzione di Neptune, segnalando che l’esperimento è completo. Ciò assicura che tutti i dati siano salvati e tutte le risorse siano liberate.
run.stop()

Ecco un dashboard che puoi creare usando Neptune. Come puoi vedere, contiene informazioni sul nostro modello (iperparametri), metriche del report di classificazione e la matrice di confusione.

Il dashboard generale in Neptune con i dati di esempio dell’esperimento registrato | Gioca con questo progetto in tempo reale

Per dimostrare la potenza di utilizzare uno strumento come Neptune per tracciare e confrontare i tuoi esperimenti di addestramento, abbiamo creato un’altra esecuzione modificando il parametro di valutazione in ‘recall’ nella funzione obiettivo di Optuna. Ecco un confronto tra entrambe le esecuzioni.

La funzione di confronto tra esecuzioni in Neptune | Gioca con questo progetto in tempo reale

Tale confronto ti permette di avere tutto in un unico posto e prendere decisioni informate in base alle prestazioni di ogni iterazione del pipeline.

Se sei arrivato fin qui, probabilmente hai implementato il pipeline di addestramento con tutti gli accessori necessari.

Questo esempio particolare ha mostrato come uno strumento di monitoraggio degli esperimenti può essere integrato nel tuo pipeline di addestramento, offrendo una visione personalizzata per il tuo progetto e aumentando la produttività.

Se sei interessato a replicare questo approccio, puoi esplorare soluzioni come la combinazione di Kedro e Neptune, che funzionano bene insieme per creare e monitorare i pipeline. Qui puoi trovare esempi e documentazione su come utilizzare Kedro con Neptune.

Per riassumere tutto, ecco un piccolo diagramma di flusso di tutti i passaggi che abbiamo seguito per creare e ottimizzare il nostro pipeline e monitorare le metriche generate da esso. Indipendentemente dal problema che stai cercando di risolvere, i passaggi principali rimangono gli stessi in qualsiasi esercizio simile.

Passaggi per creare e ottimizzare il pipeline di addestramento del modello e monitorare le metriche generate da esso | Fonte: Autore

Addestrare il tuo modello di machine learning in modo distribuito

Fino ad ora, abbiamo parlato di come creare un pipeline per addestrare il tuo modello, ma cosa succede se stai lavorando con grandi dataset o modelli complessi, in tal caso potresti voler considerare l’Addestramento Distribuito.

Distribuendo il processo di addestramento su più dispositivi, puoi velocizzare significativamente il processo di addestramento e renderlo più efficiente. In questa sezione, toccheremo brevemente il concetto di addestramento distribuito e come puoi incorporarlo nel tuo pipeline.

  1. Scegli un framework di addestramento distribuito: Ci sono diversi framework di addestramento distribuito disponibili, come tf.distribute di TensorFlow, torch.distributed di PyTorch o Horovod. Scegli quello compatibile con la tua libreria di machine learning e che meglio si adatta alle tue esigenze.
  1. Configura il tuo cluster locale: Per addestrare il tuo modello su un cluster locale, devi configurare correttamente le risorse di calcolo. Ciò include la configurazione di una rete di dispositivi (come GPU o CPU) e assicurarsi che possano comunicare in modo efficiente.
  1. Adatta il tuo codice di addestramento: Modifica il tuo codice di addestramento esistente per utilizzare il framework di addestramento distribuito scelto. Ciò potrebbe comportare modifiche al modo in cui inizializzi il tuo modello, gestisci il caricamento dei dati o esegui gli aggiornamenti del gradiente.
  1. Monitora e gestisci il processo di addestramento distribuito: Tieni traccia delle prestazioni e dell’utilizzo delle risorse del processo di addestramento distribuito. Ciò può aiutarti a identificare punti critici, assicurare un utilizzo efficiente delle risorse e mantenere la stabilità durante l’addestramento.

Anche se questo argomento va al di là del campo di questo articolo, è essenziale essere consapevoli delle complessità e delle considerazioni del training distribuito quando si costruiscono pipeline di training di modelli di machine learning, nel caso in cui si voglia avvicinarsi ad esso in futuro. Per incorporare in modo efficace il training distribuito nelle pipeline di training dei modelli di machine learning, ecco alcune risorse utili:

  1. Per gli utenti di TensorFlow: Training distribuito con TensorFlow
  2. Per gli utenti di PyTorch: Introduzione a Distributed Data Parallel
  3. Per gli utenti di Horovod: Documentazione ufficiale di Horovod
  4. Per una panoramica generale: Guida di Neptune al Training Distribuito per Data Scientist
  5. Se hai intenzione di lavorare con il training distribuito su una piattaforma cloud specifica, assicurati di consultare i tutorial pertinenti disponibili nella documentazione della piattaforma.

Queste risorse ti aiuteranno a migliorare le tue pipeline di training dei modelli di machine learning sfruttando il potere del training distribuito.

Migliori pratiche da considerare nella costruzione delle pipeline di training dei modelli

Una pipeline di training ben progettata garantisce riproducibilità e manutenibilità durante tutto il processo di machine learning. In questa sezione, esploreremo alcune delle migliori pratiche per creare pipeline efficaci, efficienti e facilmente adattabili per diversi progetti.

  • Suddividi i tuoi dati prima di qualsiasi manipolazione: È fondamentale suddividere i tuoi dati in set di training e di test prima di effettuare qualsiasi preprocessamento o ingegneria delle caratteristiche. Ciò garantisce che la valutazione del tuo modello sia imparziale e che non stai involontariamente divulgando informazioni dal set di test al set di training, il che potrebbe portare a stime di prestazioni eccessivamente ottimistiche.
  • Separare il preprocessamento dei dati, l’ingegneria delle caratteristiche e le fasi di training del modello: Scomporre la pipeline in queste fasi distinte rende il codice più facile da capire, mantenere e modificare. Questa modularità ti consente di cambiare o estendere facilmente una parte della pipeline senza influire sulle altre.
  • Utilizza la cross-validation per valutare le prestazioni del modello: La cross-validation ti aiuta a ottenere una stima migliore delle prestazioni del tuo modello su dati non visti in precedenza. Suddividendo i dati di training in più fold e addestrando ed valutando iterativamente il modello su diverse combinazioni di questi fold, puoi ottenere una stima più accurata e affidabile delle vere prestazioni del modello.
  • Stratifica i tuoi dati durante la suddivisione tra training e test e la cross-validation: La stratificazione assicura che ogni suddivisione o fold abbia una distribuzione simile della variabile target, il che aiuta a mantenere un campione più rappresentativo dei dati per l’addestramento e la valutazione. Questo è particolarmente importante quando si lavora con dataset sbilanciati, poiché la stratificazione aiuta a evitare di creare suddivisioni con pochissimi esempi della classe minoritaria.
  • Utilizza un seed casuale coerente per la riproducibilità: Impostando un seed casuale coerente nel tuo codice, ti assicuri che la generazione di numeri casuali utilizzata nella tua pipeline sia la stessa ogni volta che viene eseguito il codice. Ciò rende i tuoi risultati riproducibili e più facili da debuggare, oltre a consentire ad altri ricercatori di riprodurre i tuoi esperimenti e convalidare le tue scoperte.
  • Ottimizza gli iperparametri utilizzando un metodo di ricerca: Il tuning degli iperparametri è un passaggio essenziale per migliorare le prestazioni del tuo modello. La ricerca a griglia, la ricerca casuale e l’ottimizzazione bayesiana sono metodi comuni per esplorare lo spazio di ricerca degli iperparametri e trovare la migliore combinazione di iperparametri per il tuo modello. Optuna è una potente libreria che può essere utilizzata per l’ottimizzazione degli iperparametri.
  • Utilizza un sistema di controllo delle versioni e registra gli esperimenti: I sistemi di controllo delle versioni come Git ti aiutano a tenere traccia delle modifiche nel tuo codice, facilitando la collaborazione con gli altri e il ripristino delle versioni precedenti se necessario. Gli strumenti di tracciamento degli esperimenti come Neptune ti aiutano a registrare e visualizzare i risultati dei tuoi esperimenti, tenere traccia dell’evoluzione delle prestazioni del modello e confrontare diversi modelli e impostazioni degli iperparametri.
  • Documenta la tua pipeline e i risultati: Una buona documentazione rende il tuo lavoro più accessibile agli altri e ti aiuta a comprendere meglio il tuo stesso lavoro. Scrivi commenti chiari e concisi nel tuo codice, spiegando lo scopo di ogni passaggio e funzione. Utilizza strumenti come Jupyter Notebooks, Markdown o anche commenti nel codice per documentare la tua pipeline, metodologia e risultati.
  • Automatizza le attività ripetitive: Utilizza scripting e strumenti di automazione per semplificare attività ripetitive come il preprocessamento dei dati, l’ingegneria delle caratteristiche e il tuning degli iperparametri. Questo ti permette di risparmiare tempo e ridurre il rischio di errori e inconsistenze nella tua pipeline.
  • Testa la tua pipeline: Scrivi test unitari per assicurarti che la tua pipeline funzioni come previsto e per individuare errori prima che si propaghino in tutta la pipeline. Questo può aiutarti a identificare problemi in modo tempestivo e mantenere un codice di alta qualità.
  • Rivedi e ottimizza periodicamente il tuo pipeline durante l’addestramento: Man mano che i tuoi dati evolvono o il tuo dominio del problema cambia, è cruciale rivedere il tuo pipeline per garantirne prestazioni ed efficacia. Questo approccio proattivo mantiene il tuo pipeline attuale e adattabile, mantenendo la sua efficienza di fronte a dati in continua evoluzione e domini dei problemi.

Conclusioni

In questo tutorial, abbiamo coperto i componenti essenziali per la costruzione di un pipeline di addestramento di machine learning utilizzando Scikit-learn e altri strumenti utili come Optuna e Neptune. Abbiamo dimostrato come preelaborare i dati, creare un modello, eseguire la cross-validazione, ottimizzare gli iperparametri e valutare le prestazioni del modello sul dataset Titanic. Registrando i risultati su Neptune, puoi facilmente tenere traccia e confrontare i tuoi esperimenti per migliorare ulteriormente i tuoi modelli.

Seguendo queste linee guida e le migliori pratiche, puoi creare pipeline efficienti, mantenibili e adattabili per i tuoi progetti di Machine Learning. Che tu stia lavorando con il dataset Titanic o qualsiasi altro dataset, questi principi ti aiuteranno a razionalizzare il processo e garantire la riproducibilità tra diverse iterazioni del tuo lavoro.