TensorFlow.js:將 Python Dialogflow 轉換為 TensorFlow.js 格式

1. 簡介

您已踏出第一步,開始使用 TensorFlow.js、試試我們預先建立的模型,甚至可以自行建立。不過,您在 Python 中發現一些頂尖的研究結果,想要看看是否能夠在網路瀏覽器中執行,以便運用可擴充的方式,讓數百萬人認識這個酷炫構想。聽起來是不是很熟悉?如果有,歡迎參考 CodeLab!

TensorFlow.js 團隊透過指令列轉換器,將採用 SavedModel 格式的模型轉換為 TensorFlow.js,因此您可以放心使用這類模型,且可達網路的規模與規模。

課程內容

在本程式碼研究室中,您將瞭解如何使用 TensorFlow.js 指令列轉換工具,將 Python 產生的 Engage 代碼移植為 model.json 格式,以便在網路瀏覽器的用戶端中執行。

詳細說明:

  • 如何建立簡易的 Python 機器學習模型,並將其儲存為 TensorFlow.js 轉換工具所需的格式。
  • 如何在您從 Python 匯出的 module 上安裝及使用 TensorFlow.js 轉換工具。
  • 取得轉換產生的檔案,並在 JS 網頁應用程式中使用。
  • 瞭解發生問題時的因應方式 (並非所有模式都會轉換) 和你有哪些選項。

想像一下,我們可以接受一些最新發表的研究,並將該模型提供給全球數百萬的 JS 開發人員。或者,您也可以自行創作內容,讓全世界的使用者透過網路瀏覽器執行,不必使用複雜的依附元件或環境設定。準備好要入侵廣告了嗎?立即開始!

歡迎與我們分享你轉換的相關資訊!

您可以使用我們今天學到的內容,嘗試轉換一些您最愛的 Python 模型。如果您成功達成目標,並製作能實際運作的模型示範網站,可以使用 #MadeWithTFJS 主題標記在社群媒體上標記我們,讓您的應用程式有機會登上我們的 TensorFlow 網誌,甚至日後展示和公布活動。我們樂見著更多令人驚豔的研究成果移植到網路上,讓更多人以創新或創意的方式使用這類模型,就像這個絕佳範例

2. 什麼是 TensorFlow.js?

1aee0ede85885520.png

TensorFlow.js開放原始碼的機器學習程式庫,可以在 JavaScript 中的任何位置執行。這個程式庫是以以 Python 編寫的原始 TensorFlow 程式庫為基礎,旨在重新建立 JavaScript 生態系統適用的一組開發人員體驗和 API。

哪些地方可以使用?

由於 JavaScript 具備可攜性,現在您可以使用 1 種語言來編寫程式碼,並在下列所有平台上輕鬆執行機器學習:

  • 運用基本 JavaScript,在網路瀏覽器的用戶端
  • 使用 Node.js 的伺服器端,甚至是 Raspberry Pi 等 IoT 裝置
  • 使用 Electron 的電腦版應用程式
  • 使用 React Native 的原生行動應用程式

TensorFlow.js 也支援這些環境中的多個後端,也就是可在 CPU 或 WebGL 等內部執行的實際硬體型環境。「後端」在這個情況下,並不表示伺服器端環境。舉例來說,執行作業的後端可能是 WebGL 中的用戶端,可確保相容性,同時讓執行速度飛快。目前 TensorFlow.js 支援:

  • 在裝置的顯示卡上執行 WebGL (GPU):這是在 GPU 加速功能下執行大型模型 (大小超過 3 MB) 的最快方法。
  • 在 CPU 上執行網路組合 (WASM):提升各裝置的 CPU 效能 (例如較舊的手機)。這種級別更適用於小型模型 (大小小於 3 MB),比起使用 WebGL,實際執行 WASM 的 CPU 執行速度較 WebGL,因為將內容上傳至圖形處理器時須耗用大量資源。
  • CPU 執行:若其他環境都無法使用,備用機制就應該沒有問題。這是最慢的圖示,但系統能隨時為您效勞。

注意:如果你知道要在哪個裝置上執行,可以選擇強制執行其中一個後端;如未指定,也可以直接讓 TensorFlow.js 決定。

用戶端超能力

在用戶端電腦的網路瀏覽器中執行 TensorFlow.js,能夠帶來許多值得評估的好處。

隱私權

您可以在用戶端電腦上訓練及分類資料,而不必將資料傳送至第三方網路伺服器。在某些情況下,可能需要遵守 GDPR 等當地法律,或者在處理使用者可能想保留在電腦上的資料,而不傳送至第三方時。

速度

由於您不需要將資料傳送至遠端伺服器,推論 (資料分類) 可以更快。更棒的是,在使用者授予您存取權的情況下,您可以直接存取裝置的感應器,例如相機、麥克風、GPS、加速計等。

觸及範圍廣大

全球使用者只要按一下您傳送給自己的連結,就能在瀏覽器中開啟網頁,並且使用您製作的內容。您不必透過 CUDA 驅動程式進行複雜的伺服器端 Linux 設定,而不只是透過機器學習系統完成。

費用

不需要伺服器,只要付費使用 CDN 代管 HTML、CSS、JS 和模型檔案即可。CDN 的費用比讓全天候運作的伺服器 (可能附有顯示卡) 便宜許多。

伺服器端功能

運用 TensorFlow.js 的 Node.js 實作可啟用下列功能。

完整的 CUDA 支援

在伺服器端,如要加速顯示顯示卡,您必須安裝 NVIDIA CUDA 驅動程式,才能使用 TensorFlow 搭配顯示卡 (這點與使用 WebGL 的瀏覽器不同,不需要安裝)。不過,享有完整的 CUDA 支援,可充分運用顯示卡層級較低的功能,加快訓練和推論速度。效能與 Python TensorFlow 實作不相上下,因為兩者都共用相同的 C++ 後端。

型號大小

針對研究提供的先進模型,您可能需要處理非常大型的模型 (可能多達 GB)。由於每個瀏覽器分頁的記憶體用量限制,這些模型目前無法在網路瀏覽器中執行。如要執行這類大型模型,您可以在自己的伺服器上使用 Node.js,同時將必要的硬體規格設為有效率地執行這類模型。

IOT

Node.js 支援熱門的單板電腦 (例如 Raspberry Pi),因此您也可以在這類裝置上執行 TensorFlow.js 模型。

速度

Node.js 是以 JavaScript 編寫,因此只需進行時間編譯即可。這表示您在使用 Node.js 時,通常可以發現效能提升,因為 Node.js 會在執行階段進行最佳化,特別是您執行的任何預先處理作業。透過這份個案研究,您可以看出 Hugging Face 如何運用 Node.js,將自然語言處理模型的效能提升 2 倍。

現在您已瞭解 TensorFlow.js 的基本功能、可在何處執行,以及一些優點,讓我們開始運用 TensorFlow.js 有效執行各項工作了!

3. 設定系統

在本教學課程中,我們將使用 Ubuntu 這個熱門的 Linux 發行版本。如果選擇使用雲端式虛擬機器,則 Google Cloud Compute Engine 可做為基本映像檔使用。

編寫當時,當建立新的基本 Compute Engine 執行個體時,可以選擇 Ubuntu 18.04.4 LTS 的映像檔,並將要使用的映像檔版本。當然,您也可以選擇使用自己的電腦,甚至是不同的作業系統,但各系統的安裝指示和依附元件可能有所不同。

安裝 TensorFlow (Python 版本)

就目前而言,您可能正在嘗試轉換使用 / 或將編寫的部分現有 Python 模型,才能匯出「模組」檔案,如果您的執行個體為「模組」,您就需要採用 Python 版本的 TensorFlow 設定「 」並未開放下載。

透過 SSH 連至您在上述步驟建立的雲端機器,然後在終端機視窗中輸入以下內容:

終端機視窗:

sudo apt update
sudo apt-get install python3

如此可確保電腦上已安裝 Python 3。必須安裝 Python 3.4 以上版本才能使用 TensorFlow。

如要確認安裝的版本是否正確,請輸入以下內容:

終端機視窗:

python3 --version

畫面上應會顯示代表版本號碼的輸出內容,例如 Python 3.6.9。如果輸出正確,且數值高於 3.4,可以繼續進行這項程序。

接下來,我們會安裝 Python 3 專用的 PIP,這是 Python 的套件管理工具,然後進行更新。Type:

終端機視窗:

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

我們同樣可透過以下方式驗證 pip3 安裝:

終端機視窗:

pip3 --version

撰寫時,我們看到 pip 20.2.3 在執行這個指令之後,會輸出至終端機。

你必須先安裝 Python 套件「setuptools」,才能安裝 TensorFlow41.0.0 以上版本。執行下列指令,確認已更新為最新版本:

終端機視窗:

pip3 install -U setuptools

最後,我們可以安裝 TensorFlow for Python:

終端機視窗:

pip3 install tensorflow

這項作業可能需要一些時間才能完成,因此請等到執行完畢後再完成。

我們來看看 TensorFlow 是否已正確安裝。在目前的目錄中建立名為 test.py 的 Python 檔案:

終端機視窗:

nano test.py

nano 開啟後,即可編寫一些 Python 程式碼,輸出已安裝的 TensorFlow 版本:

test.py:

import tensorflow as tf
print(tf.__version__)

按下 CTRL + O 將變更寫入磁碟,然後按下 CTRL + X 退出 nano 編輯器。

現在我們可以執行這個 Python 檔案,查看列印顯示的 TensorFlow 版本:

終端機視窗:

python3 test.py

撰寫時,我們看到 2.3.1 在控制台中輸出了安裝 TensorFlow Python 版本。

4. 建立 Python 模型

本程式碼研究室的下個步驟將逐步說明如何建立簡單的 Python 模型,以說明如何將產生的訓練模型儲存至「模組」格式,然後與 TensorFlow.js 指令列轉換工具搭配使用。這個原則對您想要轉換的任何 Python 模型很類似,但我們會確保這個程式碼簡單明瞭,讓所有人都能瞭解。

我們可以編輯在第一節建立的 test.py 檔案,並將程式碼更新如下:

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, './')

這個程式碼會訓練非常簡單的線性迴歸,學習估算 x 的 (輸入) 和 y (輸出) 之間的關係。然後將訓練完成的模型儲存到磁碟。請查看內嵌註解,進一步瞭解各行的作用。

如果在執行這個程式 (透過呼叫 python3 test.py) 之後檢查目錄,我們現在應該會在目前的目錄中看到一些新的檔案和資料夾:

  • test.py
  • saved_model.pb
  • 資產
  • variables

現在我們已產生 TensorFlow.js 轉換工具需要使用的檔案,才能轉換這個模型在瀏覽器中執行!

5. 將 module 轉換為 TensorFlow.js 格式

安裝 TensorFlow.js 轉換工具

如要安裝轉換工具,請執行下列指令:

終端機視窗:

pip3 install tensorflowjs

這很簡單。

假設我們使用的是指令列轉換器 (tensorflowjs_converter),而非上述精靈版本,我們可以呼叫下列指令,轉換我們剛建立的已儲存模型,並將參數明確傳遞給轉換器:

終端機視窗:

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

到底怎麼回事?首先,我們呼叫剛剛安裝的 tensorflowjs_converter 二進位檔,並指定要轉換 keras 儲存的模型。

在上方的範例程式碼中,您將附註 keras ,並使用其較高層級的 API 來建立模型。如果您尚未在 Python 程式碼中使用 keras,您可能會想要使用不同的輸入格式:

  • keras:載入 keras 格式 (HDF5 檔案類型)
  • tf_saved_model - 載入使用 tensorflow 核心 API 而非 keras 的模型。
  • tf_frozen_model - 載入含有凍結權重的模型。
  • tf_hub - 載入從 tensorflow 中樞產生的模型。

如要進一步瞭解其他格式,請參閱這篇文章

接下來的 2 個參數會指定儲存的模型所在的資料夾。在上述示範中,我們會指定目前的目錄,最後指定要將轉換輸出到哪個目錄,並在上方指定名為「predict_houses_tfjs」的資料夾。檔案在目前的目錄中

執行上述指令後,系統會在目前目錄中建立名為 predict_houses_tfjs 的新資料夾,其中包含 :

  • model.json
  • Group1-shard1of1.bin

以下是在網路瀏覽器中執行模型時所需的檔案。請儲存這些檔案,下一節將會用到。

6. 在瀏覽器中使用經過轉換的模型

代管轉換後的檔案

首先,我們必須將 model.json 和產生的 *.bin 檔案放在網路伺服器上,以便我們透過網頁存取這些檔案。在這個示範中,我們使用 Glitch.com,方便您跟著操作。不過,如果您是網路工程背景,則可以選擇在目前的 Ubuntu 伺服器執行個體上啟動簡易的 http 伺服器,以執行這項作業。一切都由您決定!

將檔案上傳到 Glitch

  1. 登入 Glitch.com
  2. 使用這個連結複製 TensorFlow 樣板專案。其中包含基本架構 html、css 和 js 檔案,可匯入 TensorFlow.js 程式庫供我們使用。
  3. 按一下「資產」。
  4. 按一下「上傳素材資源」然後選取要上傳至這個資料夾的「group1-shard1of1.bin」上傳後看起來應該會像這樣:25a2251c7f165184.png
  5. 按一下剛上傳的 group1-shard1of1.bin 檔案,即可將網址複製到該檔案的位置。請複製這個路徑,如下所示:92ded8d46442c404.png
  6. 現在請在本機電腦上使用您最愛的文字編輯器來編輯 model.json,並使用 CTRL+F 鍵搜尋 group1-shard1of1.bin 檔案,該檔案會在當中被提及。

請將這個檔案名稱替換成您在步驟 5 複製的網址,但請刪除從複製路徑中產生故障而產生的前置字元 https://cdn.glitch.com/

編輯後看起來會像這樣 (注意:如何移除主要伺服器路徑,只保留最終的已上傳檔案名稱):d5a338f2dc1f31d4.png 7.完成後,請儲存並上傳這個編輯過的 model.json 檔案。如要手動上傳,請按一下素材資源,然後點選「上傳素材資源」按鈕 (重要)。如果您並未使用實體按鈕進行拖曳,系統會將其上傳為可編輯檔案 (而非 CDN),而該檔案不會位於同一個資料夾中,當 TensorFlow.js 嘗試下載特定模型的二進位檔案時,也會假設相對路徑。如果正確無誤,assets 資料夾中應會顯示 2 個檔案,如下所示:51a6dbd5d3097ffc.png

太好了!現在可以使用儲存的檔案,在瀏覽器中輸入實際程式碼。

載入模型

現在,我們已代管轉換的檔案,我們就能撰寫一個簡單的網頁來載入這些檔案,並使用這些檔案進行預測。請先在 Glitch 專案資料夾中開啟 script.js,然後將 const MODEL_URL 指向在 Glitch 上上傳的 model.json 檔案產生的 Glitch.com 連結,然後替換為以下內容:

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

在將 MODEL_URL 常數變更為指向 model.json 路徑後,執行上述程式碼後,畫面上會顯示以下輸出內容。

c5e8457213058ec3.png

如果我們檢查網路瀏覽器的控制台 (按下 F12 鍵在瀏覽器中開啟開發人員工具),我們也可以查看已載入模型的模型說明;這些結果會顯示:

35e79d70dbd66f27.png

在本程式碼研究室一開始,我們可以比較這個程式碼與 Python 程式碼,確認這和我們透過 1 個密集輸入和一個包含 1 個節點的稠密層建立的網路。

恭喜!您剛在網路瀏覽器中執行轉換後的 Python 訓練模型!

7. 無法轉換的模型

有時候,經過編譯而較少使用的複雜模式將無法支援轉換。瀏覽器版本的 TensorFlow.js 是完全重新編寫 TensorFlow 的流程,因此目前我們不支援 TensorFlow C++ API 的所有低階運算 (還有 1000 秒),但是隨著我們不斷發展,核心運算也越來越穩定,但隨著程度越來越高。

截至本文撰寫時,TensorFlow Python 中有一個函式在匯出為已儲存的模型時,會產生不支援的運算linalg.diag。如果我們嘗試轉換在 Python 中使用此功能的已儲存的模型 (可支援它產生的運算),我們便會看到類似下方的錯誤:

5df94fc652393e00.png

這裡以紅色醒目顯示,表示在編寫這個程式碼研究室時,網路瀏覽器的 TensorFlow.js 不支援 linalg.diag 呼叫,產生名為 MatrixDiagV3 的運算。

該做什麼?

具體有兩種方法。

  1. 在 TensorFlow.js 中導入這個缺少的運算 - 我們是開放原始碼專案,並且歡迎為新運算等項目貢獻一己之力。請參閱這份指南,瞭解如何針對 TensorFlow.js 編寫新運算。如果真的可以做到,可以使用指令列轉換工具上的 Skip_op_check 旗標忽略這個錯誤,繼續轉換 (假設在新建立的 TensorFlow.js 版本中,有支援缺少運算功能的新版本可以執行這項運算)。
  2. 判斷 Python 程式碼的哪個部分在您匯出的 savedmodel 檔案中產生了不支援的作業。在少數程式碼中,這可能很容易找出,但在較複雜的模型中,目前沒有方法可識別以 savedmodel 檔案格式產生特定運算一次的高階 Python 函式呼叫,因此可能需要花費更多心力。如果找到上述方法,則可變更為使用其他受支援的方法。

8. 恭喜

恭喜!您已完成第一步,開始在網路瀏覽器中透過 TensorFlow.js 使用 Python 模型!

重點回顧

在本程式碼研究室中,我們學到以下內容:

  1. 設定 Linux 環境以安裝以 Python 為基礎的 TensorFlow
  2. 匯出 Python「mod」
  3. 安裝 TensorFlow.js 指令列轉換工具
  4. 使用 TensorFlow.js 指令列轉換工具建立必要的用戶端檔案
  5. 在實際網頁應用程式中使用產生的檔案
  6. 找出無法轉換的模型,以及必須導入什麼,才能確保日後轉換。

後續步驟

別忘了,使用 #MadeWithTFJS 標記我們製作任何內容,就有機會在社群媒體上亮相,甚至有機會在日後的 TensorFlow 活動中亮相。我們非常期待看到轉換內容,並在瀏覽器中使用用戶端!

更多 TensorFlow.js 程式碼研究室可深入探索

建議結帳網站