大多数浏览器和
Developer App 均支持流媒体播放。
-
在 Core ML 中使用模型部署及安全性
探索如何在 app 二进制文件之外部署 Core ML 模型,从而在 app 中应用机器学习功能时为你提供更强的灵活性和控制能力。了解Core ML 模型部署如何让你将修改后的模型交付给你的 app 而无需更新。我们还将引导你逐步了解如何通过加密来保护自定义机器学习模型,并在 Xcode 中预览你的模型性能。 获取有关使用 Core ML 的更多信息,包括如何应用在 TensorFlow 和 PyTorch 等环境中训练过的模型,我们还建议你观看“使用 Core ML Converter 在设备上获取模型”。
资源
相关视频
WWDC20
-
下载
(你好 WWDC 2020) 你好 欢迎来到 WWDC (在 Core ML 中使用模型部署及安全性) 大家好 我是 Anil Katti 我很高兴与大家分享 今年我们在 Core ML 中 引入的一些出色新功能 Core ML 使你可以 轻松地将机器学习与你的 app 无缝集成 从而为你的用户 打开通往无数精彩体验的大门 你的 Core ML 模型 是实现这些体验的核心 今天我们将围绕这个模型 来介绍它的新功能 在这个讲座中 我们会涉及一些主题 从部署你的模型的新方式 说到如何加密它们 以及 Xcode 中的一些增强功能 我们这就开始 我们在设计 Core ML 时 考虑到了你的 app 开发工作流程 当你有一个模型后 只需要将它拖放进你的 Xcode 项目 就可以与你的 app 集成 Xcode 会将你的模型编译为 在设备上运行的最佳格式 当你提交你的 app 时 编译好的模型会与你的 app 捆绑在一起 它们会一同在 App Store 上架 接着到达用户的设备 将模型与你的 app 捆绑在一起 效果非常好 我们强烈建议你这么做 这样 只要用户安装了你的 app 就可以立即使用模型了 某些情况下 你也许需要 在模型交付过程中 有更大灵活性和掌控度 今天 我们会介绍 Core ML 模型部署 来为大家提供这种灵活性 Core ML 模型部署为你提供了一种 向你的 app 交付模型的新方式 使用模型部署仪表盘 模型能够通过 Apple Cloud 被储存、管理和部署 设备会在其可用时定期检索更新 模型部署赋予了你 独立于 app 更新周期 来开发和部署模型的能力 一种组合和管理 可协同工作的模型的新方式 以及将模型定位给特定的设备群体的选择 对于这些功能我们非常兴奋 下面就让我们一一细说 先说独立开发
一般情况下 当你重新训练你的模型时 你可能会计划 将它们与下一次 app 更新捆绑在一起
但如果你的模型更新进度 与 app 的进度不一致怎么办? 放在以前 你必须通过推送更多的 app 更新 来把更新后的模型发送到用户手上
而现在 使用模型部署 你可以快捷轻松地更新你的模型 而不必再更新 app 本身了 下一项:模型集合
模型集合是一种将一个 或多个与你的 app 功能相关的模型 进行分组的好方法 比如说 你在开发一款游戏 而它的其中一个关卡 需要一组模型来支持一项功能 你可以通过将这些模型 分组进单个模型集合 来使它们保持同步 当你部署一个模型集合时 部署会让 一个集合内的所有模型保持在一起 并通过原子方式将它们交付给你的 app 我迫不及待地想展示实际操作了 但我们开始演示之前 让我先描述一下我们将如何采用这项功能 那么 采用模型部署分三步 第一步 要使用新的 Core ML API 来主动选择加入模型部署 下一步 通过创建一个模型存档 来为模型作部署准备 你可以在 Xcode 中完成
最后一步是上传准备好的模型 并在模型部署仪表盘上部署 每次更新你的模型时 你只需要重复第二和第三步 我们在演示操作中仔细看看这些步骤 我有一个可以对花卉进行分类的简单 app 并且在你轻点两次图片后 会加上酷炫的视觉效果 它使用了两个 Core ML 模型 一个图像分类器和一个风格转换模型
我选择集成了模型部署 这样就可以将更新模型 与 app 更新过程分离 从而单独对模型进行迭代 那么 第一步是使用新的 API 来主动选择加入模型部署 我们来看看在 Xcode 中如何操作 我现在打开了我的 Xcode 项目 尽管这个 app 可以完成一系列事情 但是在这次演示中 我们只关注花卉分类的功能 下面是我们今天要实行的关键方法 它为给定图像中的花卉分类 并在用户界面更新分类标签 调用这个方法时 我要做的第一件事 是创建一个 FlowerClassifier 的实例 并将它储存在一个变量中 这使我可以在后续调用中 访问预先加载好的模型 而不用每次都加载模型了 那么现在我会开始检查预先加载的情况
这里 我会检查变量是否已经设置好 如果设置好了 就使用它对图像进行分类并立即返回 接着 我们要实现逻辑以加载模型
还记得我们说过模型被分组进集合中了 稍后 我将展示如何在新的仪表盘中 创建和部署模型集合 但目前 我对于访问 已经部署好的集合比较有兴趣 为此 我只需在 MLModelCollection 中 调用 beginAccessing 方法
第一次用这个方法 调用带有标识符的模型集合时 系统会在后台队列中 下载那个集合中的所有模型 并进行注册 便于这些模型在未来进行更新 你可以使用进度对象来监视下载进度
这里我们用的模型集合标识符 是“FlowerModels” 我们得做下记录 因为这在以后创建模型集合时是必要信息 这个方法也返回了 MLModelCollection 实例的异步结果 以此作为一种结果类型 我们来看 如何从这个结果访问下载好的模型
成功执行这项操作后 我们会得到 包含了模型集合条目的模型集合实例 每个模型对应一个条目 我可以使用模型名称作为密钥来访问 FlowerClassifier 模型的模型集合条目 条目内是一个模型 URL 指向一个由系统下载好 并放置在 app 容器内的已编译模型 访问模型集合也可能会失败 比如 如果首次调用时没有网络连接 那么模型将下载失败 处理失败情况很重要 在这个例子中 我们只需记录错误 然后回退以使用捆绑模型即可 接下来 我们要实现逻辑以加载模型
我实现了一个简单的辅助方法以加载模型 它将一个可选的 modelURL 作为输入 并用它加载 FlowerClassifier 模型 如果 URL 为空 它就会回退 并加载与 app 捆绑的模型
最后一步是使用 FlowerClassifier 来对图像进行分类
这里是代码 当模型成功加载后 我们使用加载好的模型来对图像进行分类 并且将它储存在变量中 用于后续的分类请求 我们有另一种方法来处理失败的模型加载 在这个情况中 它向用户显示了相应的错误消息
这就是为 app 作模型部署准备 所需要的所有代码 那么 我如何为模型本身做部署准备呢? 其实我可以在 Xcode 中完成 如果你点击 Xcode 中的模型 你会看到 今年我们引入了一个新的实用工具标签 其中包含模型部署的部分
我可以通过创建一个模型存档 来为模型作部署准备
好了 Xcode 创建了 FlowerClassifier.mlarchive 并将其保存在了磁盘上 我可以点击这里来定位文件位置
它就被放置在我们原本的模型文件旁边 最后一步 是在模型部署仪表盘上部署这个模型 Xcode 提供了一个按钮 能让你直接进入 Safari 浏览器中的模型部署仪表盘 在仪表盘上 你首先会注意到 我们有一种创建模型集合的方法 首先我要为我们的花卉模型 创建一个新的模型集合 并将它命名为“FlowerModels” 这应该与 app 中指定的内容相匹配
接着 我们来提供一条不错的描述 比如像是 “为花卉图像构建的模型集合”
然后列出我们计划在这个集合中 加入的两种模型
第一个是 FlowerClassifier
然后是 FlowerStylizer
接着点击创建按钮 这之后 我可以通过 创建一项新部署来部署模型 我称之为“全球部署” 因为我打算将这些模型 部署到所有设备的 app 中
我可以针对这里的每一个模型名称 上传我创建的模型存档 我先选中 FlowerClassifier 接着是 Stylizer 然后点击右上角的部署按钮
在模型集合页面 我可以确认刚刚创建的部署 处于活跃状态 所以这看起来不错 只要设备运行的是 使用此模型集合的 app 版本 那么这些模型就可以在所有设备上使用 现在我要启动 app 并尝试对花卉进行分类
我选了一张大丽花 可以看到它也被分类为大丽花 (看起来像是大丽花) 这回我再试试芙蓉花 (看起来像是芙蓉花) 看来 app 这次也答对了 我在这里使用的模型 只学习了三种不同的类别 而蔷薇不在其中 我来试试用一张蔷薇的图片会发生什么
和预期的一样 app 似乎无法识别蔷薇 (未知) 假如说我想提升我的 app 让它能够将蔷薇分类 由于我已经 在这个 app 中采用了模型部署 那么通过使用模型部署 再部署一个 学习过蔷薇图像的模型 我就可以轻松添加这项功能 为了这次演示 我已经准备好了更新后的模型来进行部署
我们现在去部署仪表盘 看看如何更新一个模型 我可以通过创建一项新部署 来部署一个更新过的模型 这次 我会选择改进后的分类器 加上同样的风格编辑器 然后点击部署按钮
和先前一样 这些更新后的模型 都可以在所有设备上的 app 中使用 不过可能无法立即使用 每台设备都会判定出一个对的时间 继而在后台下载模型 并在 app 下一次启动后可使用 我们来看看在 OS 将更新后的模型 同步到设备后 再启动我的 app 会发生什么 选择同样的这张 之前未能被分类的蔷薇图片 我看到它这次被分类为蔷薇了 (看起来像是蔷薇) 无需更改哪怕一行代码 我们就通过改进模型 提升了用户体验 我觉得这真是太酷了 下面 我们来讨论定向部署
通常来说 你的 app 在初期阶段时 它可能只能为你的用户提供一套模型 但是 随着你的 app 不断进化 针对不同人群 来使用专业模型或许更为合理 一种解决方案 就是将所有模型捆绑在 app 中 并在运行时使用合适的模型 但这么做效率不高 而且如果模型很大 可你却想让 app 的下载大小尽可能小该怎么办呢? 使用定向部署 你可以定义规则 这样每位用户的设备上只有它所需的模型 我们来看看如何设置其中的一个 最近 我改进了我们的 FlowerClassifier 不过是专门为 iPad 设计的 原来 由于 iPad 的相机角度和光影设置 用它拍摄的照片 和用 iPhone 拍摄的照片不太一样 尽管我想在 iPad 上使用一个新模型 但现有的模型在其它所有设备上都很适用 我们来看看 如何将 iPad 专用模型只定位在 iPad上 回到仪表盘中 我可以选择克隆一项已有部署 或创建一项新部署 就目前的情况 我会创建一项新的并称它为“目标 iPad”
首先 我要为这项部署的选择默认模型 这些模型会被交付到 与部署规则不匹配的所有设备上
之后 我可以添加其它定向规则 你可以看到我能定位的所有不同规则 我会选设备分类 并选择 iPad 也就是说 对于这条定向规则 我选择了 iPad 专用模型
我现在可以部署这些模型了 设备会根据设备分类提取正确的模型 不需要在 app 中做额外的改动 我们为大家展示了 使用 Core ML 模型部署来帮助解决 一些有趣的使用情况是多么轻松 你在使用这项功能时 需要记住下面这几点 首先 我们强烈推荐你往部署仪表盘中 上传模型前 先在本地对每一个模型进行测试 这能确保你的用户 不会遇到无法使用的模型
接着 要注意 你部署的模型无法在设备上立即使用 每台设备的系统 会自行决定何时在后台下载模型 因此 你的 app 需要一个后备计划 以防部署好的模型无法使用
最后 模型集合提供了一个 便捷的整理模型的方式 我们推荐你基于 app 的每项功能 将模型集合分组 那么 总结一下 我们已经为大家展示的内容 Core ML 模型部署 是将模型交付给你的用户的新方式 且独立于 app 更新 模型集合 为你提供了新的模型分组及使用方式 此外 当你想针对特定人群部署模型时 定向模型会提供很大帮助 我们认为 这些功能将为你提供更大的灵活性 并有助于你更加便捷地向用户交付模型 现在我要移交给 John Durant 他将进一步介绍 有关我们今年 为大家准备的其它精彩功能的信息
谢谢 Anil 大家好 感谢你们的参与 我们很高兴与你们分享这些功能 我们迫不及待地想看到 你将使用它们构建的出色 app 了 到目前为止 我们介绍了一些新的且更快的方式 来将模型交付给你们的用户 现在我们来看看你可以如何加密这些模型 通过模型加密 你可以发布你的模型 并且清楚 它们在静止和传输过程中都是被加密的 让我们来了解一下 它的具体含义以及工作原理 无论你的模型 是与 app 捆绑在一起还是部署在 cloud Xcode 实际加密的 都是已编译的 Core ML 模型 这个已编译模型 而非原本的 .mlmodel 文件 才是用户设备上的 app 中 真正存在的内容 那么 你该如何加密这个已编译模型呢? 很简单 使用 Xcode 首先你需要一个加密密钥 稍后我会为你展示如何做一个密钥 使用密钥 你可以让 Xcode 在构建的同时加密你的模型 或者你也可以在生成模型存档时 使用密钥对其进行加密 无论通过哪一种方法 已编译模型在传输过程中 以及在用户设备上处于静态时 都会保持加密状态 那么 你如何在运行时 使用一个已加密的模型呢? 其实你可以 像使用常规模型一样使用加密模型 Core ML 会自动为你解密模型 但解密后的模型只会存在于内存中 文件系统中的已编译模型 会始终保持加密状态 在你首次加载你的加密模型时 OS 会替你的 app 安全获取 并安全储存模型的解密密钥 这之后 当你的 app 再次加载同样的模型时 就不再需要网络连接了 我们这就进入 Xcode 看看采用模型加密 有多么简单 我现在回到 Anil 之前使用的同样一个 app 中 假设我想将我们的图像分类模型加密 首先我需要创建一个加密密钥 为此 我要打开 Xcode 中的模型 接着到实用工具标签这里
然后我会点击“创建加密密钥”
这里我们看到的是 Xcode 将加密密钥与一个团队关联了起来 所以选择你用来构建 app 的 同样的团队账号十分重要 我点击“继续”后 Xcode 会向 Apple Cloud 发送一个请求 继而生成一个新的加密密钥 服务器会将密钥安全储存好 并将副本发回给 Xcode 现在我们可以看到 Xcode 生成了一份 扩展名为 .mlmodelkey 的新文件 并且将它 投放到了我的 Core ML 模型旁边 所以可以看到 这里我们有 .mlmodel 和 .mlmodelkey
非常好 现在我们有一个密钥了 那么我们可以将这个密钥 共享到团队的安全密钥资料库 这样团队中的其他开发者也可以使用它了
现在我们有了密钥 就可以使用它来加密我们的模型了 首先 我们来看看 Anil 之前展示的情景 他使用 Core ML 的模型部署 来部署了模型 这次 当我创建一个模型存档时
Xcode 预选了我模型旁边的 .mlmodelkey 我们点击“继续”
接着我们会看到 Xcode 和先前一样生成了一个模型存档 但这次 它加密了存档内容 剩下的步骤都和之前完全一致 同 Anil 之前的操作 通过将它上传到 Core ML 的部署仪表盘 我可以轻松部署 这个已加密的模型存档 好了 部署方面已经非常棒了 但如果我想将模型 捆绑进 app 自身该怎么办呢? 也有方法来加密这些模型 在这个 app 中 我还有第二个模型 叫做 FlowerStylizer 我将再次运行这个 app 便于我们看到它的作用 当我选取了一张图片并轻点两次后 我们看到 一种酷炫的风格转换效果被应用在了上面 看起来不错! 如果你想自己构建诸如此类的模型 可以查看题为 “在 Create ML 中 构建图像和视频风格转换模型”的讲座 现在这个模型与我的 app 捆绑好了 如果我想加密它 就需要为它生成一个密钥 然后让 Xcode 在构建时对模型进行加密 首先 我要为这个模型生成一个密钥
我们看到 FlowerClassifier.mlmodelkey 已经被保存在磁盘上了
现在我需要做的是让 Xcode 在构建时使用这个密钥来进行加密
我现在要复制这些编译器标记 再来到项目属性中 构建阶段 编译源 然后我要找我的模型 找到了 我现在有了 FlowerStylizer.mlmodel 接着我要到编译器标记这里
粘贴上两个破折号开头的加密内容 再把光标 指向磁盘内的 .mlmodelkey 文件
完成之后 我们就可以再次进行构建
所以现在每当我们构建 app 时 Core ML 编译器将对模型进行编译 然后使用模型的加密密钥对其进行加密 这意味着 app 现在内置了这个已加密、编译的模型 好 现在我们来看如何加载加密过的模型
我们到这里 会看到有一项功能叫 “为图像添加风格” 但由于首次加载模型需要网络连接 因此我们引入了异步模型加载方法 就在这里 FlowerStylizer.load 我们将弃用默认的初始化程序 而且我们强烈建议你 换成这个新的 .load 方法 因为它为你提供了 处理模型加载错误的机会 加载会自动从 Apple Cloud 获取密钥 并且和你期望的一样运行 尽管 Core ML 第一次时需要网络访问来获得密钥 但它之后就不需要再次获取那个密钥了 比如说 你关闭了你的 app 随后又再次启动 这次 Core ML 不会再发送网络请求 因为 OS 已经将密钥安全存储在了本地 你可以看到我们返回了 包含模型在内的“T”结果 我们可以在成功的情况下将它解包 这时我们就有了模型 并可以像之前那样对其进行风格编辑 但我们也可能遇到失败的情况 在失败的情况下 我们有辅助方法 这里你会注意到 我们特意捕捉到了 一个 modelKeyFetch 错误 这种情况下 我们就会想让用户知道 他们需要网络连接 或者稍后重试 就是这样 采用模型加密真的如此简单 来概括一下 你可以通过三个简单步骤来使用模型加密 首先 用 Xcode 生成一个加密密钥 接着 用这个加密密钥加密你的模型 最终 在设备上加载并使用加密过的模型 创界、加密、加载 就是如此简单 无论你是在 app 中捆绑模型 还是通过模型部署发送 模型加密都可以无缝运行 你要做的就是创建一个密钥 加密你的模型并调用 .load 我们负责处理剩下的部分 来让你专注于开发出色的 app 结束之前 我们还想和你分享一些针对 Core ML 的 激动人心的 Xcode 更新 在我们的演示中 你也许注意到了 Xcode 现在会向你展示 有关你的模型的更多信息 你现在可以直观地看出 一个模型支持的 OS 版本 它的分类标签 甚至于一些内部类神经网络的详情 另外一项我们认为特别有用的新功能 是交互式模型预览 它的乐趣就更不用说了
现在你能够直接在 Xcode 中 连一行代码都不用写的情况下 交互式地预览和试验你的模型 我们支持对多种模型的预览 比如图像分割
位姿检测、深度评估以及更多模型功能 还包括 你能使用 Create ML 来训练的所有模型 预览类型的完整列表如图所示 我们鼓励你去探索 developer.apple.com 上可用的模型
同时我也很高兴地宣布 Core ML 模型 已成为 Xcode Playground 中的一等公民 只需将一个 Core ML 模型 拖放进你的资源文件夹 现在你的 Playground 就获得了与 Xcode 项目相同的 自动生成的类别界面 这使你能够在 一个实时的交互式编码会话中 通过编程的方式来试验你的模型 Playground 也是一个与朋友和同事 分享你的模型演示的绝佳方式 我们今天涵盖了大量内容 所以让我们快速回顾一遍 我们介绍了 Core ML 模型部署 使你能够 独立于 app 来交付 Core ML 模型 这使你在改进模型时 可以快速轻松地将它们发布和定位 我们认为这将大大加快 app 的开发进程 以及你采用机器学习的速度 我们还介绍了模型加密 在模型的传输过程中和静止状态下 都能够保护你的模型 且无需设置你自己的托管和密钥管理 现在你可以加密 Core ML 模型 无论它们是与你的 app 一起 还是作为模型部署的一部分 最后 我们为 Xcode 添加了一些 Core ML 增强功能 更易于你了解以及预览你的模型 并与其进行交互 谢谢大家观看我们的讲座 希望你们喜欢 WWDC 的其余部分
(你好 WWDC 2020)
-
-
4:34 - Flower Classifier using Core ML Model Deployment
private func classifyFlower(in image: CGImage) { // Check for a loaded model if let model = flowerClassifier { classify(image, using: model) return } MLModelCollection.beginAccessing(identifier: "FlowerModels") { [self] result in var modelURL: URL? switch result { case .success(let collection): modelURL = collection.entries["FlowerClassifier"]?.modelURL case .failure(let error): handleModelCollectionFailure(for: error) } let result = loadFlowerClassifier(from: modelURL) switch result { case .success(let model): classify(image, using: model) case .failure(let error): handleModelLoadFailure(for: error) } } } func loadFlowerClassifier(from modelURL: URL?) -> Result<FlowerClassifier, Error> { if let modelURL = modelURL { return Result { try FlowerClassifier(contentsOf: modelURL) } } else { return Result { try FlowerClassifier(configuration: .init()) } } }
-
20:03 - Compiler flag for encrypting a model
--encrypt "$SRCROOT/HelloFlowers/Models/FlowerStylizer.mlmodelkey" [Production note] or if we're tight for horizontal space we can use this: --encrypt "$SRCROOT/.../FlowerStylizer.mlmodelkey"
-
20:50 - Working with an encrypted model
func stylizeImage() { // If we already loaded the model, apply the effect if let model = flowerStylizer { applyStyledEffect(using: model) return } // Otherwise load and apply FlowerStylizer.load { [self] result in switch result { case .success(let model): flowerStylizer = model DispatchQueue.main.async { applyStyledEffect(using: model) } case .failure(let error): handleFailure(for: error) } } } func handleFailure(for error: Error) { switch error { case MLModelError.modelKeyFetch: handleNetworkFailure() default: handleModelLoadError(error) } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。