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

1. Introduzione

Hai fatto i primi passi con TensorFlow.js, provato i nostri modelli predefiniti o magari ne hai creati uno proprio, ma hai visto emergere qualche ricerca all'avanguardia in Python e ti piacerebbe vedere se verrà eseguito nel browser web per realizzare quell'idea fantastica che avevi trasformato in realtà per milioni di persone in modo scalabile. Suona familiare? Se sì, questo è il CodeLab che fa per te.

Il team TensorFlow.js ha realizzato un comodo strumento per convertire i modelli nel formato SavedModel in TensorFlow.js mediante un convertitore della riga di comando, in modo che sia possibile utilizzarli con la copertura e la scalabilità del web.

Cosa imparerai a fare

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

In particolare:

  • Creare un semplice modello ML Python e salvarlo nel formato richiesto richiesto dal convertitore TensorFlow.js.
  • Come installare e utilizzare il convertitore TensorFlow.js sul modulo SavedModel esportato da Python.
  • Recupera i file risultanti dalla conversione e utilizzali nell'applicazione web JS.
  • Comprendere cosa fare quando si verifica un problema (non tutti i modelli generano conversioni) e le opzioni a tua disposizione.

Immagina di poter svolgere una ricerca appena pubblicata e di rendere il modello disponibile a milioni di sviluppatori JS in tutto il mondo. O forse lo userai tu stesso per una tua creazione, che chiunque nel mondo può quindi sperimentare se viene eseguito nel browser web, in quanto non sono necessarie dipendenze complesse o configurazione dell'ambiente. Pronto a iniziare? Iniziamo!

Condividi con noi le informazioni che converti.

Puoi usare 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 mostrato nel nostro blog di TensorFlow o anche per mostrare e raccontare eventi in futuro. Ci piacerebbe vedere altre ricerche straordinarie portate sul web e consentire a un maggior numero di persone di utilizzare questi modelli in modi innovativi o creativi, proprio come questo ottimo esempio.

2. Che cos'è TensorFlow.js?

1aee0ede85885520.png

TensorFlow.js è una libreria open source di machine learning che può essere eseguita ovunque JavaScript possa essere eseguito. Si basa sulla libreria TensorFlow originale scritta in Python e mira a ricreare questa esperienza di sviluppo e un insieme di API per l'ecosistema JavaScript.

Dove può essere utilizzato?

Data la portabilità di JavaScript, ora puoi scrivere in un solo linguaggio ed eseguire facilmente il machine learning su tutte le seguenti piattaforme:

  • Lato client nel browser web con JavaScript Vanilla
  • Lato server e persino dispositivi IoT come Raspberry Pi che utilizzano 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 (ad esempio gli ambienti basati su hardware effettivi che può eseguire all'interno, come CPU o WebGL. Un "backend" in questo contesto non significa un ambiente lato server: il backend per l'esecuzione potrebbe essere sul lato client, ad esempio, in WebGL) per garantire la compatibilità e garantire anche la velocità. Attualmente TensorFlow.js supporta:

  • Esecuzione WebGL sulla scheda grafica del dispositivo (GPU): è il modo più veloce per eseguire modelli più grandi (superiori a 3 MB) con accelerazione GPU.
  • Esecuzione di Web Assembly (WASM) sulla CPU: per migliorare le prestazioni della CPU su tutti i dispositivi, inclusi, ad esempio, telefoni cellulari meno recenti. È 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 associato al caricamento dei contenuti su un processore grafico.
  • Esecuzione CPU: il fallback non dovrebbe essere disponibile in nessuno degli altri ambienti. È il più lento dei tre, ma è sempre disponibile.

Nota: puoi scegliere di forzare uno di questi backend se sai su quale dispositivo eseguirai l'esecuzione oppure puoi lasciare che sia TensorFlow.js a decidere per te, se non lo specifichi.

Superpoteri lato client

L'esecuzione di TensorFlow.js nel browser web sul computer client può portare a numerosi vantaggi che vale la pena prendere in considerazione.

Privacy

È possibile addestrare e classificare i dati sul computer client senza mai inviarli a un server web di terze parti. In alcuni casi potrebbe essere necessario rispettare le leggi locali, come ad esempio il GDPR, o durante l'elaborazione di dati che l'utente potrebbe voler conservare sul proprio computer e non essere inviati a terze parti.

Velocità

Poiché non devi inviare i dati a un server remoto, l'inferenza (l'atto di classificare i dati) può essere più veloce. Inoltre, avrai accesso diretto ai sensori del dispositivo, come fotocamera, microfono, GPS, accelerometro e altri, se l'utente ti concede l'accesso.

Copertura e scalabilità

Con un solo clic chiunque nel mondo può fare clic su un link che hai inviato, aprire la pagina web nel proprio browser e utilizzare ciò che hai creato. Non è necessaria una configurazione Linux lato server complessa 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 tuoi file HTML, CSS, JS e modello. Il costo di una CDN è molto più economico che tenere un server (potenzialmente con una scheda grafica collegata) in esecuzione 24/7.

Funzionalità lato server

L'implementazione di Node.js di TensorFlow.js attiva le seguenti funzionalità.

Supporto CUDA completo

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 - nessuna installazione necessaria). Tuttavia, con il supporto CUDA completo è possibile sfruttare appieno le capacità di livello inferiore della scheda grafica, con tempi di addestramento e inferenza più rapidi. Le prestazioni sono uguali a quelle dell'implementazione di TensorFlow Python, in quanto entrambi condividono lo stesso backend C++.

Dimensioni modello

Nel caso di modelli all'avanguardia provenienti dalla ricerca, potresti lavorare con modelli molto grandi, ad esempio di gigabyte. Questi modelli al momento non possono essere eseguiti nel browser web a causa delle limitazioni di utilizzo della memoria per scheda del browser. Per eseguire questi modelli di dimensioni maggiori puoi utilizzare Node.js sul tuo server con le specifiche hardware necessarie per eseguire questo modello in modo efficiente.

IoT

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

Velocità

Node.js è scritto in JavaScript, il che significa che trae vantaggio dalla compilazione just-in-time. Ciò significa che spesso potresti notare un miglioramento delle prestazioni quando utilizzi Node.js, in quanto verrà ottimizzato in fase di runtime, in particolare per qualsiasi pre-elaborazione. Un ottimo esempio di ciò può essere visto in questo case study, che mostra come Hugging Face ha utilizzato Node.js per ottenere un aumento delle prestazioni di 2 volte per il proprio modello di elaborazione del linguaggio naturale.

Ora che conosci le nozioni di base di TensorFlow.js, dove può essere eseguito e alcuni dei vantaggi, iniziamo a utilizzarlo.

3. Configurazione del sistema in corso

Per questo tutorial utilizzeremo Ubuntu, una distribuzione Linux molto diffusa che molti usano di frequente ed è disponibile su Google Cloud Compute Engine come immagine di base se scegli di seguirla su una macchina virtuale basata su cloud.

Al momento della stesura di questo documento, possiamo selezionare l'immagine di Ubuntu 18.04.4 LTS quando creiamo una nuova istanza di Compute Engine vanilla, che è quella che utilizzeremo. Puoi ovviamente utilizzare la tua macchina o anche un altro sistema operativo, se scegli di farlo, ma le istruzioni di installazione e le dipendenze possono variare da un sistema all'altro.

Installazione di TensorFlow (versione Python)

Ora, poiché probabilmente stai tentando di convertire un modello esistente basato su Python che hai trovato / o scriverai, prima di poter esportare un modello "SavedModel" da Python, dovrai configurare la versione Python di TensorFlow sull'istanza se il file "SavedModel" non è già disponibile per il download.

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

Finestra del terminale:

sudo apt update
sudo apt-get install python3

Questo assicura che Python 3 sia installato sulla macchina. Per utilizzare TensorFlow è necessario installare 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 vedi che è stampato correttamente ed è superiore a 3.4, possiamo continuare.

Quindi installeremo PIP per Python 3, che è il gestore di pacchetti di Python, e quindi 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 scrittura, vediamo pip 20.2.3 stampato nel terminale dopo l'esecuzione di questo comando.

Per poter installare TensorFlow, è necessario il pacchetto Python "setuptools" sia della versione 41.0.0 o successiva. 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 che termini l'esecuzione.

Verifica che TensorFlow sia installato correttamente. Crea un file Python denominato test.py nella tua 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, quindi CTRL + X per uscire dall'editor nano.

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

Finestra del terminale:

python3 test.py

Al momento della scrittura, vediamo 2.3.1 stampato sulla console per la nostra versione di TensorFlow Python installato.

4. Creazione di un modello Python

Il passaggio successivo di questo codelab illustra come creare un modello Python semplice per mostrare come salvare il modello addestrato risultante in "SavedModel". da utilizzare con il nostro convertitore della riga di comando TensorFlow.js. Il principio sarebbe simile per qualsiasi modello Python che stavi cercando di convertire, ma manterremo questo codice semplice in modo che tutti possano comprenderlo.

Modifichiamo il file test.py che abbiamo creato nella prima sezione e aggiorniamo il codice in questo modo:

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 gli x (input) e gli y (output) forniti. Il modello addestrato risultante verrà quindi salvato su disco. Consulta i commenti incorporati per ulteriori dettagli sugli scopi di ciascuna riga.

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

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

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

5. Conversione del formato SavedModel nel formato TensorFlow.js

Installa il convertitore TensorFlow.js

Per installare il convertitore, esegui questo comando:

Finestra del terminale:

pip3 install tensorflowjs

È stato facile.

Supponendo di utilizzare il convertitore della riga di comando (tensorflowjs_converter) e non la versione della procedura guidata mostrata sopra, possiamo richiamare 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 succede qui? Per prima cosa chiamiamo il programma binario tensorflowjs_converter appena installato e specifichiamo che stiamo cercando di convertire un modello salvato in keras.

Nel codice di esempio riportato sopra noterai che abbiamo importato keras e utilizzato i suoi strati di livello superiore API per creare il nostro modello. Se non hai utilizzato keras nel tuo codice Python, potresti voler usare un formato di input diverso:

  • keras: per caricare il formato keras (tipo di file HDF5)
  • tf_saved_model: per caricare un modello che utilizza le API principali di TensorFlow anziché keras.
  • tf_frozen_model: per caricare un modello che contiene pesi bloccati.
  • tf_hub: per caricare un modello generato dall'hub TensorFlow.

Puoi scoprire di più su questi altri formati qui.

I due parametri successivi specificano la cartella in cui si trova il modello salvato. Nella nostra demo precedente specifichiamo la directory corrente e infine specifichiamo in quale directory vogliamo generare la conversione, che abbiamo specificato sopra come cartella chiamata "predict_houses_tfjs" nella directory corrente.

L'esecuzione del comando riportato sopra crea una nuova cartella nella directory corrente denominata predict_houses_tfjs contenente:

  • model.json
  • Gruppo1-shard1of1.bin

Questi sono i file necessari per eseguire il modello nel browser web. Salva questi file perché verranno utilizzati nella prossima sezione.

6. Utilizzando il nostro modello convertito nel browser

Ospitare i file convertiti

Per prima cosa dobbiamo posizionare i nostri file model.json e *.bin generati su un server web, in modo da potervi accedere tramite la nostra pagina web. Per questa demo useremo Glitch.com per consentirti di seguire facilmente. Tuttavia, se fai parte del web engineering, puoi scegliere di attivare un semplice server http sulla tua attuale istanza del server Ubuntu. A te la scelta.

Caricamento di file su Glitch

  1. Accedi a Glitch.com.
  2. Utilizza questo link per clonare il nostro progetto TensorFlow.js boilerplate. Questo file contiene uno scheletro di file html, CSS e js che importa la libreria TensorFlow.js per noi pronta all'uso.
  3. Fai clic sugli "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, ora dovrebbe avere il seguente aspetto: 25a2251c7f165184.png
  5. Se fai clic sul file group1-shard1of1.bin che hai appena caricato, potrai copiare l'URL nella relativa 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 (Ctrl+F) il file group1-shard1of1.bin che verrà menzionato da qualche parte al suo interno.

Sostituisci il nome file con l'URL copiato dal passaggio 5, ma elimina il carattere https://cdn.glitch.com/ iniziale generato dal glitch dal percorso copiato.

Dopo la modifica, il file dovrebbe avere un aspetto simile al seguente (nota come il percorso del server principale è stato rimosso in modo da mantenere solo il nome del file caricato risultante): d5a338f2dc1f31d4.png 7. Ora salva e carica il file model.json modificato come glitch facendo clic sugli asset e poi su "Carica un asset". pulsante (importante). Se non utilizzi il pulsante fisico e lo trascini, il pulsante verrà caricato come file modificabile anziché sulla CDN, che non si trova nella stessa cartella e il percorso relativo viene utilizzato quando TensorFlow.js tenta di scaricare i file binari per un determinato modello. Se hai eseguito correttamente l'operazione, nella cartella assets dovresti vedere 2 file come questo: 51a6dbd5d3097ffc.png

Bene. Ora siamo pronti per utilizzare i nostri file salvati con del codice vero e proprio nel browser.

Caricamento del modello

Ora che abbiamo ospitato i nostri file convertiti, possiamo scrivere una semplice pagina web per caricare questi file e utilizzarli per fare una previsione. Apri script.js nella cartella del progetto Glitch e sostituisci i contenuti di questo file con quanto segue 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 l'output mostrato di seguito.

c5e8457213058ec3.png

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

35e79d70dbd66f27.png

Confrontando questo codice con il nostro codice Python all'inizio di questo codelab, possiamo confermare che si tratta della stessa rete che abbiamo creato con 1 input denso e uno strato denso con 1 nodo.

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

7. Modelli che non generano conversioni

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

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

5df94fc652393e00.png

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

Cosa fare?

Hai due opzioni.

  1. Implementa questa operazione mancante in TensorFlow.js. Siamo un progetto open source e siamo felici di ricevere contributi per cose 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 sul nostro convertitore della riga di comando per ignorare questo errore e continuare a effettuare la conversione (supporremo che questa operazione sia disponibile nella nuova build di TensorFlow.js che hai creato e che ha l'operazione mancante supportata).
  2. Determina quale parte del codice Python ha generato l'operazione non supportata nel file savedmodel che hai esportato. In un piccolo insieme di codice questo può essere facile da individuare, ma in modelli più complessi potrebbe richiedere molte indagini, 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 file savedmodel. Una volta individuata, tuttavia, puoi potenzialmente modificare questa impostazione per utilizzare un metodo diverso supportato.

8. Complimenti

Congratulazioni, hai fatto i primi passi nell'utilizzo di un modello Python tramite TensorFlow.js nel browser web.

Riepilogo

In questo codelab abbiamo imparato a:

  1. Configura il nostro ambiente Linux per installare TensorFlow basato su Python
  2. Esporta un "SavedModel" Python
  3. Installa il convertitore della riga di comando TensorFlow.js
  4. Utilizza il convertitore della riga di comando TensorFlow.js per creare i file lato client richiesti
  5. Usa i file generati in un'applicazione web reale
  6. Identificare i modelli che non si convertono e cosa occorre implementare per consentire una conversione in futuro.

Passaggi successivi

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

Altri codelab TensorFlow.js per approfondire

Siti web da controllare