Esercitazione: Distribuire un modello di classificazione delle immagini con training preliminare in Funzioni di Azure con PyTorch

Questo articolo illustra come usare Python, PyTorch e Funzioni di Azure per caricare un modello con training preliminare per classificare un'immagine in base al relativo contenuto. Poiché tutte le operazioni vengono eseguite in locale e non si creano risorse di Azure nel cloud, non è previsto alcun costo per completare questa esercitazione.

  • Inizializzare un ambiente locale per lo sviluppo di Funzioni di Azure in Python.
  • Importare un modello di Machine Learning PyTorch con training preliminare in un'app per le funzioni.
  • Creare un'API HTTP serverless per classificare un'immagine come una delle 1000 classi ImageNet.
  • Utilizzare l'API da un'app Web.

Prerequisiti

Controllo dei prerequisiti

  1. In una finestra di comando o di terminale eseguire func --version per verificare che la versione di Azure Functions Core Tools sia 2.7.1846 o successiva.
  2. Eseguire python --version (Linux/MacOS) o py --version (Windows) per verificare che la versione di Python sia 3.7.x.

Clonare il repository dell'esercitazione

  1. In una finestra di comando o di terminale clonare il repository seguente con Git:

    git clone https://github.com/Azure-Samples/functions-python-pytorch-tutorial.git
    
  2. Passare alla cartella ed esaminarne il contenuto.

    cd functions-python-pytorch-tutorial
    
    • start è la cartella di lavoro per l'esercitazione.
    • end è il risultato finale e l'implementazione completa per riferimento.
    • resources contiene il modello di Machine Learning e le librerie helper.
    • frontend è un sito Web che chiama l'app per le funzioni.

Creare e attivare un ambiente virtuale Python

Passare alla cartella start ed eseguire i comandi seguenti per creare e attivare un ambiente virtuale denominato .venv.

cd start
python -m venv .venv
source .venv/bin/activate

Se Python non ha installato il pacchetto venv nella distribuzione Linux, eseguire il comando seguente:

sudo apt-get install python3-venv

È possibile eseguire tutti i comandi successivi in questo ambiente virtuale attivato. Per uscire dall'ambiente virtuale, eseguire deactivate.

Creare un progetto per le funzioni locale

In Funzioni di Azure un progetto di funzione è un contenitore per una o più funzioni singole che rispondono ognuna a un trigger specifico. Tutte le funzioni di un progetto condividono le stesse configurazioni locali e di hosting. In questa sezione viene creato un progetto di funzione che contiene una singola funzione boilerplate denominata classify che fornisce un endpoint HTTP. Il codice più specifico verrà aggiunto in una sezione successiva.

  1. Nella cartella start usare Azure Functions Core Tools per inizializzare un'app per le funzioni Python:

    func init --worker-runtime python
    

    Dopo l'inizializzazione la cartella start contiene vari file per il progetto, inclusi i file di configurazione denominati local.settings.json e host.json. Poiché local.settings.json può contenere segreti scaricati da Azure, per impostazione predefinita il file viene escluso dal controllo del codice sorgente nel file con estensione gitignore.

    Suggerimento

    Poiché un progetto di funzione è associato a un runtime specifico, tutte le funzioni del progetto devono essere scritte con lo stesso linguaggio.

  2. Aggiungere una funzione al progetto usando il comando seguente, in cui l'argomento --name è il nome univoco della funzione e l'argomento --template specifica il trigger della funzione. func new crea una sottocartella corrispondente al nome della funzione che contiene un file di codice appropriato per il linguaggio scelto del progetto e un file di configurazione denominato function.json.

    func new --name classify --template "HTTP trigger"
    

    Questo comando crea una cartella che corrisponde al nome della funzione, ovvero classify. In questa cartella sono presenti due file: __init__.py, che contiene il codice della funzione e function.json, che descrive il trigger della funzione e le relative associazioni di input e output. Per informazioni dettagliate sul contenuto di questi file, vedere Modello di programmazione nella guida per sviluppatori Python.

Eseguire la funzione in locale

  1. Avviare la funzione avviando l'host di runtime locale di Funzioni di Azure nella cartella start:

    func start
    
  2. Quando nell'output viene visualizzato l'endpoint classify, passare all'URL http://localhost:7071/api/classify?name=Azure. Nell'output verrà visualizzato il messaggio "Hello Azure!".

  3. Premere CTRL-C per arrestare l'host.

Importare il modello PyTorch e aggiungere codice helper

Per modificare la classify funzione per classificare un'immagine in base al relativo contenuto, usare un modello ResNet con training preliminare. Il modello con training preliminare, proveniente da PyTorch, classifica un'immagine in 1 di 1000 classi ImageNet. Aggiungere quindi il codice helper e le dipendenze al progetto.

  1. Nella cartella start eseguire il comando seguente per copiare il codice e le etichette di stima nella cartella classify .

    cp ../resources/predict.py classify
    cp ../resources/labels.txt classify
    
  2. Verificare che la cartella classify contenga file denominati predict.py e labels.txt. In caso contrario, verificare che il comando sia stato eseguito nella cartella start.

  3. Aprire start/requirements.txt in un editor di testo e aggiungere le dipendenze richieste dal codice helper, che dovrebbe essere simile al seguente:

    azure-functions
    requests
    -f https://download.pytorch.org/whl/torch_stable.html
    torch==1.13.0+cpu
    torchvision==0.14.0+cpu
    

    Suggerimento

    Le versioni di torch e torchvision devono corrispondere ai valori elencati nella tabella delle versioni del repository di visione PyTorch.

  4. Salvare requirements.txt, quindi eseguire il comando seguente dalla cartella start per installare le dipendenze.

    pip install --no-cache-dir -r requirements.txt
    

L'installazione può richiedere alcuni minuti, durante i quali è possibile procedere con la modifica della funzione nella sezione successiva.

Suggerimento

È possibile che in Windows venga visualizzato un errore simile a "Non è stato possibile installare i pacchetti a causa di un errore EnvironmentError: [numero errore 2] non esiste alcun file o directory di questo tipo:" seguito da un percorso lungo a un file come sharded_mutable_dense_hashtable.cpython-37.pyc. Questo errore si verifica in genere perché la profondità del percorso della cartella diventa eccessiva. In tal caso, impostare la chiave del Registro di sistema HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled su 1 per abilitare i percorsi lunghi. In alternativa, controllare il percorso in cui è installato l'interprete Python. Se tale percorso è un percorso lungo, provare a reinstallare in una cartella con un percorso più breve.

Aggiornare la funzione per generare previsioni

  1. Aprire classify/__init__.py in un editor di testo e aggiungere le righe seguenti dopo le istruzioni esistenti import per importare la libreria JSON standard e gli helper predict :

    import logging
    import azure.functions as func
    import json
    
    # Import helper script
    from .predict import predict_image_from_url
    
  2. Sostituire l'intero contenuto della funzione main con il codice seguente:

    def main(req: func.HttpRequest) -> func.HttpResponse:
        image_url = req.params.get('img')
        logging.info('Image URL received: ' + image_url)
    
        results = predict_image_from_url(image_url)
    
        headers = {
            "Content-type": "application/json",
            "Access-Control-Allow-Origin": "*"
        }
    
        return func.HttpResponse(json.dumps(results), headers = headers)
    

    Questa funzione riceve un URL di immagine in un parametro della stringa di query denominato img. Chiama quindi predict_image_from_url dalla libreria helper per scaricare e classificare l'immagine usando il modello PyTorch. La funzione restituisce quindi una risposta HTTP con i risultati.

    Importante

    Dal momento che l'endpoint HTTP viene chiamato da una pagina Web ospitata in un altro dominio, la risposta include un'intestazione Access-Control-Allow-Origin per soddisfare i requisiti di condivisione di risorse tra le origini (CORS) del browser.

    In un'applicazione di produzione, per maggiore sicurezza sostituire * con l'origine specifica della pagina Web.

  3. Salvare le modifiche e quindi, supponendo che le dipendenze abbiano terminato l'installazione, avviare di nuovo l'host della funzione locale con func start. Assicurarsi di eseguire l'host nella cartella start con l'ambiente virtuale attivato. In caso contrario, l'host verrà avviato, ma verranno visualizzati errori durante la chiamata della funzione.

    func start
    
  4. In un browser aprire l'URL seguente per richiamare la funzione con l'URL di un'immagine Bernese Mountain Dog e verificare che il codice JSON restituito classifica l'immagine come Un Cane di Montagna Bernese.

    http://localhost:7071/api/classify?img=https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/Bernese-Mountain-Dog-Temperament-long.jpg
    
  5. Lasciare l'host in esecuzione perché verrà usato nel passaggio successivo.

Eseguire il front-end dell'app Web locale per testare la funzione

Per eseguire il test richiamando l'endpoint della funzione da un'altra app Web, usare l'app semplice presente nella cartella frontend del repository.

  1. Aprire un terminale o prompt dei comandi e attivare l'ambiente virtuale, come descritto in precedenza in Creare e attivare un ambiente virtuale Python.

  2. Passare alla cartella frontend del repository.

  3. Avviare un server HTTP con Python:

    python -m http.server
    
  4. In un browser passare a localhost:8000 e quindi immettere uno degli URL di foto seguenti nella casella di testo oppure usare l'URL di qualsiasi immagine accessibile pubblicamente.

    • https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/Bernese-Mountain-Dog-Temperament-long.jpg
    • https://github.com/Azure-Samples/functions-python-pytorch-tutorial/blob/master/resources/assets/bald-eagle.jpg?raw=true
    • https://raw.githubusercontent.com/Azure-Samples/functions-python-pytorch-tutorial/master/resources/assets/penguin.jpg
  5. Selezionare Invia per richiamare l'endpoint della funzione per classificare l'immagine.

    Screenshot del progetto finito

    Se il browser restituisce un errore quando si invia l'URL dell'immagine, controllare il terminale in cui si sta eseguendo l'app per le funzioni. Se viene visualizzato un errore simile a "Non sono stati trovati moduli 'PIL'", è possibile che l'app per le funzioni nella cartella start sia stata avviata senza aver prima attivato l'ambiente virtuale creato in precedenza. Se vengono ancora visualizzati errori, eseguire di nuovo pip install -r requirements.txt con l'ambiente virtuale attivato e cercare gli errori.

Pulire le risorse

Dal momento che l'intera esercitazione viene eseguita in locale sul computer in uso, non sono presenti risorse o servizi di Azure di cui eseguire la pulizia.

Passaggi successivi

In questa esercitazione si è appreso come compilare e personalizzare un endpoint API HTTP con Funzioni di Azure per classificare le immagini usando un modello PyTorch. È stato anche illustrato come chiamare l'API da un'app Web. È possibile usare le tecniche illustrate in questa esercitazione per creare API di qualsiasi complessità, eseguendo sempre il modello di calcolo serverless offerto da Funzioni di Azure.

Vedere anche la pagina relativa alla