跳過導覽
Sketch 內幕

不是熱狗 — 如何為 Sketch 建立一個 AI 驅動的插件 🌭

事實證明,要建立一個可以判斷圖層是否是熱狗的 Sketch 插件並非難事,這要歸功於 Apple 工程師的辛勤工作。

HBO 電視劇《矽谷群英》中的「不是熱狗」應用程式已成為科技界最具代表性的笑話之一。在許多不同的平台上,都有許多真實的應用案例,但唯獨缺少一個,直到現在。我著手打造這個在設計師日常工作流程中缺失的 Sketch 插件,以下是我如何將其實現。

「如果我告訴你,市面上有一個 Sketch 插件可以判斷你的文件中的一個圖層是否是熱狗,你會怎麼說?它非常好用,而且我不想再繼續開發它了。你可以另請高明。」

這是 🌭 嗎?

事實證明,要建立一個可以判斷圖層是否是熱狗的 Sketch 插件並非難事,這要歸功於 Apple 工程師的辛勤工作。Sketch 插件可以使用 JavaScript 函式庫(因此你可以利用其他人的成果來做一些很酷的事情,例如 sketch-primitivesrough-sketch)和 macOS API。這表示我們可以兼得兩者的優點,最重要的是,我們可以利用 Apple 的新 Core ML 框架

這個新的 macOS 框架讓開發者以前所未有的方式使用機器學習。事實上,「不是熱狗」插件是我第一次涉足機器學習領域,而且它比我想像的更容易上手 — 實際上,整個插件只有 100 行程式碼,其中一半是空白的(因為空白很重要,孩子們)。

想建立自己的機器學習 Sketch 插件嗎?你只需要一台筆電和一大堆熱狗的照片。讓我們開始吧。

要建立一個判斷圖層是否包含熱狗的插件,我們需要

  • 訓練一個分類器
  • 建立一個使用該分類器的 Sketch 插件

如果你正在跟著做,所有的程式碼都是開源的,可以在這裡找到:https://github.com/mathieudutour/sketch-hotdog

訓練分類器

分類器是一個系統,它可以根據屬於這些集合的其他項目的範例,判斷一個項目最可能屬於哪個資料集。這些範例稱為「訓練集」,將這些資訊提供給分類器的過程稱為「訓練」。

在我們的例子中,我們想要訓練一個分類器來辨識圖像是否包含熱狗。

收集訓練集

我們需要做的第一件事是收集訓練集的圖像。最好的方法是成為史丹佛大學的教授,並給你的每個學生一個作業,為你收集食物的照片。我不知道你的情況,但我不是史丹佛大學的教授,所以我們需要用老方法來收集我們的圖像。

ImageNet 是一個可以透過關鍵字搜尋圖片的資料庫。它也允許您選擇一個關鍵字並下載與該關鍵字相關的圖片網址列表,這對我們接下來要做的事情非常有用。我選擇了關鍵字「hotdog」、「chilidog」和「frankfurter」來搜尋熱狗圖片,以及「pets」、「buildings」、「plants」和「pizza」來搜尋非熱狗圖片。如果您不想自己尋找圖片網址,您可以直接使用我的

接下來,我們需要遍歷這些網址並下載實際的圖片。我們可以使用腳本來自動執行此操作——我不會在這裡詳細解釋,但您可以在Github 上找到這個腳本——只需按照檔案頂部的說明操作即可。此腳本會下載圖片並將它們儲存在兩個資料夾中:hotdognot_hotdog

Multiple pictures, with some being hotdogs and others not

熱狗訓練集

建立模型

現在我們有了訓練集,我們需要訓練分類器(或建立模型)。訓練分類器通常是一項非常複雜的任務,涉及許多參數。幸運的是,Apple 建立了一個名為 Turi Create 的開源工具,它使這個過程變得更加容易,所以我們將使用它。

首先,您需要安裝 Turi Create。別擔心,我會在這裡等您。

安裝完成後,我們需要建立一個 Python 腳本來建構我們的模型。Turi Create 有一個方便的方法可以遞迴載入資料夾中的所有圖片。

import turicreate as tc
import osdata = tc.image_analysis.load_images(
 './datasets/',
 with_path=True
)

您可能會看到一堆「不是 JPEG 檔案」的錯誤,因為我們下載的某些圖片已損毀,但您可以放心地忽略這些錯誤。參數 with_path=True 會在產生的資料框架中新增一個 path 欄位,其中包含每個圖片的絕對路徑。

由於該欄位,我們可以標記圖片——如果路徑包含 /hotdog/,那麼它就是熱狗——很簡單,對吧?

data['label'] = data['path'].apply(
 lambda path: 'hotdog' if '/hotdog/' in path else 'nothotdog'
)

此時,您可以要求 Turi Create 顯示一個使用者介面來瀏覽我們剛才標記的資料集。

data.explore()

現在是時候使用我們的訓練集來訓練我們的分類器了。感謝 Turi Create,我們只需要一個方法就可以做到。

model = tc.image_classifier.create(
  data, # use the training set
  target='label', # classify based on the label
  model='squeezenet_v1.1',
  max_iterations=50
)

它會自動將我們資料的 5% 作為「驗證集」,並檢查分類器的表現(先猜測,然後檢查標籤以查看是否正確)。您可以調整迭代次數,看看它如何影響準確性。如果您使用的數字太高,您會注意到準確性開始下降。這是由於一種稱為「過擬合」的現象,它導致模型對訓練資料的擬合程度過高,以至於變得過於特定。

我們快完成了——最後一件要做的事情是儲存模型,以便我們的 Sketch 外掛程式可以使用它。使用以下指令來執行此操作。

model.export_coreml('HotdogNotHotdog.mlmodel')

這是整個腳本的連結。

建立 Sketch 外掛程式

現在我們有了分類器,我們需要建立一個 Sketch 外掛程式,它將使用分類器來分類我們的圖片圖層。為了建立外掛程式,我們將使用一個名為 skpm 的開源工具。它自動化了開發和發佈外掛程式所涉及的許多任務,讓您可以專注於實際的程式碼。首先,您需要安裝 skpm

設定外掛程式

現在我們可以建立外掛程式了。在終端機中,執行以下指令

skpm create sketch-hotdog && cd sketch-hotdog

這將會建立一個叫做 sketch-hotdog 的資料夾,安裝一些建置插件所需的依賴套件,並初始化幾個檔案來建立一個簡單的樣板插件。它應該會出現在 Sketch 的插件選單中。試著執行它吧!很厲害吧?

在深入研究程式碼之前,我們需要先做幾件事。首先,我們需要打開 Sketch,建立一個新的文件,插入一張圖片並選取該圖片。然後,我們需要將我們的分類器模型放到插件可以存取的位置。你會注意到 sketch-hotdog 資料夾中有一個 assets 資料夾。插件可以存取這個資料夾中的所有檔案,所以讓我們把我們的模型移到那裡。每次修改程式碼後,我們都需要重新建置插件,所以我們接下來需要做這件事。你可以在終端機中執行以下指令來完成:npm run watch

好了,我們都準備好了。你需要在你喜歡的程式碼編輯器中打開以下檔案 sketch-hotdog/src/my-command.js。我們要寫的所有程式碼都將放在已經定義好的函式中。

與 Sketch 文件互動

首先,我們需要取得使用者選取的圖層,並檢查它是否是一個圖片圖層。如果你熟悉 JavaScript 和 NodeJS,這對你來說應該很熟悉。與 Sketch 互動的 API 可用於核心套件,就像在 NodeJS 中一樣。

var sketch = require('sketch')

如果你不完全熟悉 Sketch API,你可以查看文件

讓我們從取得 Sketch 選取的第一個圖層開始。

const document = sketch.getSelectedDocument()
const selectedLayer = document.selectedLayers.layers[0]

然後,我們需要檢查我們是否真的有一個圖層,以及該圖層是否是一個圖片。如果不是,我們將顯示一個訊息,告訴使用者選取一個。

if (!selectedLayer || selectedLayer.type !== 'Image') {
  sketch.UI.message('You need to select an image')
  return
}

利用 macOS 架構

Sketch 插件在 Sketch 中執行,而 Sketch 是一個原生的 macOS 應用程式。這意味著它可以存取所有 macOS 架構。預設情況下,只有兩個架構可用:FoundationAppKit。使用這兩個架構,你已經可以做很多事情了。但我們機器學習插件需要的是一個叫做 Vision 的架構。別擔心,我們可以在我們的插件中載入它。

framework('Vision')

現在我們可以存取 Vision 架構了,我們需要載入之前放在 assets 資料夾中的分類器模型。

我們需要的方法是 [MLModel compileModelAtURL:error:]。我知道,這不是 JavaScript,而是 Objective-C。我們不能直接使用它,所以我們需要稍微改變一下語法。不過別擔心,這相當簡單。

  • 首先,移除方括號。
  • 然後,將類別和方法之間的空格替換為 .
  • : 替換為 _(你可以省略最後一個)。
  • 然後像呼叫任何 JavaScript 函式一樣呼叫該方法。

所以 [MLModel compileModelAtURL:error:] 就變成了 MLModel.compileModelAtURL_error()

現在,讓我們來取得我們的模型。

// compile the model
const compiledModelURL = MLModel.compileModelAtURL_error(
  context.plugin.urlForResourceNamed("HotdogNotHotdog.mlmodel"),
  null
)
// load the compiled model
const model = MLModel.modelWithContentsOfURL_error(
  compiledModelURL,
  null
)
// transform our model into a Vision model
const vnModel = VNCoreMLModel.modelForMLModel_error(
  model,
  null
)
// create a an image analysis request that uses
// our Core ML model to process images
const request = VNCoreMLRequest
  .alloc()
  .initWithModel(vnModel)

我們現在需要建立一個「請求處理器」,它將接收我們剛剛建立的圖片分析請求,並將其應用於我們的圖片圖層。

// VNImageRequestHandler expects a "CIImage"
// Luckily, we can create one from our image layer
const ciImage = CIImage.imageWithData(
  selectedLayer.image.nsdata
)
const handler = VNImageRequestHandler
  .alloc()
  .initWithCIImage_options(
    ciImage,
    null
  )

我們快完成了——讓我們來執行我們的分類器!

const success = handler.performRequests_error(
  [request],
  null
)

最後一步是從分類器中取得結果,並向使用者顯示一個訊息。

if (success) {
  const bestEstimation = request.results()[0]
  const isAHotDog = String(bestEstimation.identifier()) === 'hotdog'
  sketch.UI.message(
    isAHotDog ? "Yep, it's a 🌭" : "Nope ❌"
  );
} else {
  sketch.UI.message('Something went wrong 😕')
}

完成了!現在你可以檢查一個圖層是否是熱狗了。我相信你一定很好奇在你學會這個之前你是怎麼工作的!

插件指令的程式碼可以在這裡找到:https://github.com/mathieudutour/sketch-hotdog/blob/master/src/is-it-a-hotdog.js

結論

雖然這是一個相當愚蠢的例子,但我剛剛展示了如何在 Sketch 插件中實現和利用機器學習。讓我換一種說法——我們將人工智能引入了設計工具,而且不是隨便什麼人工智能。通過利用蘋果的 Core ML 框架,我們在運行設備上的最先進機器學習模型時,可以獲得最大的性能和效率——因此數據甚至不需要離開你的 MacBook 就可以進行分析。

人工智能正在成為設計工具的一部分,而且其發展速度比任何人想像的都要快。從突變設計建議您接下來可能想在畫板上放置哪些組件,機器學習在設計領域的潛力幾乎是無限的。我迫不及待地想看看未來會是什麼樣子——希望它不僅僅是熱狗。


如果您是一名開發人員,並且想要構建這樣的插件,請與我們聯繫。我們有一個充滿活力的開發者社區和一個廣泛的插件生態系統,我們很樂意您成為其中的一份子。請通過 developer@sketch.com 與我們聯繫,或訪問 www.sketchplugins.com 了解更多信息。

您可能還喜歡

免費試用 Sketch

無論您是 Sketch 的新手,還是想看看有什麼新功能,我們都能讓您在幾分鐘內設置好並準備好開始您的最佳工作。

免費開始使用
免費開始使用