Come distribuire un modello di apprendimento automatico?
Negli ultimi anni, l’apprendimento automatico e l’intelligenza artificiale hanno guadagnato una notevole popolarità. Ciò è probabilmente dovuto ai progressi nell’elaborazione del linguaggio naturale e nei sistemi di raccomandazione.
Questo articolo introduce l’apprendimento automatico, le sue applicazioni, le opzioni di distribuzione e dimostra come distribuire un semplice modello di apprendimento automatico su Back4app Containers.
Contents
- 1 Che cos’è l’apprendimento automatico?
- 2 Applicazioni di apprendimento automatico
- 3 Opzioni di distribuzione dell’apprendimento automatico
- 4 Algoritmi di apprendimento automatico più diffusi
- 5 Come distribuire un modello di apprendimento automatico?
- 6 Sintesi
Che cos’è l’apprendimento automatico?
L’apprendimento automatico è un sottocampo dell’intelligenza artificiale. Il suo fulcro è l’utilizzo di algoritmi statistici per imparare dai dati e fare previsioni su nuovi dati non visti.
In altre parole, dà ai computer la capacità di apprendere senza essere esplicitamente programmati.
Sebbene l’apprendimento automatico e l’intelligenza artificiale siano spesso usati in modo intercambiabile, non sono la stessa cosa.
L’apprendimento automatico si concentra su algoritmi e strutture di dati, mentre l’intelligenza artificiale è un tentativo generale di creare macchine in grado di pensare in modo simile all’uomo.
Le tipiche tecniche di apprendimento automatico sono la regressione (previsione di un valore continuo, ad esempio il prezzo di una casa) e la classificazione (previsione di una classe da un insieme finito di classi, ad esempio un genere cinematografico).
In generale, possiamo suddividere l’apprendimento automatico in tre tipi:
- Apprendimento supervisionato: gli algoritmi imparano utilizzando un set di dati etichettati. Ogni esempio nel dataset contiene un’etichetta (o la cosiddetta variabile target). L’algoritmo le utilizza per prevedere le etichette degli esempi non visti. Gli algoritmi di apprendimento supervisionato includono kNN, decision trees, ecc.
- Apprendimento non supervisionato: gli algoritmi imparano senza alcuna guida esplicita. Spetta all’algoritmo trovare schemi nei dati e fare previsioni in base ad essi. Un esempio di algoritmo è il clustering k-means.
- Apprendimento per rinforzo: gli algoritmi imparano per tentativi ed errori. In genere sono basati su una ricompensa e l’obiettivo dell’algoritmo è massimizzare la ricompensa. Esempio: algoritmi genetici.
Nella parte pratica dell’articolo, esamineremo un tipico processo di costruzione di un modello. Risolveremo un compito di classificazione utilizzando l’apprendimento supervisionato.
Applicazioni di apprendimento automatico
Vediamo alcune applicazioni reali dell’apprendimento automatico!
Sistemi di raccomandazione
I sistemi di raccomandazione suggeriscono quali articoli (film, prodotti, ecc.) un utente dovrebbe consumare. Questi sistemi possono essere basati sul contenuto o sulla collaborazione.
Al giorno d’oggi i sistemi di raccomandazione sono utilizzati da quasi tutte le aziende. Consentono alle aziende di incrementare il successo commerciale, creare ulteriore domanda, aumentare il coinvolgimento degli utenti, conoscere i clienti e molto altro ancora.
Netflix, ad esempio, li utilizza per consigliare film, Spotify per consigliare canzoni e YouTube per suggerire video da guardare in base ai propri interessi.
Elaborazione del linguaggio naturale (NLP)
L’elaborazione del linguaggio naturale (NLP) consente ai computer di elaborare e comprendere il linguaggio umano. La generazione del linguaggio naturale (NLG) consente ai computer di generare il linguaggio umano.
Questa tecnologia è utilizzata da chatbot, strumenti di traduzione linguistica, strumenti di analisi del sentiment e altro ancora. ChatGPT è uno degli esempi più famosi di utilizzo di NLP e NLG.
Volete saperne di più su ChatGPT? Date un’occhiata al nostro altro articolo intitolato Come creare un’app usando ChatGPT?
Visione artificiale e riconoscimento delle immagini
La computer vision conferisce ai computer la capacità di “vedere” e “capire” immagini e video. Permette di eseguire la segmentazione (in tempo reale), di riconoscere oggetti, volti e persino emozioni.
È la tecnologia utilizzata dalle app fotografiche per taggare automaticamente gli amici. Inoltre, viene utilizzata dai sistemi di sorveglianza per rilevare comportamenti sospetti.
Rilevamento delle frodi
Le aziende utilizzano l’apprendimento automatico per rilevare attività sospette nelle transazioni o nel comportamento degli utenti. Questi sistemi possono rilevare atti potenzialmente fraudolenti studiando le tendenze e le anomalie, proteggendo le aziende e i clienti da frodi e crimini informatici.
Auto a guida autonoma
La guida autonoma di un’auto è uno dei problemi di apprendimento automatico più complicati. Combina diverse applicazioni come la computer vision, il rilevamento di anomalie, la previsione del comportamento, la pianificazione del percorso, ecc.
Al momento in cui scriviamo, non siamo affatto vicini alle auto completamente autonome. Le attuali auto “a guida autonoma” funzionano bene solo in aree geografiche ristrette.
Opzioni di distribuzione dell’apprendimento automatico
Per distribuire un modello di apprendimento automatico, di solito lo si serve da un’applicazione web. Pertanto, le opzioni di distribuzione dei modelli di apprendimento automatico sono praticamente le stesse di quelle delle applicazioni web. Vediamole!
In sede
L’implementazione on-premise comporta l’hosting e la gestione di apparecchiature IT, come server e dispositivi di archiviazione, presso la sede effettiva di un’azienda.
Questa strategia tradizionale richiede un notevole investimento iniziale in hardware e software e una manutenzione e un’assistenza continue.
I suoi vantaggi includono un livello più elevato di controllo e sicurezza e una personalizzazione più accessibile. D’altro canto, gli aspetti negativi sono il costo, la scalabilità e la manutenzione.
Nuvola
Al contrario, la distribuzione in cloud impiega servizi di terze parti per ospitare infrastrutture e applicazioni via Internet.
Questo modello consente agli utenti di pagare a consumo per risorse e servizi scalabili, gestiti dai fornitori di servizi cloud.
I vantaggi sono la scalabilità, la facilità d’uso e l’assenza di costi iniziali. D’altro canto, gli svantaggi sono un livello di controllo inferiore, una minore flessibilità e un possibile vendor lock-in.
Esempi di piattaforme basate sul cloud sono
- Back4app
- Amazon Web Services (AWS)
- Google Cloud Platform (GCP)
- Microsoft Azure
Algoritmi di apprendimento automatico più diffusi
Gli algoritmi di apprendimento automatico più diffusi sono:
- k-Nearest Neighbours (kNN)
- Decision Trees & Random Forests
- Support Vector Machines (SVM)
- Linear Regression
- Naive Bayes
- K-means
Nell’esempio pratico, utilizzeremo k-Nearest Neighbours.
Come distribuire un modello di apprendimento automatico?
In questa sezione dell’articolo, costruiremo un modello di apprendimento automatico, lo serviremo con FastAPI, lo dockerizzeremo e infine lo distribuiremo su Back4app Containers.
Prerequisiti
- Conoscenza di base dell’apprendimento automatico
- Esperienza con Python e FastAPI
- Conoscenza di base di Docker e della tecnologia di containerizzazione
- Git e Docker Desktop installati sulla macchina locale
Panoramica del progetto
Prima di dimostrare come distribuire un modello di apprendimento automatico, ne costruiremo uno. Creeremo un semplice classificatore kNN utilizzando il popolare set di dati Iris. Lo scopo del modello sarà quello di prevedere se un’osservazione è “setosa”, “versicolore” o “virginica” in base a diverse caratteristiche.
Salveremo quindi il modello in un file, lo caricheremo in FastAPI e lo serviremo tramite un endpoint. Dopodiché, dockerizzeremo l’applicazione, la invieremo a GitHub e la distribuiremo su Back4app Containers.
Creare il modello
Per creare il modello, utilizzeremo i Jupyter Notebooks. È possibile installare Jupyter sul proprio computer locale o utilizzare gratuitamente Google Colab.
Creare innanzitutto un nuovo blocco note Jupyter.
Ogni blocco di codice in questa sezione dell’articolo rappresenta una cella Jupyter. È possibile crearle dal menu o utilizzando la combinazione di tasti “B” (in modalità comando).
Inoltre, non dimenticate di eseguirli (dal menu o con “ALT + INVIO”).
Aggiungete le seguenti importazioni nella prima cella:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from joblib import dump
Caricare il set di dati
Il set di dati Iris è incluso in Scikit-learn per impostazione predefinita. È sufficiente richiamare la funzione load_iris()
e trasformare l’oggetto in un frame.
Creare una nuova cella:
df = load_iris(as_frame=True)["data"]
df["target"] = load_iris(as_frame=True)["target"]
Quando si carica il dataset Iris, questo viene ordinato in base alla variabile target. Questo non è un bene perché il nostro modello di apprendimento automatico potrebbe vedere solo alcuni tipi di esempi nella fase di addestramento. Ad esempio, solo “setosa” e “versicolore”.
Per evitare questo problema, possiamo mescolarli:
df = df.sample(frac=1, random_state=42)
L’attributo
random_state
è utilizzato per la riproducibilità. È possibile utilizzare un numero a piacere.
Esplora il set di dati
Prima di creare un modello, è bene esplorare i dati con cui si ha a che fare. Per farlo, si possono usare le funzioni integrate di Pandas, come head()
, describe()
e così via.
# Displays the first five rows of the dataset
df.head(5)
# Generates descriptive statistics
df.describe()
Inoltre, è necessario visualizzare il set di dati per capire quali caratteristiche separano meglio gli esempi e quale algoritmo di apprendimento automatico potrebbe essere utile per il problema.
L’immagine qui sopra è stata presa in prestito dall’articolo Guide to Data Visualization with Python. Assicuratevi di consultarlo per saperne di più sulla visualizzazione dei dati.
L’immagine mostra che i punti “rossi” sono linearmente separabili dagli altri due. I punti “blu” e “verdi”, invece, non sono linearmente separabili.
Set di dati diviso
Procediamo con la definizione delle caratteristiche (predittori) e della variabile target:
features = [
"sepal length (cm)", "sepal width (cm)", "petal length (cm)", "petal width (cm)"
]
target = "target"
Quindi li estrae in X
(dati delle caratteristiche) e y
(dati della variabile target) e li divide in test-training:
X = df[features].values
y = df[target].values
dev_X, test_X, dev_y, test_y = train_test_split(X, y, test_size=0.25, random_state=42)
Utilizzando test_size=0,25
, il 25% del dataset viene utilizzato per i test, mentre il 75% viene utilizzato per l’addestramento.
Modello di costruzione
Quindi, si crea una pipeline che prima scala i dati e poi utilizza il classificatore kNN:
knn = Pipeline(steps=[
("scaler", StandardScaler()),
("predictor", KNeighborsClassifier()),
])
knn.fit(dev_X, dev_y)
Per sapere perché il ridimensionamento è essenziale, consultate questo articolo.
Quindi utilizzare la convalida incrociata a 10 volte e verificare l’errore di convalida:
cross_val_score(knn, dev_X, dev_y, cv=10, scoring="accuracy").mean()
# 0.9363636363636362
Valutare il modello sul set di test:
accuracy_score(test_y, knn.predict(test_X))
# 0.9736842105263158
L’accuratezza della validazione e quella del test sono praticamente uguali. Ciò indica che il nostro modello non è in underfitting o overfitting.
Salva il modello
Infine, riqualificare il modello utilizzando tutti i dati e salvarlo nel file model.pkl:
knn.fit(X, y)
dump(knn, "model.pkl")
Se si utilizzava Google Colab, scaricare il file model.pk, poiché ne avremo bisogno nella fase successiva.
Modello di servizio
Come già detto, useremo FastAPI per servire il modello.
Creare un nuovo progetto FastAPI e sostituire main.py in questo modo:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {
"name": "back4app-deploy-ml-model",
"description": "A FastAPI app serving an ML model",
"version": "1.0.0",
}
Avviare il server di sviluppo:
$ uvicorn app.main:app --reload
Andate all’indirizzo http://localhost:8000/ e dovreste ottenere la seguente risposta:
{
"name": "back4app-deploy-ml-model",
"description": "A FastAPI app serving an ML model",
"version": "1.0.0"
}
Modello di carico
Quindi, carichiamo il modello e definiamo le model_classes
.
Per prima cosa copiate model.pkl dal passo precedente nella radice del progetto. Quindi caricare il modello e definire le classi sotto l’inizializzazione dell’applicazione FastAPI, in questo modo:
# ...
model = load("model.pkl")
model_classes = {
0: "setosa",
1: "versicolor",
2: "virginica",
}
# ...
Useremo model_classes
per tradurre la variabile di destinazione da numerica a testuale.
Modello di carico
Creare quindi l’endpoint /predict
, che riceve le caratteristiche e utilizza il modello caricato per fare una previsione:
# main.py
# ...
class Observation(BaseModel):
"""
A Pydantic model for the observation data.
This is our ML model's input data.
"""
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
@app.post("/predict")
async def predict(observation: Observation):
predictions = model.predict([[
observation.sepal_length,
observation.sepal_width,
observation.petal_length,
observation.petal_width,
]])
prediction = predictions[0]
prediction_class = model_classes[prediction]
return {
"prediction": int(prediction),
"prediction_class": prediction_class,
}
L’endpoint restituisce la previsione numerica e la previsione del test di facile utilizzo.
Non dimenticate le importazioni all’inizio del file:
from joblib import load
from pydantic import BaseModel
Il file main.py finale dovrebbe avere questo aspetto.
Riavviate il server di sviluppo e visitate http://localhost:8000/docs nel vostro browser web preferito. FastAPI genera automaticamente la documentazione interattiva per tutti gli endpoint.
Provate il modello inviando una richiesta come questa:
Ottimo, la nostra web app è ora completamente funzionante!
App Dockerize
In questa sezione dell’articolo, si procederà alla dockerizzazione dell’applicazione web. Creeremo un file Docker e configureremo il file .dockerignore.
Profilo Docker
Un Dockerfile è un file che contiene le istruzioni che Docker Engine deve seguire per costruire l’immagine.
Questi includono tipicamente il trasferimento di file, la definizione dell’immagine di base, la configurazione della directory di lavoro, l’esecuzione di comandi personalizzati e altro ancora.
I comandi di Dockerfile sono solitamente scritti in lettere maiuscole e sono seguiti direttamente dai loro argomenti corrispondenti.
<COMMAND> <arg1> <arg2> ... <arg_n>
# Example
WORKDIR /app
Visitate il riferimento al Dockerfile per saperne di più su tutte le istruzioni.
Nella root del progetto, creare un file Docker:
# Dockerfile
# Set the base image
FROM python:3.12.2-alpine3.19
# Install the required dependencies (gcc)
RUN apk add build-base
# Set the working directory
WORKDIR /app
# Confingure Python using environmental variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Copy the requirements file into the image and install them
COPY ./requirements.txt .
RUN pip install --no-cache-dir --upgrade pip
RUN pip install --no-cache-dir --upgrade -r ./requirements.txt
# Copy the source code into the image
COPY . .
# Expose the port
EXPOSE 8000
# Start the Uvicorn server
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
.dockerignore
Quando si lavora con Docker, si desidera creare immagini il più possibile piccole.
Un modo per ridurre le dimensioni dell’immagine è utilizzare un file .dockerignore. Questo file funziona in modo simile a un file .gitignore. Permette di omettere i file che non devono essere inclusi nell’immagine.
Nella radice del progetto, creare un .dockerignore:
.git/
.idea/
__pycache__/
venv/
create_model.ipynb
Assicurarsi di adattare il file .dockerignore in base ai requisiti del progetto (ad esempio, se si utilizza un IDE diverso).
Costruire, eseguire, testare
Prima di inviare l’immagine al cloud, è bene testarla in locale.
Per seguirci è necessario che Docker Desktop sia installato sul vostro computer.
Aprire il terminale e controllare le immagini attualmente installate:
$ docker images
Successivamente, costruire l’immagine usando il file Docker:
$ docker build -t iris-webapp:1.0 .
Docker impiegherà un po’ di tempo per costruire l’immagine. Questo perché Scikit-learn non è ottimizzato per i container Docker. Sentitevi liberi di fare una breve pausa caffè.
Al termine del comando, ricontrollare le immagini. L’immagine appena creata dovrebbe essere presente.
Infine, utilizzare l’immagine per creare un nuovo contenitore:
$ docker run -p 8000:8000 --name iris-webapp iris-webapp:1.0
Ecco fatto!
L’applicazione web è ora containerizzata. Dovrebbe essere accessibile all’indirizzo http://localhost:8000/ e funzionare come prima.
Spingere su GitHub
Per prima cosa, navigare su GitHub e creare un nuovo repository. Prendete nota dell’URL remoto, perché ci servirà in una fase successiva.
Quindi, tornare alla radice del progetto.
Prima di inviare il codice sorgente al cloud, creare un file .gitignore. Un file .gitignore consente di specificare quali file e directory devono essere omessi dal controllo di versione.
Questo tipo di file funziona come i file .dockerignore.
Nella radice del progetto, creare un file .gitignore:
#.dockerignore
.idea/
__pycache__/
venv/
Aprite il terminale ed eseguite il seguente comando per inizializzare Git:
$ git init
Aggiungere tutti i file al VCS e fare il commit:
$ git add .
$ git commit -m "first commit"
Infine, aggiungere l’origine remota di GitHub usando l’URL di prima e fare il push del codice sorgente:
$ git remote add origin <remote_url>
$ git push origin master
Assicurarsi che l’URL remoto del passo precedente sia utilizzato al posto di .
Ecco fatto. Se si visita ora la pagina del repository GitHub, si dovrebbe vedere che tutti i file sono stati aggiunti.
Distribuire l’applicazione
Per distribuire un’applicazione su Back4app Containers, è necessario prima registrarsi o accedere (se si possiede già un account).
Una volta effettuata l’autenticazione con il proprio account Back4app, si accede alla dashboard dell’applicazione. Per creare una nuova app, fare clic su “Build new app”.
Back4app consente la distribuzione di Backend as a Service e di Containers as a Service. Poiché stiamo distribuendo un’applicazione containerizzata, sceglieremo la seconda opzione.
Successivamente, dovrete collegare il vostro account GitHub a Back4app. Questo permetterà a Back4app di estrarre il codice sorgente dai vostri repository. È possibile concedere l’accesso a tutti i repository o sceglierne di specifici.
Una volta importati i repository, fare clic su “Seleziona”.
La configurazione dell’ambiente non è necessaria, se non per fornire un nome descrittivo all’applicazione.
Quindi fare clic su “Crea”.
Back4app avrà bisogno di qualche minuto per costruire l’immagine, inviarla al registro dei container e avviare un container. Una volta completata la distribuzione, lo stato dell’applicazione dovrebbe cambiare in “Pronto”.
Per visitare l’applicazione, fare clic sull’URL indicato nell’immagine sottostante.
Bene, avete distribuito con successo un modello di apprendimento automatico su Back4app Containers. L’applicazione web dovrebbe funzionare come quella locale. Assicuratevi di testare l’applicazione ancora una volta.
Sintesi
In questo articolo abbiamo appreso le basi dell’apprendimento automatico, le sue applicazioni e come distribuire un modello di apprendimento automatico.
Ora dovreste essere in grado di creare i vostri semplici modelli, servirli con FastAPI e distribuirli nei contenitori Back4app.
Prelevare il codice sorgente finale dal repo GitHub di back4app-deploy-ml-model.