(SwiftUI) 使用 CreateML 建立 台灣美食辨識 APP

Photo by THE 5TH on Unsplash

目的:學習使用 CreateML 建立 CoreML 模型,並在 iphone 上進行 inference

Taiwanese Food 101 Dataset

開啟 CreateML

點選 Xcode 右鍵,然後將滑鼠移動到 Open Developer Tool ,選取 CreateML

選取 Image Classification ,點選 Next

點選 Training Data,將從 kaggle 下載的資料集放入其中

接下來點選左上角 Train 進行訓練

訓練完畢後,可以點選 上方 Training 查看訓練結果

訓練結果

Training Accuracy : 85.4%

Validation Accuracy : 77.2%

點選 Evaluation,可以查看訓練及驗證每筆資料的 Precision、Recall、F1 Score

使用 Preview 進行測試

將圖片拖入其中進行預測

將訓練後的模型輸出成 CoreML model

選取 Output 後,點選 Get 再按 save 將模型保存起來

評估模型

執行下方程式碼

import PIL
from PIL import Image
import coremltools as ct
import os

img_path = "/Users/jason/Documents/ML_data/food_data/tw_food_101/tw_food_101/test/"
files = os.listdir(img_path)






if __name__ == '__main__':

results = []

data_dict = {}


sorted_imagepath = sorted(files, key=lambda x: int(os.path.basename(x).split('.')[0]))

with open('/Users/jason/Documents/ML_data/food_data/tw_food_101_classes.csv', 'r') as f:
lines = f.readlines()
for line in lines[:]:
line = line.strip()
data = line.split(',')
index = int(data[0])
category = data[1]
data_dict[index] = category


for i in sorted_imagepath:
image_path = os.path.join(img_path, i)
img = Image.open(image_path)
img = img.resize([299, 299], PIL.Image.ANTIALIAS)
img = img.convert('RGB')
ret = model.predict({"image": img})
results.append(list(data_dict.values()).index(ret["classLabel"]))

with open('pred_results.csv', 'w') as f:
f.write('Id,Category\n')
for i in range(len(results)):
f.write(str(i) + ',' + str(results[i]) + '\n')

Inference 完成後,到 kaggle 頁面提交 pred_results.csv

最終可以發現測試資料的準確率只有 74.4% 左右,排名能到 57 看起來還可以?畢竟跟平常訓練的方式不同,只需要將照片資料夾拖入 CreateML 就可訓練,且訓練的時間僅花 26 分鐘,模型大小也僅有 1.6 MB。

😢 若是增加訓練的次數,以及使用資料增強( Augmentations),一定能夠得到更好的準確率,但是目前 CreateML 似乎無法支援 GPU 加速,所以當增加訓練的次數與使用資料增強( Augmentations)後,訓練的時間會大幅增加,我借用了朋友 劉季婷 的 MacBook Pro M2 (14-inch),訓練了整整一天也無法完成。

下載 CoreML 專案,將模型進行替換

將 Food.mlmodel 拖入專案中,並點選 Finish

到 ContentView 將 Resnet50Int8LUT 改成 Food,將每一個 224 的數值都改為 299

struct ContentView: View {
...


private var model: Food?

init() {
// 初始化模型
do {
// 創建 Resnet50Int8LUT 模型實例,並使用空的 MLModelConfiguration 進行初始化
model = try Food(configuration: MLModelConfiguration())
} catch {
// 如果在模型初始化過程中發生錯誤,則輸出錯誤信息
print("初始化模型時發生錯誤:\(error)")
}
}

使用 Xcode 模擬器進行 Inference

使用 CreateML 訓練的模型,並不能在模擬器執行,會出現輸出為 nil 的情況,所以必須連接實機進行 inference

在實機進行 Inference

最終就完成了一款 能夠辨識台灣 101 種美食的 APP,CreateML 其實使用起來還算方便,但是如果需要更高的準確率,就必須使用 Tensorflow 或是 Pytorch 自行搭建模型,不過若是今天只是幾種類別的分類,準備好照片的話,就很推薦使用 CreateML 搭建一個分類的模型。

--

--