TensorFlow.js: conversione di un SavedModel Python in formato TensorFlow.js

1. Introduzione

Hai fatto i primi passi con TensorFlow.js, hai provato i nostri modelli predefiniti o magari ne hai creato uno tuo, ma hai visto alcune ricerche all'avanguardia in Python e vuoi sapere se funzioneranno nel browser web per trasformare la tua fantastica idea in realtà per milioni di persone in modo scalabile. Ti suona familiare? In caso affermativo, questo è il codelab che fa per te.

Il team di TensorFlow.js ha creato un comodo strumento per convertire i modelli in formato SavedModel in TensorFlow.js tramite un convertitore da riga di comando, in modo da poter utilizzare questi modelli con la portata e la scalabilità del web.

Cosa imparerai a fare

In questo lab di programmazione imparerai a utilizzare il convertitore della riga di comando TensorFlow.js per trasferire un SavedModel generato in Python nel formato model.json richiesto per l'esecuzione lato client in un browser web.

In particolare:

  • Come creare un semplice modello ML Python e salvarlo nel formato richiesto dal convertitore TensorFlow.js.
  • Come installare e utilizzare il convertitore TensorFlow.js sul modello SavedModel esportato da Python.
  • Prendi i file risultanti dalla conversione e utilizzali nella tua applicazione web JS.
  • Scopri cosa fare in caso di problemi (non tutti i modelli verranno convertiti) e quali opzioni hai a disposizione.

Immagina di poter prendere una ricerca appena pubblicata e rendere il modello disponibile a milioni di sviluppatori JS in tutto il mondo. Oppure potresti utilizzarlo tu stesso nella tua creazione, che chiunque al mondo potrà sperimentare se viene eseguita nel browser web, poiché non sono richieste dipendenze complesse o configurazioni dell'ambiente. Pronto per iniziare a programmare? Iniziamo!

Condividi con noi le tue conversioni.

Puoi utilizzare ciò che impariamo oggi per provare a convertire alcuni dei tuoi modelli preferiti da Python. Se riesci a farlo e a creare un sito web demo funzionante del modello in azione, taggaci sui social media utilizzando l'hashtag #MadeWithTFJS per avere la possibilità che il tuo progetto venga pubblicato sul nostro blog di TensorFlow o anche in futuri eventi di presentazione. Ci piacerebbe vedere altre ricerche straordinarie trasferite sul web e consentire a un maggior numero di persone di utilizzare questi modelli in modo innovativo o creativo, proprio come questo ottimo esempio.

2. Che cos'è TensorFlow.js?

1aee0ede85885520.png

TensorFlow.js è una libreria di machine learning open source che può essere eseguita ovunque sia possibile eseguire JavaScript. Si basa sulla libreria TensorFlow originale scritta in Python e mira a ricreare questa esperienza per gli sviluppatori e questo insieme di API per l'ecosistema JavaScript.

Dove può essere utilizzata?

Data la portabilità di JavaScript, ora puoi scrivere in una sola lingua ed eseguire il machine learning con facilità su tutte le seguenti piattaforme:

  • Lato client nel browser web utilizzando JavaScript vanilla
  • Lato server e persino dispositivi IoT come Raspberry Pi utilizzando Node.js
  • App desktop che utilizzano Electron
  • App native per dispositivi mobili che utilizzano React Native

TensorFlow.js supporta anche più backend all'interno di ciascuno di questi ambienti (gli ambienti basati sull'hardware effettivo in cui può essere eseguito, ad esempio la CPU o WebGL). Un "backend" in questo contesto non indica un ambiente lato server. Il backend per l'esecuzione potrebbe essere lato client in WebGL, ad esempio, per garantire la compatibilità e mantenere la velocità di esecuzione. Al momento TensorFlow.js supporta:

  • Esecuzione di WebGL sulla scheda grafica (GPU) del dispositivo: questo è il modo più veloce per eseguire modelli più grandi (di dimensioni superiori a 3 MB) con l'accelerazione GPU.
  • Esecuzione di Web Assembly (WASM) sulla CPU: per migliorare le prestazioni della CPU su tutti i dispositivi, inclusi ad esempio i cellulari di vecchia generazione. Questo è più adatto a modelli più piccoli (di dimensioni inferiori a 3 MB) che possono essere eseguiti più velocemente sulla CPU con WASM rispetto a WebGL a causa dell'overhead del caricamento dei contenuti su un processore grafico.
  • Esecuzione della CPU: il fallback se nessuno degli altri ambienti è disponibile. È il più lento dei tre, ma è sempre a tua disposizione.

Nota:puoi scegliere di forzare uno di questi backend se sai su quale dispositivo verrà eseguito il codice oppure puoi lasciare che TensorFlow.js decida per te se non lo specifichi.

Superpoteri lato client

L'esecuzione di TensorFlow.js nel browser web sul computer client può comportare diversi vantaggi da prendere in considerazione.

Privacy

Puoi addestrare e classificare i dati sulla macchina client senza mai inviarli a un server web di terze parti. A volte, questo potrebbe essere un requisito per rispettare le leggi locali, ad esempio il GDPR, o durante l'elaborazione di dati che l'utente potrebbe voler conservare sul proprio computer e non inviare a terzi.

Velocità

Poiché non devi inviare dati a un server remoto, l'inferenza (l'atto di classificare i dati) può essere più veloce. Ancora meglio, se l'utente ti concede l'accesso, puoi accedere direttamente ai sensori del dispositivo, come fotocamera, microfono, GPS, accelerometro e altro ancora.

Copertura e scalabilità

Con un solo clic, chiunque al mondo può fare clic su un link che gli invii, aprire la pagina web nel browser e utilizzare ciò che hai creato. Non è necessario configurare Linux lato server con driver CUDA e molto altro solo per utilizzare il sistema di machine learning.

Costo

Nessun server significa che l'unica cosa che devi pagare è una CDN per ospitare i file HTML, CSS, JS e modello. Il costo di una CDN è molto inferiore rispetto a quello di un server (potenzialmente con una scheda grafica collegata) in esecuzione 24 ore su 24, 7 giorni su 7.

Funzionalità lato server

L'utilizzo dell'implementazione Node.js di TensorFlow.js consente le seguenti funzionalità.

Supporto completo di CUDA

Sul lato server, per l'accelerazione della scheda grafica, devi installare i driver NVIDIA CUDA per consentire a TensorFlow di funzionare con la scheda grafica (a differenza del browser che utilizza WebGL, senza necessità di installazione). Tuttavia, con il supporto completo di CUDA puoi sfruttare appieno le funzionalità di basso livello della scheda grafica, ottenendo tempi di addestramento e inferenza più rapidi. Il rendimento è alla pari con l'implementazione di TensorFlow in Python, in quanto entrambi condividono lo stesso backend C++.

Dimensioni del modello

Per i modelli all'avanguardia della ricerca, potresti lavorare con modelli molto grandi, forse di dimensioni di gigabyte. Al momento questi modelli non possono essere eseguiti nel browser web a causa delle limitazioni dell'utilizzo della memoria per scheda del browser. Per eseguire questi modelli più grandi, puoi utilizzare Node.js sul tuo server con le specifiche hardware necessarie per eseguire un modello di questo tipo in modo efficiente.

IOT

Node.js è supportato su computer a scheda singola popolari come Raspberry Pi, il che significa che puoi eseguire modelli TensorFlow.js anche su questi dispositivi.

Velocità

Node.js è scritto in JavaScript, il che significa che beneficia della compilazione just-in-time. Ciò significa che spesso potresti notare miglioramenti delle prestazioni quando utilizzi Node.js, in quanto verrà ottimizzato in fase di runtime, soprattutto per qualsiasi preelaborazione che potresti eseguire. Un ottimo esempio è visibile in questo case study, che mostra come Hugging Face ha utilizzato Node.js per ottenere un aumento delle prestazioni di due volte per il proprio modello di elaborazione del linguaggio naturale.

Ora che hai compreso le nozioni di base di TensorFlow.js, dove può essere eseguito e alcuni dei suoi vantaggi, iniziamo a fare cose utili.

3. Configurazione del sistema

Per questo tutorial utilizzeremo Ubuntu, una popolare distribuzione Linux utilizzata da molte persone e disponibile su Compute Engine di Google Cloud come immagine di base se scegli di seguire la procedura su una macchina virtuale basata sul cloud.

Al momento della stesura, possiamo selezionare l'immagine di Ubuntu 18.04.4 LTS quando creiamo una nuova istanza di Compute Engine di base, che è quella che utilizzeremo. Puoi ovviamente utilizzare la tua macchina o anche un sistema operativo diverso, se lo desideri, ma le istruzioni di installazione e le dipendenze possono variare a seconda dei sistemi.

Installazione di TensorFlow (versione Python)

Ora, dato che probabilmente stai cercando di convertire un modello esistente basato su Python che hai trovato o che scriverai, prima di poter esportare un file "SavedModel" da Python, devi configurare la versione Python di TensorFlow sulla tua istanza se "SavedModel" non è già disponibile per il download.

Accedi tramite SSH alla macchina cloud che hai creato sopra, quindi digita quanto segue nella finestra del terminale:

Finestra del terminale:

sudo apt update
sudo apt-get install python3

In questo modo, ci assicureremo che Python 3 sia installato sulla macchina. Per utilizzare TensorFlow, deve essere installato Python 3.4 o versioni successive.

Per verificare che sia installata la versione corretta, digita quanto segue:

Finestra del terminale:

python3 --version

Dovresti vedere un output che indica il numero di versione, ad esempio Python 3.6.9. Se la stampa è corretta e il valore è superiore a 3,4, possiamo continuare.

Successivamente, installeremo PIP per Python 3, il gestore dei pacchetti di Python, e lo aggiorneremo. Tipo:

Finestra del terminale:

sudo apt install python3-pip
pip3 install --upgrade pip

Anche in questo caso possiamo verificare l'installazione di pip3 tramite:

Finestra del terminale:

pip3 --version

Al momento della stesura, dopo l'esecuzione di questo comando viene stampato pip 20.2.3 nel terminale.

Prima di poter installare TensorFlow, è necessario che il pacchetto Python "setuptools" sia della versione 41.0.0 o successive. Esegui questo comando per assicurarti che sia aggiornato all'ultima versione:

Finestra del terminale:

pip3 install -U setuptools

Infine, possiamo installare TensorFlow per Python:

Finestra del terminale:

pip3 install tensorflow

Il completamento dell'operazione potrebbe richiedere del tempo, quindi attendi il termine dell'esecuzione.

Verifichiamo che TensorFlow sia installato correttamente. Crea un file Python denominato test.py nella directory attuale:

Finestra del terminale:

nano test.py

Una volta aperto nano, possiamo scrivere del codice Python per stampare la versione di TensorFlow installata:

test.py:

import tensorflow as tf
print(tf.__version__)

Premi CTRL + O per scrivere le modifiche sul disco e poi CTRL + X per uscire dall'editor nano.

Ora possiamo eseguire questo file Python per visualizzare la versione di TensorFlow stampata sullo schermo:

Finestra del terminale:

python3 test.py

Al momento della stesura, vediamo 2.3.1 stampato nella console per la nostra versione di TensorFlow Python installata.

4. Creazione di un modello Python

Il passaggio successivo di questo codelab descrive la creazione di un semplice modello Python per mostrare come salvare il modello addestrato risultante nel formato "SavedModel" da utilizzare poi con il nostro convertitore da riga di comando TensorFlow.js. Il principio sarebbe simile per qualsiasi modello Python che tenti di convertire, ma manterremo questo codice semplice in modo che tutti possano comprenderlo.

Modifichiamo il file test.py creato nella prima sezione e aggiorniamo il codice come segue:

test.py:

import tensorflow as tf
print(tf.__version__)

# Import NumPy - package for working with arrays in Python.
import numpy as np

# Import useful keras functions - this is similar to the
# TensorFlow.js Layers API functionality.
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense

# Create a new dense layer with 1 unit, and input shape of [1].
layer0 = Dense(units=1, input_shape=[1])
model = Sequential([layer0])

# Compile the model using stochastic gradient descent as optimiser
# and the mean squared error loss function.
model.compile(optimizer='sgd', loss='mean_absolute_error')

# Provide some training data! Here we are using some fictional data 
# for house square footage and house price (which is simply 1000x the 
# square footage) which our model must learn for itself.
xs = np.array([800.0, 850.0, 900.0, 950.0, 980.0, 1000.0, 1050.0, 1075.0, 1100.0, 1150.0, 1200.0, 1250.0, 1300.0, 1400.0, 1500.0, 1600.0, 1700.0, 1800.0, 1900.0, 2000.0], dtype=float)

ys = np.array([800000.0, 850000.0, 900000.0, 950000.0, 980000.0, 1000000.0, 1050000.0, 1075000.0, 1100000.0, 1150000.0, 1200000.0,  1250000.0, 1300000.0, 1400000.0, 1500000.0, 1600000.0, 1700000.0, 1800000.0, 1900000.0, 2000000.0], dtype=float)

# Train the model for 500 epochs.
model.fit(xs, ys, epochs=500, verbose=0)

# Test the trained model on a test input value
print(model.predict([1200.0]))

# Save the model we just trained to the "SavedModel" format to the
# same directory our test.py file is located.
tf.saved_model.save(model, './')

Questo codice addestrerà una regressione lineare molto semplice per imparare a stimare la relazione tra le x (input) e le y (output) fornite. Salveremo quindi il modello addestrato risultante sul disco. Controlla i commenti in linea per ulteriori dettagli sulla funzione di ogni riga.

Se controlliamo la nostra directory dopo aver eseguito questo programma (chiamando python3 test.py), dovremmo vedere alcuni nuovi file e cartelle creati nella nostra directory corrente:

  • test.py
  • saved_model.pb
  • asset
  • variables

Ora abbiamo generato i file necessari per essere utilizzati dal convertitore TensorFlow.js per convertire questo modello in modo che venga eseguito nel browser.

5. Conversione di SavedModel nel formato TensorFlow.js

Installare TensorFlow.js Converter

Per installare il convertitore, esegui questo comando:

Finestra del terminale:

pip3 install tensorflowjs

È stato facile.

Supponendo di utilizzare il convertitore da riga di comando (tensorflowjs_converter) e non la versione guidata mostrata sopra, possiamo chiamare il seguente comando per convertire il modello salvato appena creato e passare esplicitamente i parametri al convertitore:

Finestra del terminale:

tensorflowjs_converter \
    --input_format=keras_saved_model \
    ./ \
    ./predict_houses_tfjs

Che cosa sta succedendo qui? Per prima cosa, chiamiamo il file binario tensorflowjs_converter appena installato e specifichiamo che stiamo tentando di convertire un modello salvato di Keras.

Nel nostro esempio di codice riportato sopra, noterai che abbiamo importato Keras e utilizzato le relative API di livello superiore per creare il nostro modello. Se non hai utilizzato Keras nel tuo codice Python, ti consigliamo di utilizzare un formato di input diverso:

  • keras: per caricare il formato keras (tipo di file HDF5)
  • tf_saved_model: per caricare il modello che utilizza le API TensorFlow Core anziché Keras.
  • tf_frozen_model: per caricare un modello che contiene pesi bloccati.
  • tf_hub: per caricare un modello generato da TensorFlow Hub.

Puoi scoprire di più su questi altri formati qui.

I due parametri successivi specificano la cartella in cui si trova il modello salvato. Nella demo precedente, abbiamo specificato la directory corrente e infine la directory in cui vogliamo generare l'output della conversione, che abbiamo specificato sopra come cartella denominata "predict_houses_tfjs" nella directory corrente.

L'esecuzione del comando precedente crea una nuova cartella nella directory corrente denominata predict_houses_tfjs che contiene:

  • model.json
  • Group1-shard1of1.bin

Questi sono i file necessari per eseguire il modello nel browser web. Salva questi file perché li utilizzeremo nella sezione successiva.

6. Utilizzo del modello convertito nel browser

Ospitare i file convertiti

Per prima cosa, dobbiamo inserire i file model.json e *.bin generati su un server web in modo da potervi accedere tramite la nostra pagina web. Per questa demo utilizzeremo Glitch.com, in modo che tu possa seguirla facilmente. Tuttavia, se hai esperienza di ingegneria web, puoi scegliere di avviare un semplice server HTTP sull'istanza del server Ubuntu corrente. A te la scelta.

Caricare file su Glitch

  1. Accedi a Glitch.com
  2. Utilizza questo link per clonare il nostro progetto TensorFlow.js boilerplate. Contiene file HTML, CSS e JS scheletrici che importano la libreria TensorFlow.js pronta per l'uso.
  3. Fai clic sulla cartella "asset" nel riquadro a sinistra.
  4. Fai clic su "Carica un asset" e seleziona group1-shard1of1.bin da caricare in questa cartella. Una volta caricato, dovrebbe avere questo aspetto: 25a2251c7f165184.png
  5. Se fai clic sul file group1-shard1of1.bin che hai appena caricato, potrai copiare l'URL della sua posizione. Copia questo percorso ora come mostrato: 92ded8d46442c404.png
  6. Ora modifica model.json utilizzando il tuo editor di testo preferito sul tuo computer locale e cerca (utilizzando CTRL+F) il file group1-shard1of1.bin, che verrà menzionato da qualche parte al suo interno.

Sostituisci questo nome file con l'URL che hai copiato dal passaggio 5, ma elimina https://cdn.glitch.com/ che il problema genera dal percorso copiato.

Dopo la modifica, dovrebbe essere simile a questo (nota come il percorso del server iniziale è stato rimosso, quindi viene mantenuto solo il nome file caricato risultante): d5a338f2dc1f31d4.png 7. Ora salva e carica questo file model.json modificato su Glitch facendo clic su Asset, poi fai clic sul pulsante "Carica un asset" (importante). Se non utilizzi il pulsante fisico e il trascinamento, il file verrà caricato come file modificabile anziché sulla CDN, quindi non si troverà nella stessa cartella e il percorso relativo viene presupposto quando TensorFlow.js tenta di scaricare i file binari per un determinato modello. Se hai eseguito l'operazione correttamente, dovresti visualizzare due file nella cartella assets, come segue: 51a6dbd5d3097ffc.png

Bene. Ora siamo pronti a utilizzare i file salvati con del codice effettivo nel browser.

Caricamento del modello

Ora che abbiamo ospitato i file convertiti, possiamo scrivere una semplice pagina web per caricarli e utilizzarli per fare una previsione. Apri script.js nella cartella del progetto Glitch e sostituisci i contenuti di questo file con i seguenti dopo aver modificato const MODEL_URL in modo che punti al link Glitch.com generato per il file model.json che hai caricato su Glitch:

script.js:

// Grab a reference to our status text element on the web page.
// Initially we print out the loaded version of TFJS.
const status = document.getElementById('status');
status.innerText = 'Loaded TensorFlow.js - version: ' + tf.version.tfjs;

// Specify location of our Model.json file we uploaded to the Glitch.com CDN.
const MODEL_URL = YOUR MODEL.JSON URL HERE! CHANGE THIS!';
// Specify a test value we wish to use in our prediction.
// Here we use 950, so we expect the result to be close to 950,000.
const TEST_VALUE = 950.0

// Create an asynchronous function.
async function run() {
    // Load the model from the CDN.
    const model = await tf.loadLayersModel(MODEL_URL);

    // Print out the architecture of the loaded model.
    // This is useful to see that it matches what we built in Python.
    console.log(model.summary());

    // Create a 1 dimensional tensor with our test value.
    const input = tf.tensor1d([TEST_VALUE]);

    // Actually make the prediction.
    const result = model.predict(input);

    // Grab the result of prediction using dataSync method
    // which ensures we do this synchronously.
    status.innerText = 'Input of ' + TEST_VALUE + 
        'sqft predicted as $' + result.dataSync()[0];
}

// Call our function to start the prediction!
run();

L'esecuzione del codice riportato sopra dopo aver modificato la costante MODEL_URL in modo che punti al percorso model.json genera un output mostrato di seguito.

c5e8457213058ec3.png

Se esaminiamo la console del browser web (premi F12 per visualizzare gli strumenti per sviluppatori nel browser), possiamo anche vedere la descrizione del modello caricato, che stampa:

35e79d70dbd66f27.png

Se lo confrontiamo con il codice Python all'inizio di questo codelab, possiamo confermare che si tratta della stessa rete che abbiamo creato con un input denso e un livello denso con un nodo.

Complimenti! Hai appena eseguito un modello addestrato Python convertito nel browser web.

7. Modelli che non generano conversioni

A volte, i modelli più complessi che vengono compilati per utilizzare operazioni meno comuni non saranno supportati per la conversione. La versione di TensorFlow.js basata sul browser è una riscrittura completa di TensorFlow e, in quanto tale, al momento non supportiamo tutte le operazioni di basso livello disponibili nell'API TensorFlow C++ (ce ne sono migliaia), anche se nel tempo ne vengono aggiunte altre man mano che cresciamo e che le operazioni principali diventano più stabili.

Al momento della stesura, una di queste funzioni in TensorFlow Python che genera un'operazione non supportata quando viene esportata come SavedModel è linalg.diag. Se proviamo a convertire un modello salvato che utilizza questa funzionalità in Python (che supporta le operazioni risultanti che produce), verrà visualizzato un errore simile a quello mostrato di seguito:

5df94fc652393e00.png

Qui possiamo vedere evidenziato in rosso che la chiamata linalg.diag è stata compilata per produrre un'operazione denominata MatrixDiagV3, che non è supportata da TensorFlow.js nel browser web al momento della stesura di questo codelab.

Che cosa fare?

Hai due opzioni.

  1. Implementa questa operazione mancante in TensorFlow.js. Siamo un progetto open source e accettiamo contributi per elementi come nuove operazioni. Consulta questa guida sulla scrittura di nuove operazioni per TensorFlow.js. Se riesci a farlo, puoi utilizzare il flag Skip_op_check nel nostro convertitore della riga di comando per ignorare questo errore e continuare comunque la conversione (si presuppone che questa operazione sia disponibile nella nuova build di TensorFlow.js che hai creato e che supporta l'operazione mancante).
  2. Determina quale parte del codice Python ha prodotto l'operazione non supportata nel file savedmodel che hai esportato. In un piccolo insieme di codice potrebbe essere facile da individuare, ma in modelli più complessi potrebbe richiedere un'indagine piuttosto approfondita, in quanto al momento non esiste un metodo per identificare la chiamata di funzione Python di alto livello che ha prodotto una determinata operazione una volta nel formato di file savedmodel. Una volta individuato, puoi potenzialmente modificarlo per utilizzare un metodo diverso supportato.

8. Complimenti

Congratulazioni, hai fatto i primi passi per utilizzare un modello Python tramite TensorFlow.js nel browser web.

Riepilogo

In questo lab sul codice abbiamo imparato a:

  1. Configura l'ambiente Linux per installare TensorFlow basato su Python
  2. Esportare un "SavedModel" Python
  3. Installare il convertitore a riga di comando TensorFlow.js
  4. Utilizza il convertitore della riga di comando TensorFlow.js per creare i file lato client richiesti
  5. Utilizzare i file generati nell'applicazione web reale
  6. Identifica i modelli che non verranno convertiti e cosa dovrebbe essere implementato per consentirne la conversione in futuro.

Passaggi successivi

Ricordati di taggarci in tutto ciò che crei utilizzando #MadeWithTFJS per avere la possibilità di essere pubblicati sui social media o persino presentati in occasione di eventi TensorFlow futuri. Ci piacerebbe vedere cosa converti e utilizzi lato client nel browser.

Altre codelab su TensorFlow.js per approfondire l'argomento

Siti web da visitare