在黑胡桃社群的體驗案例中,有一個“人工智慧教練”,它其實是一個自定義的影象分類器。使用 TensorFlow.js 這個強大而靈活的 Javascript 機器學習庫可以很輕鬆地構建這樣的影象分類器,並在瀏覽器中即時訓練。
首先我們要載入並執行一個名為 MobileNet 的預訓練模型,在瀏覽器中進行影象分類;然後通過遷移學習為我們的應用定製預訓練好的 MobileNet 模型,並進行引導訓練。在開始之前,我們也要先做好一些準備:
現在,來看看“人工智慧教練”是怎麼誕生的吧!
載入 TensorFlow.js 和 MobileNet 模型我們先在編輯器中開啟 index.html 並新增以下內容:
let net;async function app() { console.log('Loading mobilenet..'); // Load the model. net = await mobilenet.load(); console.log('Successfully loaded model'); // Make a prediction through the model on our image. const imgEl = document.getElementById('img'); const result = await net.classify(imgEl); console.log(result);}app();
在瀏覽器中測試 MobileNet 的預測因為要執行該網頁,我們在 Web 瀏覽器中打開了 index.html 即可。但如果你正在使用雲控制檯,只需重新整理預覽頁面。
這時候,我們在開發者工具的 JavaScipt 控制檯中看到了一張狗狗的照片。
其實在手機上我們也可以體驗這個有趣的“人工智慧教練”。
通過網路攝像頭影象在瀏覽器中執行 MobileNet 預測現在,我們要讓它更具互動性和實時性,所以要設定網路攝像頭來預測由網路攝像頭傳輸的影象。
首先要設定的是網路攝像頭的視訊元素。開啟 index.html 檔案,在 <body> 部分中新增如下行,並刪除我們用於載入狗影象的 <img> 標籤。
<video autoplay playsinline muted id="webcam" width="224" height="224"></video>
開啟 index.js 檔案並將 webcamElement 新增到檔案的最頂部。
const webcamElement = document.getElementById('webcam');
現在,在之前新增的 app() 函式中,我們刪除通過影象預測的部分,用一個無限迴圈,通過網路攝像頭預測代替。
async function app() { console.log('Loading mobilenet..'); // Load the model. net = await mobilenet.load(); console.log('Successfully loaded model'); // Create an object from Tensorflow.js data API which could capture image // from the web camera as Tensor. const webcam = await tf.data.webcam(webcamElement); while (true) { const img = await webcam.capture(); const result = await net.classify(img); document.getElementById('console').innerText = ` prediction: ${result[0].className}\\n probability: ${result[0].probability} `; // Dispose the tensor to release the memory. img.dispose(); // Give some breathing room by waiting for the next animation frame to // fire. await tf.nextFrame(); }}
開啟控制檯,現在我們就可以看到 MobileNet 的預測和網路攝像頭收集到的每一幀影象了。
這可能有些不可思議,因為 ImageNet 資料集看起來不太像出現在網路攝像頭中的影象。不過大家可以把狗的照片先放在你的手機上,再放在膝上型電腦的攝像頭前來測試這一點。
在 MobileNet 預測的基礎上新增一個自定義的分類器現在,我們要把它變得更加實用。我們使用網路攝像頭動態建立一個自定義的 3 物件的分類器,通過 MobileNet 進行分類。但這次我們使用特定網路攝像頭影象在模型的內部表示(啟用值)來進行分類。
有一個叫做 "K-Nearest Neighbors Classifier" 的模組,它會有效地讓我們把攝像頭採集的影象(實際上是 MobileNet 中的啟用值)分成不同的類別,當用戶要求做出預測時,我們只需選擇擁有與待預測影象最相似的啟用值的類即可。
在 index.html 的 <head> 標籤的末尾新增 KNN 分類器的匯入(我們仍然需要 MobileNet,所以不能刪除它的匯入):
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/knn-classifier"></script>
在 index.html 視訊部分下面新增三個按鈕。這些按鈕將用於向模型新增訓練影象。
<button id="class-a">Add A</button><button id="class-b">Add B</button><button id="class-c">Add C</button>
在 index.js 的頂部,建立一個分類器
const classifier = knnClassifier.create();
更新 app 函式
async function app() { console.log('Loading mobilenet..'); // Load the model. net = await mobilenet.load(); console.log('Successfully loaded model'); // Create an object from Tensorflow.js data API which could capture image // from the web camera as Tensor. const webcam = await tf.data.webcam(webcamElement); // Reads an image from the webcam and associates it with a specific class // index. const addExample = async classId => { // Capture an image from the web camera. const img = await webcam.capture(); // Get the intermediate activation of MobileNet 'conv_preds' and pass that // to the KNN classifier. const activation = net.infer(img, 'conv_preds'); // Pass the intermediate activation to the classifier. classifier.addExample(activation, classId); // Dispose the tensor to release the memory. img.dispose(); }; // When clicking a button, add an example for that class. document.getElementById('class-a').addEventListener('click', () => addExample(0)); document.getElementById('class-b').addEventListener('click', () => addExample(1)); document.getElementById('class-c').addEventListener('click', () => addExample(2)); while (true) { if (classifier.getNumClasses() > 0) { const img = await webcam.capture(); // Get the activation from mobilenet from the webcam. const activation = net.infer(img, 'conv_preds'); // Get the most likely class and confidence from the classifier module. const result = await classifier.predictClass(activation); const classes = ['A', 'B', 'C']; document.getElementById('console').innerText = ` prediction: ${classes[result.label]}\\n probability: ${result.confidences[result.label]} `; // Dispose the tensor to release the memory. img.dispose(); } await tf.nextFrame(); }}
現在,載入 index.html 頁面時,我們就可以使用常用物件或面部表情/手勢為這三個類中的每一個類捕獲影象。每次單擊其中一個 "Add" 按鈕,就會向該類新增一個影象作為訓練例項。這樣做的時候,模型會繼續預測網路攝像頭的影象,並實時顯示結果。
總結到這裡,我們已經成功使用 Tensorflow.js 實現了一個簡單的機器學習 Web 應用程式——影象分類器,而且隨時可以在瀏覽器上開啟並進行訓練。
原文連結:
https://codelabs.developers.google.com/codelabs/tensorflowjs-teachablemachine-codelab/#8