好久不見,最近過得好嗎? 你可能有發現到 WordPress 開發日常許久未更新了,大概是從去年十月開始停更,會停更的主要原因滿多的,像是 ChatGPT 的崛起、工作的安排、職涯發展的規劃等等,但總歸一句就是懶了XD 之前因為每週五都一定要產出文章來,礙於截稿時間讓我覺得自己寫的東西為了要快速產出因此過於淺薄,而現在這些淺薄的知識全部都能透過 AI 得到,於是開始懷疑自我寫作的價值,在停更期間我也慢慢把電子報拋諸腦後,雖然工作還是會做筆記,但就沒動力整理出來。 直到上半年在回顧工作時,發現到累積了不少東西,再加上前陣子感冒,新冠的腦霧後遺症又再次發作,為了活化自己的大腦,決定還是開始寫些東西來刺激大腦,透過寫作來自省與紀錄。 因此未來的寫作方向會跟以往不太一樣,我會針對專案的經驗以及學習到的東西來分享,並且盡可能的詳述開發過程與思考方向,希望可以寫出 ChatGPT 比較不容易問到的東西,雖然可能過不久當它爬到本文後就被收編了XD 接下來本電子報會不定期更新,主要都會是以長文為主,為了不讓自己倉促的發文,每篇文章的產出週期會比較長,像今天分享的這篇我就寫了三個禮拜,希望透過這樣的整理能讓自己放慢腳步,寫出時效性比較長的內容。 前言在 2022 年上線的「BlueTrend 海洋生物資料庫」很順利的穩定運作中,截止目前為止共累積了 8,122 位會員、81 位社群分類員,以及蒐集到超過一萬兩千張的海洋生物照片,這個數字放眼全球的生態資料庫應該都是非常亮眼的成績,等未來拓展到海外勢必會有更驚人的資料量。
但從數字中可以發現已上傳的一萬多張照片中,已經辨識的照片數量還不到一半,沒有辨識的照片就無法得知該物種的相關資訊,像是地理位置、水下深度、水溫等等,這對於生態維護與周邊海域的效益就非常有限。 期間 Bluetrend 的 Spark 團隊也試過許多活動以及跟學術單位合作來提升照片的辨識率,不然已辨識照片的數量可能還會更低,正當大家苦思該如何提升辨識率的同時,AI 技術的突飛猛進提供我們一個契機:使用機器圖像辨識來分類物種。 確定這個方向後,我們從 2023 年底開始著手進行,期間歷經了無數的討論、爬了一堆文件、不停的修改程式碼,剩下的就是測試再測試,而該專案也榮獲了台灣大哥大基金會 Tech The Dreamers 科技夢想+ 第三屆的團隊,並於 2024 四月正式完成上線:https://www.cna.com.tw/postwrite/chi/367792 在開發 AI 圖像辨識之前,我是機器學習小白無誤,我完全沒有這方面的相關知識,每天只會用 ChatGPT 問些低級問題,所以當被告知要從蒐集圖片到訓練模型,甚至要串接辨識結果到網站中時,當下除了興奮外,更是佩服&感謝 Spark 團隊願意信任我這個 AI 零經驗的工程師。 這過程中學到超級多,也踩了不少雷,更是遇到許多前輩的熱心指導,這篇文章紀錄了我的學習跟開發過程,希望能讓有興趣投入機器辨識的朋友少走一些冤枉路。先來看一下我們成果:
僅有的三個畫面,背後花了超過三個月XD 網頁好讀版:https://oberonlai.blog/wordpress-vertex-ai/ 一、使用情境在使用者上傳照片選擇照片分類時,系統會根據該分類是否有提供 AI 辨識功能來進行判斷,如果有的話會詢問使用者是否要進行機器辨識,確認後就會開始等待辨識結果,辨識完成後會顯示信心度超過 N 分的的結果,最後再透過人為的判斷來決定是那個分類, 理論上大家應該都會選擇信心度最高的結果,可能會有人問說為何不自動取信心度最高的結果來進行分類,然而實際情況是有些照片辨識出來的結果信心度非常接近,這時候就是還是需要人為介入來進行判斷,整個過程可以想成是電影賭俠裡面海珊弄小刀的經典場景XD:
至於後台的部分有紀錄每次辨識的信心度,之所以要記錄是因為模型有可能因為某些原因失真,譬如說把鹿辨識成馬,這個時候透過信心度的資料與人為的判斷就能知道這個模型中猴了,就需要再次訓練或是打掉重練。 重新訓練的部分透過前輩得知也能做到全自動化,也就是先設好條件讓系統自行判斷何時該重新訓練,譬如連續辨識 N 次的結果都沒有被使用者採納,當滿足條件後就會透過 API 自動觸發重新訓練的流程,這是 MLOps 的領域,這專案還沒搞剛到這種程度,有興趣的朋友可以自行研究~ 二、技術選擇既有圖像辨識模型在實作這專案時剛好遇到 OpenAI 推出他們的圖像辨識服務 Vision,透過 API 就能進行圖像辨識,實測結果 10 次裡面會辨識正確 2~3 次,如果是個人興趣使用或許還行,而當時 Vision 尚未提供自行訓練模型的功能,以此在這專案中就不適用。 另外一個評估的模型是桃園的 Xpark 海洋水族館,之前去逛的時候有使用他們名為 「LINNÉ LENS」的手機 App,安裝後可以透過它即時辨識眼前看的海洋生物是什麼物種:
研究發現這間日本的公司有提供技術給全球的海洋水族館作物種辨識,雖然官網沒寫但感覺一定有 API 可以串接,因此本想說直接寫信跟他們合作,就能省下自己訓練模型的成本,但礙於本專案的性質以及考量到資料的完整度,最後還是以自行訓練為優先選擇。 公有雲的選擇因為沒有機器學習相關的知識,在技術選擇上以三大公有雲主機提供的機器學習服務為尋找方向,而網路上查到的資料與相關文件以 Google 雲比較完整,再加上有前輩可以請教,最後就以 Google 的 Vertex AI 作為我們的訓練&辨識模型。 訓練成本Vertex AI 的收費點主要是儲存空間、訓練時間以及辨識模型 API。要使用 Vertex AI 進行圖像模型訓練一定要把要訓練資料上傳 Google Cloud Storage,因此會有相關費用的產生,不同地區有不同價格,詳細可以參考官方說明:https://cloud.google.com/storage/pricing?hl=zh-tw 訓練圖像辨識模型要新增儲存空間,首先要建立 Bucket ( 值區 ) 也就是一個容器的概念,撰文當下要做模型訓練只有北美機房支援,因此我們選擇 us-central1,並且使用單一地區,另外根據儲存資料的用途不同還可以選擇空間級別,我們選擇的是 Standard,以下是我們儲放訓練資資料的值區設定方式:
目前我們的訓練照片資料量大概是 45 GB 左右,每個月的儲存費用還不到 1 塊美金,只有在訓練時有資料傳輸才會有額外的費用產生,除非是要上到 TB 等級的訓練資料量,否則儲存的成本低到幾乎可以忽略。 其次是訓練的費用,是依照訓練時數與節點數量來計算,時間的部分就是訓練時間跑多久就算多久,以訓練 3,395 張照片為例,訓練完成花了 1 小時 33 分,如果想要快一點的話,可以用多個節點下去跑,但節點越多總費用就越高。 另外模型還有分線上或是邊緣部署,前者直接會把訓練好的模型放在 Google 上,要用的時候以 API 請求即可,邊緣部署則是把模型下載下來放在自己的主機上,要用的時候需要自己開發 API 讓網站存取。 有了以上概念對於 Vertex AI 的訓練費用就會比較有概念:
最後是部署的費用,前面提到我們可以把訓練好的模型放在 Google 的主機上,並用他們內建的 API 來進行圖像辨識的操作,可以省去我們自行準備機器以及開發 API 的時間,以上圖的價目表來看,只要模型放在 Google 就會計費,並且實際進行辨識的讀取時間也會算錢。 然而我們在開發時忽略了這件事,當時訓練完後想說就用他們的機器去部署並測試辨識結果,但測試完後忘記把機器關掉,導致整個服務都還沒上線就噴了超多錢 > <,於是後來我們改用邊緣部署的方式來做,不然這筆開銷很容易造成營運的負擔。 三、模型架構確定了技術之後,接下來我們進一步思考一個模型到底要放多少資料?資料太大會不會導致辨識速度慢、資料太少一次辨識存取多個模型會不會更花時間?在完全沒有概念的情況下只能透過不斷的測試來尋找最佳解。 這邊先簡單介紹一下我們的資料結構,物種的層級有四層關聯,分別是祖分類 > 父分類 > 子分類 > 孫分類,我們的目標是當上傳照片時選擇祖分類,就會開始進行圖像辨識,辨識完的結果是孫分類:
第一個想法是一個孫分類是一個模型,原因是一個孫分類一個模型要重新訓練比較方便,辨識的時間理論上也會比較短,但對網站來說就比較不方便使用,由於上傳照片時的欄位只能選擇祖分類,因此我要撈出祖分類底下所有的孫分類模型,並且去迴圈判斷當 A 孫分類模型辨識結果都沒有超過一定的信心度時,再去請求 B 孫分類模型的結果。 以此類推,如果 B 也沒有就必須 C → D → E 一個一個送照片去辨識是否有符合的結果,當時在思考時就覺得重複 API 請求一定會花不少時間,對使用者來說感受上可能會不太好。第二個想法是是從父或子分類的層級來訓練模型,但依舊跑不掉迴圈判斷的邏輯。 最後我們的做法是訓練祖分類這個大模型,把屬於同一個祖分類的孫分類全部都塞進同一個模型之中,實際測試的結果還不錯,只有第一次請求的時候約需要十秒左右的等待,同一個模型第二次請求就可以秒辨識,而且不管是線上部署還是邊緣部署時間都差不多,這樣的測試結果讓我們非常滿意! 四、訓練模型依照 Google 官方的建議,一個辨識結果最好要有 3000 張的照片來訓練才會得到比較準確的預測,實測結果如果待辨識的照片品質很好,像是被攝主體的輪廓、角度、清晰度都不錯的話,大概使用 200~500 張照片訓練的模型就能取得理想的結果,但如果是長得太像的物種就會不準。 像是以海龜來說,就算是不同種類但他們的外型都很接近,差別可能只是殼的花紋或是體型的大小,因此要取得更準確的結果就需要更精細的訓練資料,像是只拍攝針對龜殼花紋的大量照片才有可能取得比較好的辨識。 所以假設今天要能夠辨識出「冠刺棘海膽」這個物種,訓練模型的步驟如下: (一)蒐集 3000 張冠刺棘海膽的照片盡可能蒐集到該物種各個角度的照片,多虧海洋生物資料庫已經取得許多辨識過的照片,在基礎資料的蒐集上就有很好的開始,不足的部分再去網路上找圖,把單一物種可能呈現的樣貌都囊括其中。 (二)在 GCS ( Google Cloud Storage ) 建立冠刺棘海膽的值區上述提及訓練資料必須放在 Google 的 Storage,因此當照片蒐集完成後必須要把他們上傳到 GCS,Vertex AI 才能讀取到這些照片,值區內可以建立不同資料夾來區分物種。 (三)彙整資料集 Dataset資料集是訓練資料的集合,要訓練模型必須要透過資料集來訓練,我們可以在 Vertex AI 後台建立它,我們的作法是一個資料集對應一個模型,如果一個模型用多個資料集進行訓練也是可以:
接下來就要將資料集的內容整理好後進行上傳,資料集定義了照片的路徑與對應的標籤(物種),使用 csv 格式來彙整,長得像這樣:
一行一個 GCS 圖片路徑與標籤名稱,echinothrix_diadema 是冠刺棘海膽的學名,所以一個有 3000 張照片的資料集就是一個有 3000 行的 csv 檔,在這之前還要先上傳照片以及將照片路徑整理出來,這要人工整理會瘋掉,因此這樣的作法比較適合用程式處理。 另外一種整理方式可以直接在 Vertex AI 的進行操作,在建立好資料集後點擊進入,可以直接在介面中上傳圖片到 GCS:
上傳完成後切換到「瀏覽」頁籤,先新增物種的標籤,接著全選照片並指派標籤,就可以批次完成資料集的整理:
(四)訓練模型當所有照片都有指派好標籤後,就可以在資料集的右上角看到訓練新模型的按鈕:
點擊後會出現模型訓練的確認視窗,比較需要注意的有以下兩個地方:
首先是模型的使用位置,上述提到為了節省模型的部署成本,我們選擇使用 Edge 也就是邊緣部署的方式將模型放在自己的主機上來使用,雖然要自行開發 API 以及確保模型的可用率,但實際比較之後辨識結果沒有差太多。 其次是關係到訓練費用的節點數:
訓練費用是以節點數與訓練時間來計算,以我們使用的 Edge 邊緣部署為例,定價為每節點時數價格 18 美元,也就是說我用 1 個節點訓練 1 小時,費用是 1 節點 x 1 小時 x 18 美元 = 18 美元,公式是: 總費用 = 節點數量 × 訓練時間(小時)× 每節點時數價格 由於訓練時數會跟資料集的大小有關,很難預估大概會跑多久,因此為了避免荷包爆炸,這邊可以設定預算,這邊輸入的是小時節點數,也就是如果我們希望預算控制在 100 美元以內並只跑一小時的話,節點數上限為 100 元 / (1 個節點 x 每小時 18 元) = 5.6 取整數 5,公式是: 節點數上限 = 金額預算 / ( 所需節點數 x 節點數每小時單價) 因此在相同 100 元的預算下,如果不希望花費太多時間可以增加節點數,100/(2x18) = 2.7 取整數 2,但萬一模型太大就會導致預算花完了但模型還沒訓練完,因此下方的「啟用提早中止訓練功能」一定要記得勾,可以減少訓練的花費。 訓練完成後就能實際上傳照片來測試模型的準確度,但前提是要先把模型發佈到端點,也就是將模型部署在 Google 的主機上,由於一部署就要計費了,因此我們採取把模型載回來部署在自己主機上的方式來測試,並於網站後台紀錄每次辨識的信心度,再由專家判斷該模型是否失真:
五、邊緣部署接著說明如何取得訓練好的模型並上傳到主機。首先進入要匯出的模型找到上方的匯出按鈕,並以 TensorFlow.js 的格式匯出,要以 Edge 模式訓練的模型才有辦法匯出:
匯出後它不會給你一個檔案直接下載,而是會儲存到 GCS 裡面,因此模型匯出後我們要去匯出時指定的 GCS 路徑找到模型:
匯出的資料夾名稱會以 model- 加一串數字開頭,點進去後會是一個 tf-js 的資料夾,而我們需要將這資料夾下載到我們電腦,所以勾選資料夾後點選右上角的下載,就會出現 gsutil 的指令,這是 Google 專用的終端機指令,我們必須先在電腦安裝好。 具體的安裝方式可以參考官方說明:https://cloud.google.com/storage/docs/gsutil_install#install 裝好後開啟終端機,首先執行 接下來回到 GCS 的網頁複製下載的指令並於本機執行,就能將我們所需的模型下載回來,打開模型資料夾後會發現以下的檔案:
model.json 是讀取模型的引入檔,以 group 開頭的 .bin 檔則是模型本身,根據模型的大小數量不一定,dict.txt 是所有的標籤,因此只要這些檔案上傳到主機上,並透過前端來讀取 model.json 就能載入所需的模型。要注意的地方伺服器的設定要放行 .bin 不然會讀取不到。 六、取得辨識結果透過 TensorFlow.js 讓我們可以很方便的在前端取得辨識結果,首先引入相關的 JS,可以透過 NPM 安裝或是直接引入: 接下來就可以用 tf automl 物件的 loadImageClassification 方法來讀取模型的引入檔 model.json:
然後使用 classify 方法就可以取得辨識結果:
classify 帶的參數 image 是需要透過 tf 的 fromPixels 方法來轉換格式,如果你的圖片是放在 id 名為 img 的 <img> 標籤裡面,可以這樣取得 image:
由於該專案上傳的圖片都是放在第三方圖床,因此需要從外部網址來取得 image:
loadImageFromUrl 帶入一個網址參數就可以回傳 tf 所需的 image 格式,這邊以圖片在 <img> 標籤內為範例,重新整理上述的程式碼:
predictions 回傳的範例如下:
label 是標籤名稱,prob 是信心度,取得這些資料後就可以判斷當辨識完成後取 prob 高於 0.8 的 label 做顯示,或是將 prob 超過 0.5 的 label 全部列出來讓使用者決定哪個才是正確答案,這部分就看遊戲規則怎麼設定。 結論不得不說有了 Vertex AI 的協助讓完全沒有機器學習知識的我也能夠開發出圖像辨識這種強大的功能,花比較多時間的地方在於熟悉 Vertex AI 的操作介面與專有名詞,至於在開發的體驗上覺得 Google 的文件真的好多,多到都不知道要看哪個才是正確的 > < 但如果是用線上部署的話 API 用法會直接附在後台的側邊欄,只能說 Google 為了賺這一條錢設計了很多貼心的地方讓開發者容易入坑XD 希望這篇整理能幫助到也想入坑圖像辨識的你!有相關問題都可以來信跟我討論~ 參考資料Vertex AI 訓練資料 API 文件https://cloud.google.com/vertex-ai/docs/reference/rest https://blog.cloud-ace.tw/ai-machine-learning/vertex-ai-tutorial-and-intro/ https://cloud.google.com/vertex-ai/docs/training-overview Vertex AI 設定教學https://dotblogs.com.tw/jakeuj/2023/08/21/Google-Cloud-Vertex-AI PHP SDKhttps://cloud.google.com/php/docs/reference/cloud-ai-platform/latest 邊緣部署教學https://cloud.google.com/vision/automl/docs/tensorflow-js-tutorial https://www.wingwill.com.tw/zh-tw/%E9%83%A8%E8%90%BD%E6%A0%BC/google-cloud-vertex-ai/ |
在使用 LINE 作為客服工具時,常遇到一個棘手問題:顧客在 LINE 上詢問「我的訂單什麼時候到?」但打開 LINE 官方帳號後台,看到的只是陌生的使用者名稱,完全無法得知對方是誰、買了什麼、訂單狀態如何。 由於 LINE 後台看不到好友的電子郵件,而 LINE 顯示名稱又常與顧客下單時填寫的姓名不一致,只能先向顧客詢問購買時使用的電子郵件。若顧客記錯或忘記,再加上同一電子郵件可能有多筆訂單,還得進一步詢問訂單編號或購買日期。 因此,一位顧客詢問訂單資訊的客服流程,通常需要經過以下步驟: 詢問顧客電子郵件 詢問訂單編號或購買日期 登入 WooCommerce 後台 在訂單列表中使用電子郵件搜尋訂單 確認所屬訂單並記下相關資訊 回到 LINE 聊天介面回覆顧客 假設顧客即時回覆且訂單搜尋一次就成功,每個步驟約花 30 秒,整個流程至少要 3 分鐘。若同時有 10 位顧客詢問,就需耗時 30 分鐘,這還不包含等待回覆、網站後台讀取速度,以及在不同平台之間切換的時間。難道沒有更便利的方法嗎? OrderChatz - WooCommerce LINE 客服外掛 OrderChatz...
三個月前,我曾寫過一篇關於 AI 開發工作流程的文章。沒想到短短幾個月,因為 AI 技術的快速進展,我的工作流程又有了天翻地覆的改變。這篇文章紀錄了這段期間的變化,並分享針對不同開發情境可採用的方法。 根據我自己的實務經驗與今年的開發心得,我將 AI 協助開發的方式分成四種: Tab Auto Completion(自動補齊) Chat Coding(聊天開發) Vibe Coding(直覺開發) Spec Coding(規格開發) 這四種方法沒有絕對的優劣,差別主要在於使用情境、開發者的技術程度,以及對 AI 成本的控管。以下分別說明適用場景、對象、成本與工具選擇。 1. 自動補齊 適用對象:會去 Google 找語法複製貼上,且對語法具有基礎認識者 適用場景:一個或是數個函式能完成的功能 花費成本:0 元 工具選擇:VSCode + GitHub Copilot 自動補齊是最簡單的方式。在編輯器中輸入註解或函式名稱後,AI 會根據提示自動產生程式碼建議,按下 Tab 就能直接完成程式碼。這對於經常撰寫小功能或快速測試語法的人非常實用。 例如在 WordPress...
對我來說,學習新東西最好的方法就是從做中學,為此我暫時離開了 PHP,投入自己完全不熟悉的領域,使用 AI 開發了一個社群平台,技術採用了 React、Vite、Shadcn、Vercel 以及 Supabase,實驗看看全面交由 AI 進行開發會發生什麼事。 剛開始的第一週衝擊實在太大,以前大概要花一個月弄的東西 AI 一天就搞定,但也因此陷入了多巴胺中毒的危機之中,幸好即時清醒避免越陷越深。命令 AI 執行的過程中,也逐漸理解到它的可能性、限制與風險,更重要的是可以分辨出網路上瘋傳的最新模型、AI 工具是否適合自己,也慢慢知道這些工具該應用在什麼地方,如果沒有從做中學,這些資訊真的會讓人焦慮。 工作佔比 六月份我開始捨棄紀錄工作時數這件事了,一方面是因為事情都是 AI 在做,它執行的速度太快,我根本沒辦法依照每個工作事項記錄時數,另一方面因為暫時沒在接案,也就沒有跟客戶回報工作時數的流程,所以就沒有再繼續計時,取而代之的是用開發日誌來記錄,這樣工作起來反而更自在些。 六月工作時間安排基本上就是週一到週五早上 3 小時,下午 1~2...