跳过导航
走进 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 是一个可以通过关键字搜索的图像数据库。 它还允许你选择一个关键字并下载与该关键字相关的图像 URL 列表,这对于我们接下来要做的事情非常有用。 我选择了“hotdog”、“chilidog”和“frankfurter”作为热狗的图像,选择了“pets”、“buildings”、“plants”和“pizza”作为非热狗的图像。 如果你不想自己查找图像 URL,你可以直接获取我的

接下来,我们需要循环遍历 URL 并下载实际图像。 我们可以使用脚本自动执行此操作 - 我不会在此处详细解释,但你可以在 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 显示一个 UI 来浏览我们刚刚标记的数据集。

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 中的 woulda core 包一样使用。

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 插件中实现和利用机器学习。让我换句话说——我们将人工智能引入了设计工具,而且不仅仅是任何 AI。通过利用 Apple 的 Core ML 框架,我们在设备上运行最先进的机器学习模型时,可以获得最大的性能和效率——因此数据甚至不需要离开您的 MacBook 即可进行分析。

人工智能正在成为设计工具的一部分,而且发生的速度比任何人想象的都要快。从变异设计建议您接下来可能想要在画板上放置哪些组件,机器学习在设计方面的潜力几乎是无限的。我迫不及待地想看看未来会怎样——希望它不仅仅是热狗。


如果您是一名开发人员,并且想构建这样的插件,请与我们联系。我们拥有一个充满活力的开发者社区和一个广阔的插件生态系统,我们希望您成为其中的一员。请通过 developer@sketch.com 与我们联系,或访问 www.sketchplugins.com 了解更多信息。

您可能还喜欢

走进 Sketch

Sketch 与 AI

一段时间以来,我们一直在思考人工智能对 Sketch 的意义。以下是我们可能使用它的方式、我们永远不会使用它的方式以及指导我们思考的内容。

免费试用 Sketch

无论您是 Sketch 的新手,还是回来看看有什么新功能,我们都会在几分钟内让您设置好并准备好完成您的最佳工作。

免费开始
免费开始