TensorFlow.js:使用 Firebase 託管,大規模部署及託管機器學習模型

1. 簡介

您已使用 TensorFlow.js 建立自訂機器學習模型,但現在需要將模型代管在某處,以便在所選網站上使用。這麼做的方法有很多,但今天我們要來瞭解如何輕鬆使用 Firebase 託管,這項服務還提供許多額外好處,例如版本控制、透過安全連線提供模型,以及更多即用功能。

建構項目

在本程式碼實驗室中,您將建立完整的端對端系統,能夠代管及執行自訂儲存的 TensorFlow.js 模型,以及相關資產,例如 HTML、CSS 和 JavaScript。我們會建立一個非常簡單的輕量模型,在給定某些輸入值 (例如房屋的平方英尺數) 時,預測數值輸出值,並透過 Firebase 代管服務託管模型,以便大規模使用。

課程內容

  • 如何以正確的格式儲存自訂 TensorFlow.js 模型
  • 如何設定 Firebase 帳戶以便託管
  • 如何將素材資源部署至 Firebase 託管
  • 如何部署模型的新版本。

請注意:這個程式碼研究室的重點是如何使用自訂訓練模型並代管該模型以便部署,而非建立完美模型架構的課程,因此我們會快速透過簡單的範例說明如何建立機器學習模型。無論您最後建立哪種模型,原則都相同。

與我們分享你的創作

如果您使用這個堆疊打造出有趣的成果,歡迎與我們分享!我們很期待看到你的創作。

使用 #MadeWithTFJS 主題標記在社群媒體上標記我們,你的專案就有機會登上 TensorFlow 網誌,甚至是日後的展演秀等活動。

2. 什麼是 Firebase 託管?

Firebase 代管可為您的網路應用程式、靜態 / 動態內容和微服務提供快速又安全的實際執行環境等級代管服務

只要下達一個指令,即可快速部署網路應用程式,並將內容提供至全球內容傳遞聯播網 (CDN),確保內容幾乎隨時隨地都能以低延遲時間提供。您也可以將 Firebase 託管與 Firebase Cloud FunctionsCloud Run 配對,以便建構及代管微服務,但這超出本程式碼研究室的範圍。

Firebase 代管服務的主要功能

  • 透過安全連線提供內容 - 現代網際網路是安全的。通常,您必須透過安全的環境才能存取用戶端端點的感應器。Firebase 代管內建零設定 SSL,因此可以持續安全遞送託管的所有檔案。
  • 託管靜態和動態內容,以及支援驗證的微服務,這樣一來,只有登入的使用者才能載入 / 查看這些檔案。
  • 快速傳送內容:您上傳的每個檔案都會以快取形式儲存在全球 CDN 邊緣伺服器的固態硬碟 (SSD)。無論使用者位在哪裡,都能快速傳遞內容。
  • 透過單一指令部署新版本 - 使用 Firebase 指令列介面,您可以在幾秒內啟動並執行應用程式。
  • 一鍵復原 - 快速部署固然不錯,但如果能撤銷錯誤會更好。Firebase 託管提供完整的版本設定與版本管理功能,按一下即可執行復原程序。

無論您要部署簡單的應用程式到達網頁,還是複雜的漸進式網頁應用程式 (PWA),代管服務都能提供專為部署及管理網站和應用程式而設計的基礎架構、功能和工具。

根據預設,每個 Firebase 專案都會在 web.app 和 firebaseapp.com 網域上擁有免費子網域。這兩個網站提供相同的部署內容和設定。如有需要,您也可以將自有的網域名稱連結至 Firebase 代管的網站。

導入步驟

不過,我們必須先部署機器學習模型和網頁應用程式,才能執行上述操作。那麼,我們來建立一個吧!

3. 用來預測房價的簡單機器學習模型

為了完成本練習,我們將建立一個非常簡單的 ML 模型,用來預測數值。我們將嘗試使用機器學習技術,根據虛構房屋的平方英尺大小預測房屋價值,僅供說明用途。事實上,在這個示範中,我們只需將房屋的平方英尺數量乘以 1000,即可取得訓練資料的預測值,但機器學習需要自行學習這項技能。

實際上,您會選擇使用可能具有更複雜關係的實際資料 (例如,較小房屋的估價美元價值可能只有房屋大小的 500 倍,但超過特定門檻後,就會逐漸變成 1000 倍),因此您可能需要更進階的模型,才能瞭解預測這些值的最佳方式。

我們今天要建立的模型 (線性迴歸) 可用於預測許多其他事物 (前提是擁有足夠的實際資料),而且只要針對上述假設用途開始使用,就能輕鬆上手。不過,今天我們將著重於瞭解如何儲存及部署模型,而非針對特定用途設計及最佳化模型。那麼,讓我們開始吧!

訓練與測試資料

所有機器學習模型都會先取得一些訓練資料範例,以便教導模型預測未來的值。通常您可以從資料庫、檔案資料夾、CSV 等來源取得這類資料,但我們會直接將 20 個範例硬編為 JavaScript 中的陣列,如下所示。建議您在目前方便編寫程式的環境中複製這段程式碼,例如 Glitch.com,或是在本機上執行伺服器時使用您自己的文字編輯器。

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];

如您所見,每個資料都有對應的答案值,也就是我們日後會嘗試預測的值 (您可以將這些值視為簡單 2D 圖表中的 x 和 y 值)。

因此,對於值 800,我們希望產生 $800,000 美元的輸出答案預估值。對於值為 900 的值,我們會輸出 $900,000,以此類推。基本上,這個數字會乘以 1000。不過,機器學習模型不知道 1000 * N 這個簡單的關係,必須從我們提供的這些範例自行學習。

請注意,我們也有一些測試資料,與訓練資料完全分開。這可讓我們評估訓練好的模型,瞭解模型在未知資料上的成效。

我們將使用以下 HTML 載入此指令碼和 TensorFlow.js 程式庫:

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>

訓練模型

接著,請在檔案結尾的現有 JS 程式碼中加入下列程式碼,訓練模型。

我們已為好奇的讀者新增註解,但如前文所述,本程式碼研究室主要講解如何取得已儲存的模型並代管。如要進一步瞭解模型建立程序,請參閱結尾的其他程式碼研究室。目前您可以將程式碼複製並貼到專案中。

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();
}

使用上述程式碼,我們已能訓練出可根據輸入值預測輸出值的模型。執行上述程式碼後,我得到的預測值為 768,073,這個值會印到瀏覽器的開發人員控制台 (如果尚未開啟,請按下 F12 鍵)。這是相當不錯的房價估算值,因為我們提供的範例比輸入值高出 1000 倍。注意:系統預測的值可能會略有不同,這屬於正常現象。

如果您對這項效能感到滿意,現在只需將這個模型儲存到磁碟,即可上傳至 Firebase 託管服務!

儲存模型

將下列程式碼新增至 evaluate 函式結尾 (上方 model.predict 之後),即可在訓練完成後直接從網路瀏覽器匯出產生的模型,並儲存至磁碟,以便日後在某處代管並使用,而不需要每次載入網頁時都重新訓練。

model.js

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

如果現在前往 train.html 並執行該頁面,系統應會訓練模型 (可能需要幾秒鐘的時間),然後在完成後提示您下載訓練完成的模型。

4. 設定 Firebase

登入 Firebase 並建立專案

如果您是 Firebase 新手,可以輕鬆使用 Google 帳戶註冊。只要前往 https://firebase.google.com/,然後使用您要使用的一般 Google 帳戶登入即可。系統會將您重新導向至首頁,請按一下頁面右上方的「前往主控台」:

ea7ff3f08e4019b0.png

重新導向至主控台後,您應該會看到類似以下的到達網頁:

166d9408ad46599b.png

只要按一下「新增專案」即可建立新的 Firebase 專案,為專案命名,接受條款,然後按一下「繼續」。

系統會詢問您是否要將數據分析加入專案。如果您想存取這類數據分析,請啟用這個選項,然後點選「繼續」,如下所示:

a34c2be47b26e6b5.png

如果一切順利,您應該會看到如下所示的專案就緒頁面:

1306dc803ad22338.png

太厲害了!我們有專案。按一下「繼續」,即可前往新建專案的主控台。請將這個頁面保持開啟狀態,以便稍後使用,但我們現在必須安裝一些工具。

安裝及連線 CLI

Firebase 可做為 Node NPM 套件提供,您可以透過指令列介面 (CLI) 安裝及使用,輕鬆將本機檔案和資料夾部署至 Firebase 託管。在今天的教學課程中,我們將使用 Linux 環境,但如果您使用的是 Windows 或 Mac,可以按照這裡的操作說明在裝置上設定 CLI 工具。

不過,如果您在 Linux 上使用其他環境,請按照 這些操作說明操作,在終端機視窗中使用以下 3 個指令,先安裝 NPM 和 Node.js (如果尚未安裝):

指令列終端機:

sudo apt update

指令列終端機:

sudo apt install nodejs

指令列終端機:

sudo apt install npm

在安裝 Node.js 和 NPM 後,只要在終端機視窗中執行下列指令,即可安裝 Firebase 指令列工具:

指令列終端機:

sudo npm install -g firebase-tools

太好了!我們現在可以將 Firebase 專案連結至系統,以便將檔案推送至該系統,以及執行其他操作。

登入 Firebase

執行下列指令,使用 Google 帳戶登入 Firebase:

指令列終端機:

firebase login

系統會要求您授予 Google Firebase 帳戶存取權,如下所示:

4dc28589bef2ff5d.png

允許這項權限後,您應該會看到指令列工具成功連結至 Firebase 帳戶:

df397ec7a555e8de.png

關閉視窗,然後返回先前輸入指令的命令列終端機,現在應該可以接受新的指令了,如下圖所示 (我們已隱藏螢幕截圖中的任何私人資訊):

67a3ff39d3c0f3e4.png

恭喜!我們現在可以從本機電腦將檔案推送至已建立的專案。

初始化專案,以便部署至 Firebase 託管

如要將本機資料夾連結至 Firebase 專案,請在本機專案目錄的根目錄 (您要在部署時用來上傳檔案的資料夾) 中執行下列指令。

指令列終端機:

firebase init

執行這項指令後,只要按照終端機中的操作說明完成設定即可,如下所示:

61e0f6d92ef3e1c4.png

這裡我們可以直接使用鍵盤上的向下箭頭選取「Hosting」,然後按下空格鍵選取,再按下 Enter 鍵確認

我們現在可以選取先前建立的現有專案:

4f2a1696d5cfd72f.png

按下「Use an existing project」的 Enter 鍵,然後使用向下鍵選取該專案,如下所示:

4dfcf2dff745f2c.png

最後按下 Enter 鍵即可使用,然後接受彈出式畫面上的預設值,並說「否」來將其設為單頁應用程式:

7668a2175b624af2.png

這樣一來,您就能選擇代管多個 HTML 網頁。

初始化完成後,您會發現在執行上述指令的目錄中,已建立 firebase.json 檔案和「public」資料夾。

cd7724b92f3d507.png

接下來,我們只需將要部署的檔案移至我們建立的公開資料夾,即可部署!開始行動吧。

5. 建立 TensorFlow.js 網頁

載入已儲存的模型

首先,請務必將先前在程式碼研究室中儲存的機器學習模型,複製到剛剛透過 Firebase 建立的公開資料夾。只要將已儲存的檔案拖曳到這個資料夾即可,如下圖所示:

cd6f565189e23705.png

您也會發現 Firebase 為我們建立了 index.html 和 404.html 檔案。接下來,我們將使用電腦上喜愛的文字編輯器編輯 index.html,以便新增自訂程式碼,如下所示:

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>

在上述 index.html 的新程式碼中,我們指定了樣式表單,以便日後視需要為網頁新增樣式,同時也使用 script.js 來代管我們需要編寫的程式碼,以便使用 TensorFlow.js 儲存的模型。

我們現在就來建立這些檔案,並按照以下方式填入內容,讓這些檔案發揮作用:

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();

如果您已正確完成步驟,現在應該會在我們建立的公開資料夾中看到下列已編輯的檔案:

253498c703c04ee.png

我們現在只需要部署檔案,即可檢查是否正常運作!

6. 部署模型和網站

進行直播

返回您在本機電腦的 Firebase 專案資料夾中開啟的終端機視窗 (這個資料夾包含上述的「public」資料夾,以及 Firebase 初始化檔案)。

只要輸入下列指令,即可部署公用資料夾檔案:

指令列終端機:

firebase deploy

等待終端機指令完成,您應該會看到成功發布完成的訊息,以及可用來使用該版本的網址:

c5795cae85ed82a5.png

在上述範例中,您可以看到最終的部署網址如下:

https://tensorflow-js-demo.web.app (但網址會是您建立的專案名稱)。

在網路瀏覽器中開啟這個網址,確認是否正常運作。如果成功,您開啟的網頁開發人員工作階段應會顯示類似以下的內容 (按下 F12 鍵即可開啟開發人員工作階段)。

182aee0acfa7c41e.png

您可以看到頁面已在已部署的網域上載入,而且我們可以正確看到模型預測的 1337 平方英尺,結果為 $1,336,999.25 美元,這項估算值非常準確,因為我們預期這項估算值會是平方英尺的 1000 倍。當然,如果我們建立了方便使用的使用者介面來呼叫模型,我們就能盡情進行預測,而且這一切都會在 JavaScript 中執行,確保您的查詢隱密且安全。

模型已部署並代管,您可以與全球任何人分享網站,讓他們在自己的電腦上使用應用程式。您可能會想加入更好的使用者介面,讓介面看起來更出色,但這超出本教學課程的範圍。您可以託管的機器學習輔助網路應用程式不限於上述範例,只要點按一下即可運作,完全不需要安裝,我們也鼓勵您思考其他可從瀏覽器內機器學習模型中受益的情況。

監控用量

除了您可能會新增至網站程式碼的 Google Analytics 外,Firebase 也會透過專案的控制台提供版本和使用率統計資料。部署完成後,您會看到類似下方的畫面,可視需要不時查看:

42b1cb8f7c10016.png

fbdd6504bec7c3d.png

如您所見,在免費方案中,您每月可為代管檔案提供 10 GB 的頻寬。如果您的網站更受歡迎,您可能需要新增帳單帳戶,才能在特定月份使用超過這個數量。您可以前往這個頁面查看較大型專案適用的 Firebase 方案,不過如果模型較小且使用率偏低,大多數的簡易原型概念使用者可能不會超過免費方案的限制,因此在您決定採用付費方案時,可以先透過這個方式測試及確認是否符合需求,再根據業務或構想的發展情況,決定是否要採用付費方案。

7. 恭喜

恭喜!您已開始使用 TensorFlow.js 和 Firebase 建構及部署自訂機器學習模型,並將模型分享給全世界。您可以運用這項強大且可擴充的做法,製作出其他應用程式,如果需要,您也可以將其用於正式環境,因為 Firebase 會根據需求自動擴充,因此無論有 10 或 10,000 位使用者想使用這項功能,都會正常運作。

如果您變更任何檔案,只要使用 Firebase 部署功能重新部署應用程式即可,並務必清除瀏覽器快取,確保下次載入網頁時,您會取得新版檔案。如果您已開啟開發人員工具,在測試時,您可以透過在網路分頁下方選取「停用快取」核取方塊,在這個分頁頂端附近輕鬆完成這項操作:

b1e4c1bf304a4869.png

重點回顧

在本程式碼研究室中,我們:

  1. 從頭開始定義及訓練自訂的 TensorFlow.js 模型,以預測房價。
  2. 在開發機器上註冊、設定及安裝 Firebase 和 Firebase CLI 工具。
  3. 部署並啟用可運作的網站,從第 1 步驟載入訓練好的模型,並在實際的網頁應用程式中使用,讓全球各地的使用者都能大規模存取。

後續步驟

您現在有了可用的基礎,可以發揮創意,擴充這個機器學習模型部署範本嗎?

我們很樂意看到您使用這項功能處理自己的資料。思考您居住或工作的產業或地區。您可以如何訓練這類資料,以便日後為您 (或其他人) 做出有用的預測?房地產只是其中一個例子,我們也鼓勵您將這項做法應用於自己的挑戰。祝您駭客愉快!

請記得在您使用 #MadeWithTFJS 標記的任何內容中標記我們 (按一下這個連結,即可查看他人的作品,獲得靈感),有機會在社群媒體上亮相,甚至在日後的 TensorFlow 活動中展示!我們很樂意看到您製作的內容,當然,如果您有任何意見或問題,也歡迎與這個程式碼研究室的作者聯絡。

更多 TensorFlow.js 程式碼研究室,讓您深入瞭解

值得一看的網站