ML5.js 神經網路 開發圖像辨識

ML5.js 神經網路 開發圖像辨識
ML5.js 神經網路 開發圖像辨識

本篇要解決的問題

這一篇原本是 2019 年寫好的,這幾天因為有遇到相關需求,所以回頭再來看,發現!竟然!!原本的 Demo 程式碼是不能用的!!!所以今天晚上再次翻了一下官方文件,更新本篇程式碼的部份後,再次發佈這篇。

本篇主要是要解決,當使用者上傳圖片後,可以由前端做圖片辨識的需求。


機器學習的 JavaScript Library

前幾天看到文章,說 Google 有一套機器學習,是有給 JavaScript 用的版本,叫作「TensorFlow」,昨天打開網頁來看,有看到教學的第一個就寫:

想要開始機器學習,同時不用擔心任何類似張量或優化器的低級細節嗎?
ml5.js 庫構建在TensorFlow.js 之上,通過簡潔的、可利用的API,可以在瀏覽器中訪問機器學習算法和模型。

看到第二句就心動了,又再打開 ml5.js 的頁面後,第一個的教學就是圖像辨識。

教學頁面是用 ml5.js,加上 p5.js 去把抓到的圖片給丟到頁面上。不過 August 想了一下,覺得可以不用透過 p5.js,就能把使用者上傳的圖片給丟到頁面上了,就是之前寫過的這篇:

File API 客製上傳檔案按鈕(input file)

把抓到的圖片塞進 img 的 src 裡,再讓圖像識別模型去抓、去判斷,就省去了再去學 p5.js 的時間。

本篇筆記主要寫用 Vue.js,搭配 File API、ml5.js,做一個簡單的圖像識別頁面來玩。

最後完成的 Demo 頁在這邊:

https://letswritetw.github.io/letswrite-ml5-image-classifier/


Vue.js 抓 input file

原本是這樣子寫:

<input type="file" v-model="file" @change="getFile(file)">

習慣用 v-model 去抓 input 的值,但這樣寫會一直看到 getFile 抓出來的是檔案的名字,而不是檔案本身。後來查了一下,才知道 Vue.js 在 @change 裡的 method 中就可以抓到 file了,改成這樣寫就行:

<input type="file" @change="getFile">
const { createApp, markRaw } = Vue;

const App = {
   methods: {
     getFile(e) {
       const img = URL.createObjectURL(e.target.files[0]);
     }
   }
}

ml5.js 圖像辨識 API

確定了用 Vue.js 可以抓到 input file 裡的檔案後,接著就是要接 ml5 的圖像辨識 API。

官網的文件在這邊,以下是參考文件改成寫在 Vue.js 裡的:imageClassifier

第一個坑:沒等 model 載完

一開始就踩了一個坑,就是頁面一開啟,August 就按了選擇檔案的案鈕,然後就報錯了,說 classifier 不是一個 function。

回頭看了一下文件後發現,有說因為要載入圖像識別的 model,會花一點時間,所以 API 在載入完後會有一個 callback,確認 model 載入完成:

// Initialize the Image Classifier method with MobileNet
const classifier = ml5.imageClassifier('MobileNet', modelLoaded);

// When the model is loaded
function modelLoaded() {
  console.log('Model Loaded!');
}

之所以一開始會遇到報錯,就是在 model 未載入完時就選擇了檔案開始調用 API。

考慮到使用者也會有一樣的情況,就在頁面上加了一 層 Loading 的效果。在 model 載入完後移掉蓋住的 Loading 就可以了。Loading 效果選用了一個看上去有點 AI 感的(自己講),如下圖:

loading effect
loading effect

第二個坑:沒給圖片寬高

2024.01.23:新的 ml5.js 已經沒有這個問題了,這段留下來給使用舊版的人一個解決的紀錄。

接著又踩了第二個坑,model 在讀圖的時候,必須要有圖片的尺寸,不能只是把 img src 放進去,報錯會報一個圖片尺寸 是0 x 0 的錯誤,所以無法判斷。

這部份就用 Vue.js 的 refs 去處理,August 寫的如下:

<input type="file" @change="getFile" ref="img">

new Vue({
  // 省略
  methods: {
    getFile(e) {
      var file = e.target.files[0];
      var img = URL.createObjectURL(file);
      img.width = this.$refs.img.width; // 設圖片寬
      img.height = this.$refs.img.height; // 設圖片高
    }
  }
})

踩過了以上二個坑以後,接著就順利了。


關於圖片辨識模組

文件中有提到,模組的部份除了範例中的「MobileNet」,也還有「Darknet、Darknet-tiny、DoodleNet」這三個,或者是可以讀自己的模組。

以下是 ChatGPT 說明這 4 個 model 的不同:

MobileNet

設計目標:適用於移動和邊緣設備的輕量級深度學習模型。

特點:使用深度可分卷積減少計算量和模型大小,仍保持良好的性能。

應用場景:移動設備或具有計算能力限制的設備上的圖像識別和分類。

Darknet

設計目標:是一個開源神經網路框架,用於物體檢測的 YOLO (You Only Look Once) 模型就是基於此框架。

特點:能夠實現實時物體檢測,速度快,但模型較大,需要較多的計算資源。

應用場景:需要實時檢測的系統,如監控視頻分析。

Darknet-tiny

設計目標:是 Darknet 的一個縮小版,目的是在保持合理準確度的同時,減少模型的大小和計算需求。

特點:對比原版 Darknet,它更輕量,但準確度可能略有下降。

應用場景:適合資源有限的設備,需要進行實時物體檢測但可以接受一定準確度折衷的場景。

DoodleNet

設計目標:專注於識別手繪草圖或畫作。

特點:對手繪圖像有良好的識別能力,但不一定適用於普通的圖像識別任務。

應用場景:草圖識別、藝術創作輔助等。


原始碼

原始碼的部份整理到 GitHub 上了,可從這邊下載:

https://github.com/letswritetw/letswrite-ml5-image-classifier

最後再放一次 Demo 的連結,可以玩玩看,不過回傳的資料都是英文,請按下 Google 翻譯:

https://letswritetw.github.io/letswrite-ml5-image-classifier/

Summary
ml5.js 開發神經網路圖像辨識
Article Name
ml5.js 開發神經網路圖像辨識
Description
本篇大綱:機器學習的 JS Library、Vue.js 抓 input file、ml5.js 圖像辨識 API、第一個坑 沒等 model 載完、第二個坑 沒給圖片寬高、補充 關於圖片辨識模組、原始碼。
August
Let's Write
Let's Write
https://letswritetw.github.io/letswritetw/dist/img/logo_512.png
訂閱
通知
guest

1 Comment
最舊
最新
Inline Feedbacks
看所有留言
Nathan Cheng 鄭柏昇
Nathan Cheng 鄭柏昇
4 年 之前

給正在尋找使用Vue proj + cdn引入的朋友們參考: 由於p5.js、ml5.js 在npm的支援度不高,若是使用Vue專案建置的人, 引入p5.js、ml5.js cdn的方式可以如下: 1… 繼續閱讀 »