TensorFlow.js: utilizzare Firebase Hosting per eseguire il deployment e ospitare un modello di machine learning su larga scala

1. Introduzione

Hai creato un modello di machine learning personalizzato con TensorFlow.js, ma ora devi ospitarlo da qualche parte per utilizzarlo su un sito web a tua scelta. Esistono molti modi per farlo, ma oggi vedremo quanto è facile utilizzare Firebase Hosting, che può anche offrire alcuni vantaggi aggiuntivi, come il controllo delle versioni, l'hosting di modelli su una connessione sicura e altro ancora, tutto pronto all'uso.

Cosa creerai

In questo codelab creerai un sistema end-to-end completo in grado di ospitare ed eseguire un modello TensorFlow.js salvato personalizzato insieme agli asset correlati come HTML, CSS e JavaScript. Creeremo un modello leggero molto semplice che possa prevedere un valore di output numerico in base a un valore di input (ad es. il prezzo di una casa in base ai suoi metri quadrati) e lo ospiteremo tramite Firebase Hosting in modo che possa essere utilizzato su larga scala.

Cosa imparerai a fare

  • Come salvare un modello TensorFlow.js personalizzato nel formato corretto
  • Come configurare un account Firebase per l'hosting
  • Come eseguire il deployment degli asset in Firebase Hosting
  • Come eseguire il deployment di nuove versioni di un modello.

Nota: l'obiettivo di questo laboratorio di codice è spiegare come prendere un modello addestrato personalizzato e ospitarlo per il deployment, anziché un corso sulla creazione dell'architettura del modello perfetta, quindi passeremo rapidamente alla creazione del modello di machine learning stesso con un esempio banale. I principi saranno gli stessi indipendentemente dal modello che finirai per creare.

Condividere con noi i tuoi contenuti

Se hai realizzato qualcosa di interessante utilizzando questa suite, non esitare a comunicarcelo. Ci farebbe piacere vedere le tue creazioni.

Taggaci sui social media utilizzando l'hashtag #MadeWithTFJS per avere la possibilità di mostrare il tuo progetto sul nostro blog di TensorFlow o anche in occasione di eventi futuri come i nostri Show & Tell.

2. Che cos'è Firebase Hosting?

Firebase Hosting offre un hosting di produzione rapido e sicuro per la tua app web, i contenuti statici / dinamici e i microservizi

Con un solo comando, puoi implementare rapidamente le app web e pubblicare contenuti su una CDN (Content Delivery Network) globale, assicurandoti che i contenuti siano disponibili con bassa latenza quasi ovunque. Puoi anche accoppiare Firebase Hosting con Cloud Functions o Cloud Run per creare e ospitare microservizi, ma questo argomento non rientra nell'ambito di questo codelab.

Funzionalità chiave di Firebase Hosting

  • Pubblica i contenuti su una connessione sicura: il web moderno è sicuro. Spesso, per accedere ai sensori lato client, il sito deve essere pubblicato in un contesto sicuro. La tecnologia SSL senza necessità di configurazione è integrata in Firebase Hosting, in modo che i contenuti siano sempre disponibili in totale sicurezza per tutti i file ospitati.
  • Ospita contenuti statici e dinamici, oltre a microservizi con supporto per l'autenticazione, in modo che solo gli utenti che hanno eseguito l'accesso possano caricare / visualizzare questi file, se lo desiderano.
  • Pubblica i contenuti rapidamente: ogni file caricato viene memorizzato nella cache delle unità SSD sui server perimetrali della rete CDN a livello globale. Ovunque si trovino gli utenti, i contenuti verranno distribuiti in tempi rapidi.
  • Esegui il deployment di nuove versioni con un solo comando: con l'interfaccia a riga di comando di Firebase, puoi avviare la tua app in pochi secondi.
  • Rollback con un solo clic: i deployment rapidi sono fantastici, ma la possibilità di annullare gli errori è ancora meglio. Firebase Hosting fornisce il controllo completo delle versioni e la gestione delle release grazie ai rollback che richiedono un solo clic.

Che tu stia eseguendo il deployment di una semplice pagina di destinazione dell'app o di una complessa app web progressiva (PWA), Hosting ti offre l'infrastruttura, le funzionalità e gli strumenti personalizzati per il deployment e la gestione di siti web e app.

Per impostazione predefinita, ogni progetto Firebase dispone di sottodomini senza costi sui domini web.app e firebaseapp.com. Questi due siti pubblicano gli stessi contenuti e la stessa configurazione di cui è stato eseguito il deployment. Se vuoi, puoi collegare il tuo nome di dominio anche a un sito ospitato su Firebase.

Passaggi per l'implementazione

Tuttavia, prima di poter procedere, dobbiamo eseguire il deployment di un modello di machine learning e di un'app web. Quindi, creane uno.

3. Un semplice modello di machine learning per prevedere i prezzi delle case

Ai fini di questo esercizio, creeremo un modello di ML molto semplice che preveda valori numerici. Proveremo a utilizzare il machine learning per prevedere il valore di una casa immaginaria in base alle sue dimensioni in metri quadrati solo a scopo illustrativo. In effetti, per questa demo moltiplicheremo semplicemente per 1000 i metri quadrati della casa per ottenere il valore previsto per i nostri dati di addestramento, ma il machine learning dovrà apprenderlo autonomamente.

In realtà, dovresti scegliere di utilizzare dati reali che potrebbero avere relazioni più complesse (ad esempio, per le case più piccole, il valore in dollari è solo 500 volte più grande delle dimensioni, ma dopo una certa soglia diventa gradualmente 1000 volte più grande e così via) e potresti aver bisogno di un modello più avanzato per scoprire il modo migliore per prevedere questi valori.

Il modello che creeremo oggi (regressione lineare) potrebbe essere utilizzato per prevedere molte altre cose, a condizione che siano disponibili dati sufficienti del mondo reale, ed è facile da iniziare a utilizzare per il nostro caso d'uso ipotetico riportato sopra. Tuttavia, oggi il nostro obiettivo è imparare a salvare e implementare un modello anziché progettarne e ottimizzarne uno per un determinato caso d'uso. Mettiamoci all'opera.

Dati di addestramento e test

Tutti i modelli ML iniziano con l'ottenimento di alcuni dati di addestramento di esempio che possiamo utilizzare per insegnare al modello a prevedere i valori in futuro. In genere, puoi acquisire questi dati da un database, una cartella di file, un file CSV o altro, ma qui imposteremo direttamente 20 esempi come array in JavaScript, come mostrato di seguito. Per il momento ti consigliamo di replicare questo codice in un ambiente in cui ti trovi a tuo agio, ad esempio Glitch.com, o nel tuo editor di testo locale se sei in grado di eseguire un server su localhost.

model.js

// House square footage.
const data =    [800, 850, 900, 950, 980, 1000, 1050, 1075, 1100, 1150, 1200, 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000];

// Estimated dollar cost of house for each piece of data above (1000x square footage).
const answers = [800000, 850000, 900000, 950000, 980000, 1000000, 1050000, 1075000, 1100000, 1150000, 1200000,  1250000 , 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000];

// Testing data separate from training data.
const dataTest =     [886, 1225, 500];
const answersTest =  [886000, 1225000, 500000];

Come puoi vedere, per ogni dato abbiamo un valore di risposta corrispondente, che è il valore che cercheremo di prevedere in futuro (puoi immaginarli come i valori x e y in un semplice grafico 2D).

Pertanto, per il valore 800,vogliamo produrre una stima della risposta in uscita di 800.000 $. Per il valore 900, viene visualizzato 900.000 $e così via. In sostanza, il numero viene moltiplicato per 1000. Tuttavia, il modello ML non conosce questa semplice relazione di 1000 * N e deve apprenderla autonomamente da questi esempi che forniamo.

Tieni presente che abbiamo anche alcuni dati di test completamente separati dai dati di addestramento. In questo modo possiamo valutare il modello addestrato per vedere come funziona con dati mai visti prima.

Caricheremo questo script insieme alla libreria TensorFlow.js utilizzando il seguente codice HTML:

train.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Training Model</title>
    <meta charset="utf-8">
  </head>  
  <body>   
    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
    <!-- Import our JS code to train the model -->
    <script src="/model.js" defer></script>
  </body>
</html>

Addestramento del modello

Ora è il momento di addestrare il modello aggiungendo il codice riportato di seguito al codice JS esistente sopra alla fine del file.

Sono stati aggiunti commenti per i curiosi, ma come accennato, questo codelab riguarda più l'hosting di un modello salvato. Se vuoi saperne di più sulla creazione del modello, alla fine sono disponibili altri codelab. Per il momento puoi copiare e incollare il codice nel tuo progetto.

model.js

// Create Tensor representations of our vanilla JS arrays above 
// so can be used to train our model.
const trainTensors = {
  data: tf.tensor2d(data, [data.length, 1]),
  answer: tf.tensor2d(answers, [answers.length, 1])
};

const testTensors = {
  data: tf.tensor2d(dataTest, [dataTest.length, 1]),
  answer: tf.tensor2d(answersTest, [answersTest.length, 1])
};


// Now actually create and define model architecture.
const model = tf.sequential();

// We will use one dense layer with 1 neuron and an input of 
// a single value.
model.add(tf.layers.dense({inputShape: [1], units: 1}));

// Choose a learning rate that is suitable for the data we are using.
const LEARNING_RATE = 0.0001;

train();

async function train() {
  // Compile the model with the defined learning rate and specify
  // our loss function to use.
  model.compile({
    optimizer: tf.train.sgd(LEARNING_RATE),
    loss: 'meanAbsoluteError'
  });

  // Finally do the training itself over 500 iterations of the data.
  // As we have so little training data we use batch size of 1.
  // We also set for the data to be shuffled each time we try 
  // and learn from it.
  let results = await model.fit(trainTensors.data, trainTensors.answer, {epochs: 500, batchSize: 1, shuffle: true});
  
  // Once trained we can evaluate the model.
  evaluate();
}

async function evaluate(stuff) {
  // Predict answer for a single piece of data.
  model.predict(tf.tensor2d([[768]])).print();
}

Utilizzando il codice riportato sopra, siamo riusciti ad addestrare un modello in grado di prevedere un valore di output in base al valore di input. Se eseguo il codice riportato sopra, ottengo una previsione di 768.073 per il valore di input 768, che viene stampato nella console per gli sviluppatori del browser (premi F12 per aprirla se non è già aperta). Si tratta di una stima abbastanza buona del prezzo della casa, dato che abbiamo fornito esempi 1000 volte superiori all'input. Nota: il valore previsto potrebbe essere leggermente diverso ed è normale.

Se il rendimento ci soddisfa, non ci resta che salvare il modello su disco per poterlo caricare su Firebase Hosting.

Salvataggio del modello

L'aggiunta del codice riportato di seguito alla fine della funzione di valutazione (dopo model.predict) sopra riportata ci consente di esportare il modello risultante al termine dell'addestramento direttamente dal browser web e salvarlo su disco in modo da poterlo poi ospitare da qualche parte e utilizzarlo in futuro senza dover ripetere l'addestramento ogni volta che carichiamo la pagina.

model.js

await model.save('downloads://my-model');

Se ora visiti train.html ed esegui la pagina, il modello dovrebbe essere addestrato (l'operazione potrebbe richiedere alcuni secondi) e, al termine, ti verrà chiesto di scaricare il modello addestrato risultante.

4. Configurazione di Firebase

Accedi a Firebase e crea un progetto

Se non hai mai utilizzato Firebase, la registrazione è facile con il tuo Account Google. Basta andare all'indirizzo https://firebase.google.com/ e accedere con il tuo Account Google normale che vuoi utilizzare. Dopo il reindirizzamento alla home page, fai clic su "Vai alla console" in alto a destra nella pagina:

ea7ff3f08e4019b0.png

Una volta reindirizzato alla console, dovresti vedere una pagina di destinazione simile alla seguente:

166d9408ad46599b.png

Basta fare clic su Aggiungi progetto come mostrato per creare un nuovo progetto Firebase, assegnare un nome univoco al progetto, accettare i termini e fare clic su Continua.

A questo punto ti verrà chiesto se vuoi aggiungere dati e analisi al tuo progetto. Se vuoi avere accesso a questi dati e analisi, non esitare ad attivare questa opzione e fai clic su Continua, come mostrato di seguito:

a34c2be47b26e6b5.png

Se tutto è andato a buon fine, dovresti visualizzare una pagina di progetto pronta come mostrato di seguito:

1306dc803ad22338.png

Bene! Abbiamo un progetto. Fai clic su Continua per accedere alla console del progetto appena creato. Tieni aperta la pagina per utilizzarla in un secondo momento, ma per il momento dobbiamo installare alcuni strumenti.

Installazione e connessione dell'interfaccia a riga di comando

Firebase è disponibile come pacchetto NPM Node che puoi installare e utilizzare tramite l'interfaccia a riga di comando (CLI), che semplifica il deployment di file e cartelle locali su Firebase Hosting. Per il tutorial di oggi utilizzeremo un ambiente Linux, ma se hai Windows o Mac, puoi seguire le istruzioni qui per configurare gli strumenti CLI sul tuo dispositivo.

Su Linux, tuttavia, installeremo prima NPM e Node.js, se non sono già presenti (segui queste istruzioni se utilizzi altri ambienti) utilizzando i seguenti 3 comandi in una finestra del terminale:

Terminale a riga di comando:

sudo apt update

Terminale a riga di comando:

sudo apt install nodejs

Terminale a riga di comando:

sudo apt install npm

Ora che hai installato Node.js e NPM, devi semplicemente eseguire quanto segue in una finestra del terminale per installare gli strumenti a riga di comando Firebase:

Terminale a riga di comando:

sudo npm install -g firebase-tools

Bene. Ora siamo pronti a collegare il nostro progetto Firebase al nostro sistema per poter inviare file e altro ancora.

Accedere a Firebase

Accedi a Firebase utilizzando il tuo Account Google eseguendo il seguente comando:

Terminale a riga di comando:

firebase login

Ti verrà chiesto di concedere l'accesso al tuo account Firebase Google, come mostrato di seguito:

4dc28589bef2ff5d.png

Se lo consenti, dovresti finalmente visualizzare una connessione riuscita degli strumenti a riga di comando al tuo account Firebase:

df397ec7a555e8de.png

Chiudi la finestra e torna al terminale a riga di comando in cui stavi digitando in precedenza, che ora dovrebbe essere pronto ad accettare nuovi comandi come mostrato (abbiamo nascosto le informazioni private nello screenshot):

67a3ff39d3c0f3e4.png

Complimenti! Ora siamo pronti a inviare i file al progetto creato dalla nostra macchina locale.

Inizializza il progetto per il deployment in Firebase Hosting

Per collegare la tua cartella locale al progetto Firebase, esegui il seguente comando dalla directory principale del progetto locale (la cartella da cui vuoi caricare i file durante il deployment).

Terminale a riga di comando:

firebase init

Dopo aver eseguito questo comando, segui le istruzioni nel terminale per completare la configurazione come mostrato di seguito:

61e0f6d92ef3e1c4.png

Qui possiamo semplicemente selezionare Hosting utilizzando la Freccia giù sulla tastiera, quindi premere Barra spaziatrice per selezionare e Invio per confermare.

Ora possiamo selezionare il progetto esistente che abbiamo creato in precedenza da utilizzare:

4f2a1696d5cfd72f.png

Premi Invio su "Utilizza un progetto esistente" e poi selezionalo utilizzando il tasto Freccia giù come mostrato di seguito:

4dfcf2dff745f2c.png

Infine, premi Invio per utilizzarlo, accetta i valori predefiniti nella schermata finale visualizzata e rispondi "No" per configurarlo come applicazione a pagina singola:

7668a2175b624af2.png

In questo modo potrai ospitare più pagine HTML, se vuoi.

Ora che l'inizializzazione è completata, noterai che è stato creato un file firebase.json e una cartella "public" nella directory in cui abbiamo eseguito i comandi precedenti.

cd7724b92f3d507.png

Ora non ci resta che spostare i file che vogliamo eseguire nella cartella pubblica che abbiamo creato e il deployment sarà pronto. Ed è quello che faremo ora.

5. Creazione della pagina web TensorFlow.js

Caricamento del modello salvato

Innanzitutto, assicuriamoci di copiare il modello di machine learning salvato in precedenza nel codelab nella nostra cartella pubblica appena creata con Firebase. Trascina semplicemente i file salvati in questa cartella, come mostrato di seguito:

cd6f565189e23705.png

Noterai anche che Firebase ha creato i file index.html e 404.html per noi. Andiamo avanti e modifichiamo il file index.html utilizzando il tuo editor di testo preferito sul computer per poter aggiungere il nostro codice personalizzato come mostrato:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Hello World - TensorFlow.js</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Import the webpage's stylesheet -->
    <link rel="stylesheet" href="style.css">
  </head>  
  <body>
    <h1>TensorFlow.js Hello World</h1>
    <p>Check the console (Press F12) to see predictions!</p>
    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>

    <!-- Import the page's JavaScript to do some stuff -->
    <script src="script.js" defer></script>
  </body>
</html>

Nel nuovo codice per index.html riportato sopra specifichiamo uno stile in modo da poter aggiungere uno stile alla pagina in un secondo momento, se lo vogliamo, e anche script.js per ospitare il codice che dobbiamo scrivere per utilizzare il modello salvato di TensorFlow.js.

Ora crea questi file e compilali come segue in modo che siano utili:

style.css

/** Leave blank for now **/

script.js

// Load our saved model from current directory (which will be 
// hosted via Firebase Hosting)
async function predict() {
  // Relative URL provided for my-model.json.
  const model = await tf.loadLayersModel('my-model.json');
  // Once model is loaded, let's try using it to make a prediction!
  // Print to developer console for now.
  model.predict(tf.tensor2d([[1337]])).print();
}

predict();

Se hai seguito correttamente i passaggi, nella cartella pubblica che abbiamo creato dovresti vedere i seguenti file modificati:

253498c703c04ee.png

Ora non ci resta che eseguire il deployment dei file per verificare che funzionino.

6. Eseguire il deployment del modello e del sito web

Trasmissione dal vivo

Torna alla finestra del terminale che hai aperto nella cartella del progetto Firebase della tua macchina locale (questa è la cartella che contiene la cartella "public" sopra insieme ai file di inizializzazione di Firebase).

Digita quanto segue per eseguire il deployment dei file della cartella pubblica:

Terminale a riga di comando:

firebase deploy

Attendi il completamento del comando del terminale. La release dovrebbe essere completata correttamente e dovresti visualizzare l'URL che puoi utilizzare per utilizzarla:

c5795cae85ed82a5.png

Nell'esempio riportato sopra, puoi vedere che l'URL finale per visualizzare il nostro deployment è:

https://tensorflow-js-demo.web.app (ma il tuo URL sarà il nome del progetto che hai creato).

Apri questo URL in un browser web per verificare che funzioni. Se l'operazione va a buon fine, nella console dello sviluppatore della pagina che apri dovrebbe essere visualizzato qualcosa di simile (premi F12 per aprire la console dello sviluppatore).

182aee0acfa7c41e.png

Come puoi vedere, la pagina viene caricata nel dominio di cui è stato eseguito il deployment e possiamo vedere correttamente la previsione del nostro modello per 1337 piedi quadrati, che corrisponde a 1.336.999,25 $, una stima davvero molto buona, dato che ci aspettavamo che fosse 1000 volte superiore. Ovviamente possiamo fare tutte le previsioni che vogliamo se creiamo una bella interfaccia utente per chiamare il modello, il tutto verrà eseguito interamente in JavaScript mantenendo le tue query private e sicure.

Ora che il modello è stato implementato e ospitato, puoi condividere il sito web con chiunque nel mondo, che potrà utilizzare la tua applicazione sul proprio computer. Chiaramente, potresti voler aggiungere un'interfaccia utente migliore e renderla accattivante, ma questo non rientra nell'ambito di questo tutorial. Non esiste un limite alle possibili app web che puoi ospitare come questa basata sul machine learning che può funzionare con un solo clic senza bisogno di installazione. Ti invitiamo a pensare ad altre situazioni che potrebbero trarre vantaggio da un modello di machine learning in browser.

Monitoraggio dell'utilizzo

Oltre a Google Analytics, che puoi aggiungere al codice del tuo sito web, Firebase offre anche statistiche sulle versioni e sull'utilizzo tramite la console del tuo progetto. Dopo il deployment, vedrai qualcosa di simile a quanto segue, che puoi controllare di volta in volta in base alle esigenze:

42b1cb8f7c10016.png

fbdd6504bec7c3d.png

Come puoi vedere, per impostazione predefinita, nel livello senza costi hai a disposizione 10 GB di larghezza di banda al mese per i file ospitati. Se il tuo sito è più popolare, potresti dover aggiungere un account di fatturazione per utilizzarne di più in un determinato mese. Puoi consultare i piani Firebase per progetti più grandi qui, anche se la maggior parte degli utenti occasionali per i prototipi probabilmente non supererà il livello senza costi se il tuo modello è di piccole dimensioni e l'utilizzo è ridotto. Questo è un ottimo modo per testare e verificare che soddisfi le tue esigenze prima di impegnarti con un piano a pagamento man mano che la tua attività o idea cresce.

7. Complimenti

Congratulazioni, hai fatto i primi passi nell'utilizzo di TensorFlow.js con Firebase per creare ed eseguire il deployment di un modello di machine learning personalizzato in modo da poterlo condividere con il mondo. Immagina tutte le altre cose che potresti creare utilizzando questo approccio potente e scalabile, che è pronto per i casi d'uso di produzione, se vuoi, perché Firebase si adatta automaticamente alla domanda, quindi non importa se 10 o 10.000 utenti vogliono utilizzarlo, funzionerà.

Se modifichi uno dei file, esegui nuovamente il deployment dell'app utilizzando firebase deploy come prima e assicurati di svuotare la cache del browser per assicurarti di ottenere la nuova versione dei file al successivo caricamento della pagina. Se hai aperto gli strumenti per sviluppatori, puoi forzare questa impostazione nella scheda Rete durante i test selezionando la casella di controllo "Disattiva cache" nella parte superiore della scheda:

b1e4c1bf304a4869.png

Riepilogo

In questo lab di codice:

  1. Abbiamo definito e addestrato un modello TensorFlow.js personalizzato completamente da zero per prevedere i prezzi delle case.
  2. Hai eseguito la registrazione, la configurazione e l'installazione degli strumenti Firebase e Firebase CLI sulla tua macchina di sviluppo.
  3. Abbiamo implementato e lanciato un sito web funzionante che carica il nostro modello addestrato dal passaggio 1 e lo utilizza in un'applicazione web reale a cui chiunque può accedere da qualsiasi parte del mondo su larga scala.

Passaggi successivi

Ora che hai una base di lavoro da cui partire, quali idee creative puoi trovare per estendere questo boilerplate di deployment del modello di machine learning?

Saremmo lieti di vederti utilizzare questa funzionalità con i tuoi dati. Pensa al settore o al contesto in cui vivi o lavori. Come potresti addestrare un modello su questi dati per fare previsioni che potrebbero essere utili a te (o ad altri) in futuro? L'immobiliare non è l'unico esempio e ti invitiamo ad applicare questo approccio anche alle tue sfide. Buon hacking!

Ricordati di taggarci in tutto ciò che crei utilizzando l'hashtag #MadeWithTFJS (fai clic su questo link per trovare ispirazione in ciò che hanno creato gli altri) per avere la possibilità di essere messo in evidenza sui social media o addirittura mostrato in occasione di eventi TensorFlow futuri. Ci piacerebbe vedere cosa crei e, naturalmente, contattare l'autore di questo codelab in caso di feedback o domande.

Altri codelab su TensorFlow.js per approfondire

Siti web da consultare