使用 Coral Edge TPU 通过 TensorFlow.js 在 Node 中运行 TFlite 模型

1. 简介

54e81d02971f53e8.png

上次更新日期:2022 年 4 月 11 日

在此 Codelab 中,您将学习如何使用 Teachable Machine 训练图片分类模型,并使用 TensorFlow.js(一个强大而灵活的机器学习库)通过 Coral 硬件加速功能运行该模型。 。您将构建一个 Electron 应用,该应用会显示来自网络摄像头的图片,并使用 Coral Edge TPU 对其进行分类。可在 sig-tfjs GitHub 代码库中找到此 Codelab 的完整版本

我需要 Coral 设备吗?

不需要。您可以试用此 Codelab,而不使用 Coral 设备,但在桌面设备上使用 WebNN 加速器仍可获得出色性能。

构建内容

在此 Codelab 中,您将构建一个对图片进行分类的 Electron 应用。您的应用:

  • 将来自网络摄像头的图片归类到您已训练的模型中定义的类别。
  • 使用 Coral 加速器提高性能(如果有)。
  • 使用 WebNN 提升性能(如果您的平台支持的话)。

学习内容

  • 如何安装和设置 tfjs-tflite-node NPM 软件包以在 Node.js 中运行 TFLite 模型。
  • 如何安装 Edge TPU 运行时库以在 Coral 设备上运行模型。
  • 如何使用 Coral Edge TPU 加快模型推断速度。
  • 如何使用 WebNN 加速模型推断。

此 Codelab 重点介绍 Node.js 中的 TFLite。对不相关的概念和代码块仅做简略介绍,并直接提供代码块供您复制和粘贴。

所需条件

为完成此 Codelab,您需要:

  • 一台装有摄像头的计算机。
  • 对于 Coral,我们建议使用搭载桌面设备的 Raspberry Pi OS(64 位)的 Raspberry Pi。
  • 对于 WebNN,建议使用运行 Ubuntu 20.04 或 Windows 10 的 Intel x86-64 机器。
  • Node.js 版本 >= 12。
  • 了解 JavaScript。
  • (推荐)Cral USB Accelerator,用于加快模型速度。

2. 进行设置

获取代码

我们已将此项目所需的所有代码放入 Git 代码库中。首先,请获取代码并在您常用的开发环境中打开。在此 Codelab 中,我们建议使用搭载桌面设备的 Rasberry Pi OS(64 位)的 Raspberry Pi。这便于连接 Coral 加速器。

强烈建议做法:使用 Git 克隆 Raspberry Pi 上的代码库

如需获取代码,请打开新的终端窗口并克隆代码库:

git clone https://github.com/tensorflow/sig-tfjs.git

您需要为此 Codelab 修改的所有文件都位于 tfjs-tflite-node-codelab 目录(位于 sig-tfjs 中)。在该目录中,您会看到名为 starter_codecpu_inference_workingcoral_inference_workingwebnn_inference_working 的子目录。以下是本 Codelab 步骤的检查点。

代码库中的其他文件包括 tfjs-tflite-node-codelab 所依赖的 NPM 软件包。您无需修改这些文件,但需要运行部分测试以确保环境设置正确。

安装 Edge TPU 运行时库

Coral 设备要求您安装 Edge TPU 运行时库,然后才能使用。按照适用于您的平台的说明操作。

在 Linux 设备 / Raspberry Pi 设备上

在 Linux 上,该库以 Debian 软件包 (libedgetpu1-std) 的形式提供给 Google,适用于 x86-64 和 Armv8(64 位)架构。如果您的处理器使用其他架构,则需要从源代码编译它

运行此命令以添加 Google 的 Coral PPA 并安装 Edge TPU 运行时库。

# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

sudo apt-get update
sudo apt-get install libedgetpu1-std

在 Windows / 其他操作系统上

预编译二进制文件适用于 x86-64 版本的 MacOS 和 Windows,可通过运行 install.shinstall.bat 进行安装脚本进行下载。

重启设备

安装 Edge TPU 运行时后,重启设备以激活安装程序添加的新 Coral Udev 规则。

验证已检测到您的 Coral 设备

如需验证您的 Coral 设备是否可检测到并正常工作,请对 coral-tflite-delegate 软件包运行集成测试。此软件包位于代码库的根目录中。如需运行集成测试,请插入 Coral 加速器并在软件包的目录中运行以下命令:

npx yarn
npx yarn build-deps
npx yarn test-integration

您应该会看到如下所示的输出:

yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.

1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.

无需按照日志中的说明安装 @tensorflow/tfjs-node,,因为您将在 TFLite 中运行该模型。

如果输出包含 Encountered unresolved custom op: edgetpu-custom-op,则表示未检测到您的 Coral 设备。确保您已安装 Edge TPU 运行时库,并将 Coral 设备插入计算机。您还可以按照 Coral 的入门指南来测试 Python 版本的 Coral 绑定。如果 Python 版本可以运行,但这些测试仍然失败,请提交错误报告来告知我们。

运行起始代码

现在,您可以运行起始代码了。请按以下步骤开始操作。

  1. 转到 tfjs-tflite-node-codelab 目录下的 starter_code 目录。
  2. 运行 npm install 来安装依赖项。
  3. 运行 npm start 以启动项目。系统应该会打开一个应用,其中会显示来自计算机的摄像头的视频画面。

我们从何处入手?

我们的起点是专为此 Codelab 设计的基本 Electron 相机应用。代码已简化为显示 Codelab 中的概念,并且几乎没有错误处理。如果您选择在正式版应用中重复使用任何代码,请确保处理所有错误并全面测试所有代码。

一个基本电子应用,具有设备相机的实时信息流。

探索起始代码

此起始代码中有许多文件,但唯一需要编辑的文件是 renderer.js。它控制页面上显示的内容(包括视频 Feed 和 HTML 元素),并且您将机器学习模型添加到应用中。在其他文件中有一个 index.html 文件,但它只是加载 renderer.js 文件。此外,还有一个 main.js 文件,它是 Electron 的入口点。它控制应用的生命周期,包括应用启动时显示的内容以及应用关闭后要执行的操作,但您无需对其进行任何更改。

打开调试程序

在学习此 Codelab 时,您可能需要调试应用。由于此应用基于 Electron,因此内置了 Chrome 调试程序。在大多数平台上,您都可以使用 Ctrl + Shift + i 将其打开。点击控制台标签页,以查看相应应用的日志和错误消息。

此处没有其他探索内容,下面我们就来训练图像分类器吧!

3.训练图像分类器

在本部分中,您将训练自定义图片分类模型的 TFLite 和 Coral 版本。

训练分类器

图片分类器接受输入图片并为其分配标签。在本 Codelab 中,您将在浏览器中使用 Teachable Machine 训练模型。为加快此部分的训练速度,您可以使用台式机或笔记本电脑来代替 Raspberry Pi,但必须将生成的文件复制到 Pi 中。

现在,您可以训练模型了。如果您不确定要训练哪种模型,一种简单的训练模型是人物检测器,它可以检测是否有人在画面中。

  1. 在新标签页中打开“会学习的机器”培训页面
  2. 选择 Image Project,然后选择 Standard image model
  3. 为每个类添加图片示例。 使用网络摄像头输入是最简单的方法。您还可以重命名这些类。
  4. 当您收集了每个类别的足够数据(50 个样本通常已足够)后,请按训练模型

模型完成训练后,您应该会看到模型输出的预览。

模型基于两个人的图片(“人物”和“无人”)进行训练。经过训练的模型的演示会在设备摄像头的帧上进行实时运行,并且模型本身可以多种格式下载。

尝试为模型提供不同的输入。如果您发现输入的分类不正确,请将其添加到训练数据中,然后重新训练模型。

  1. 在对模型的准确性感到满意后,请点击导出模型。您需要下载两个单独的模型版本。
  2. 将您的模型导出为 Tensorflow Lite 浮点模型。系统将下载名为 converted_tflite.zip 的文件。在 CPU 上运行的 API。
  3. 将您的模型导出为 Tensorflow Lite Edge TPU 模型。系统将下载在 Coral Edge TPU 上运行的名为 converted_edgetpu.zip 的文件。

4.在应用中运行 CPU 模型

现在您已训练模型,接下来可以将其添加到应用中。完成本部分后,应用将可以使用设备的 CPU 运行您的模型。

将模型文件添加到应用

解压缩您在训练分类器时下载的 converted_tflite.zip 模型文件。归档中有 2 个文件。model_uquant.tflite 是已保存的 TFLite 模型,包括模型图和权重。labels.txt 包含模型预测的类的直观易懂的标签。将两个文件都放在 modeldirectory 中。

安装依赖项

加载模型并预处理输入需要 TensorFlow.js 的一些依赖项:

  • tfjs-tflite-node:用于在 Node.js 中运行 TFLite 模型的 TensorFlow.js 软件包。
  • @tensorflow/tfjs:TensorFlow.js 的主软件包。

已安装 @tensorflow/tfjs,但您需要使用以下命令安装 tfjs-tflite-node

npm install --save tfjs-tflite-node

安装后,将其添加到 renderer.js 顶部的应用中:

CODELAB 第 1 部分:导入 tfjs-tflite-node。

const {loadTFLiteModel} = require('tfjs-tflite-node');

加载模型

现在,您可以加载模型了。tfjs-tflite-node 提供用于执行此操作的 loadTFLiteModel 函数。它可以从文件路径、ArrayBuffer 或 TFHub 网址加载模型。如需加载模型及其权重,请将以下代码添加到 main 函数中:

第 1 部分代码:在此处加载模型。

const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
      .split('\n');

运行模型

运行模型需要三个步骤。首先,您需要从网络摄像头提取输入帧并对其进行预处理。然后,您可以在该帧上运行模型并获取预测结果。然后,您在页面上显示预测内容。

对摄像头输入进行预处理

目前,摄像头只是一个 HTML 元素,它显示的帧不适用于 JavaScript renderer.js 文件。为了从摄像头中提取帧,TensorFlow.js 提供了 tf.data.webcam,它提供了一种易用的 capture() 方法,用于从相机捕获帧。

如需使用该功能,请将以下设置代码添加到 main()

CODELAB 第 1 部分:在此处设置 tf.data.webcam。

const tensorCam = await tf.data.webcam(webcam);

然后,如需每一帧拍摄一张图片,请将以下内容添加到 run()

Codelab 第 1 部分:在此处拍摄网络摄像头镜头。

const image = await tensorCam.capture();

您还需要预处理每一帧,以便与模型兼容。此 Codelab 使用的模型具有输入形状 [1, 224, 224, 3],因此它需要 224 x 224 像素的 RGB 图片。 tensorCam.capture() 的形状为 [224, 224, 3],因此您需要使用 tf.expandDims 在张量的前面添加一个额外的维度。此外,CPU 模型要求输入介于 -1 和 1 之间的 Float32,但网络摄像头会捕获 0 到 255 之间的值。您可以将输入张量除以 127,以将其范围从 [0, 255] 更改为 [0, ~2],然后减去 1 以获得所需的范围 [-1, ~1]。为此,请将以下几行代码添加到 run() 函数的 tf.tidy() 中:

CODELAB 第 1 部分:在此处预处理摄像头帧。

const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));

请务必在使用张量后对其进行处置。tf.tidy() 会自动为其回调中包含的代码执行此操作,但不支持异步函数。您需要通过调用 dispose() 方法来手动处理之前创建的图片张量。

Codelab 第 1 部分:在此处处理摄像头画面

image.dispose();

运行模型并显示结果

如需对预处理的输入运行模型,请对归一化张量调用 model.predict()。这将返回一个一维张量,其中包含每个标签的预测概率。将此概率乘以 100 可以得到每个标签的百分比概率,并使用起始代码中包含的 showPrediction 函数在屏幕上显示模型的预测结果。

此代码还使用 stats.js 通过在 model.predict 周围调用 stats.beginstats.end 来预测预测所需的时间。

第 1 部分代码:运行模型并在此处显示结果。

stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);

使用 yarn start 再次运行应用,您应该会看到来自模型的分类。

TFLite CPU 模型在 Electron 应用中运行。它会对来自网络摄像头的图片进行分类,并在下方显示每个类的置信度值。

性能

根据当前设置,模型在 CPU 上运行。这种做法非常适合桌面设备和大多数笔记本电脑,但如果您在 Raspberry Pi 或其他低功耗设备上运行时,可能不希望出现这种情况。在 Raspberry Pi 4 上,您可能会看到大约 10 FPS,对于一些应用来说,这可能不够快。如要在不使用速度更快的机器的情况下获得更好的性能,您可以以 Coral Edge TPU 的形式使用特定于应用的芯片。

5. 在应用中运行 Coral 模型

如果您没有 Coral 设备,则可以跳过此部分。

此 Codelab 的这个步骤以您在上一部分编写的代码为基础构建,但如果您想从零开始构建,可以使用 cpu_inference_working 检查点。

运行 Coral 模型的步骤与运行 CPU 模型的步骤几乎完全相同。主要区别在于模型格式。由于 Coral 仅支持 uint8 张量,因此量化了模型。这会影响传递给模型的输入张量及其返回的输出张量。另一个区别是,模型需要使用 Edge TPU 编译器进行编译,才能在 Coral TPU 上运行。TeachableMachine 已经完成此步骤,但您可以访问 Coral 文档,了解如何针对其他模型执行此操作。

将 Coral 模型文件添加到应用中

解压缩您在训练分类器时下载的 converted_edgetpupu.zip 模型文件。归档中包含两个文件。model_edgetpu.tflite 是已保存的 TFLite 模型,包括模型图和权重。labels.txt 包含模型预测的类的直观易懂的标签。将模型文件放在 coral_model 目录中。

安装依赖项

运行 Coral 模型需要 Edge TPU 运行时库。请先按照设置说明进行安装,然后再继续。

TFLite 代理的形式访问 Coral 设备。如需通过 JavaScript 访问这些软件包,请安装 coral-tflite-delegate 软件包:

npm install --save coral-tflite-delegate

然后,将以下行添加到 renderer.js 文件顶部,以导入代理:

CODELAB 第 2 部分:在此处导入代理。

const {CoralDelegate} = require('coral-tflite-delegate');

加载模型

现在,您可以加载 Coral 模型了。您可以采用与处理 CPU 模型相同的方式,只是现在您要将选项传递给 loadTFLiteModel 函数以加载 Coral 代理。

CODELAB 第 2 部分:在此处加载代理模型。

const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);

您无需加载标签,因为它们与 CPU 型号相同。

添加在 CPU 和 Coral 之间切换的按钮

您将 Coral 模型与在上一部分中添加的 CPU 模型一同添加。同时运行两个库会很难看出性能差异,因此切换开关按钮可在 Coral 和 CPU 执行之间切换。

使用以下代码添加该按钮:

第 2 部分代码:在此处创建代理按钮。

let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
  useCoralDelegate = !useCoralDelegate;
  toggleCoralButton.innerText = useCoralDelegate
      ? 'Using Coral. Press to switch to CPU.'
      : 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);

让我们在 run() 函数中附加此条件。当 useCoralDelegate 为 false 时,应运行 CPU 版本。否则,它会运行 Coral 版本(但目前什么都不做)。将代码封装在 if 语句中运行 CPU 模型。请注意,if 语句中不包含 expanded 张量,因为 Coral 模型使用了该张量。

第 2 部分代码:检查是否在此处使用代理。

// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
  // CODELAB part 2: Run Coral prediction here.
} else {
  const divided = tf.div(expanded, tf.scalar(127));
  const normalized = tf.sub(divided, tf.scalar(1));
  stats.begin();
  const prediction = model.predict(normalized);
  stats.end();
  const percentage = tf.mul(prediction, tf.scalar(100));
  showPrediction(percentage.dataSync(), labels);
}

运行模型

模型的 Coral 版本需要 0 到 255 的 uint8 张量,因此输入不需要进行归一化。不过,输出也是一个 0 到 255 范围内的 uint8 张量。它需要转换为 0 到 100 之间的浮点数,然后才能显示。

CODELAB 第 2 部分:在此处运行 Coral 预测。(这是上述代码段的一部分)

stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);

使用 yarn start 再次运行应用,该应用会显示 Coral 加速器的分类。

每次在应用中运行一个 CPU 和 Coral 模型,并且可以通过一个模型在它们之间切换。CPU 模型的帧速率大约为 20 FPS,而 Coral 模型的帧速率大约为 45。

您可以通过按此按钮在 Coral 推断和 CPU 推断之间切换。您可能会注意到,Coral 模型的置信度排名低于 CPU 模型的置信度排名,其排名通常以偶数小数结尾。这种精确率损失是对 Coral 量化模型进行权衡。在实践中,通常并不重要,但需要牢记这一点。

性能注意事项

您看到的帧速率包括预处理和后处理,因此它不能代表 Coral 硬件的功能。您可以点击 FPS 计量器,直到显示延迟时间(以毫秒为单位),从而仅衡量对 model.predict 的调用,从而更好地了解性能。然而,这仍需要将张量移到 TFLite 原生 C 绑定,然后迁移到 Coral 设备,因此这不是一次完美的衡量。如需了解使用 C++ 编写的更准确的性能基准,请参阅 Edge TPU 基准页面

另请注意,视频是在笔记本电脑上录制的,而不是 Raspberry Pi,因此您看到的可能会有所不同。

加快 Coral 预处理

在某些情况下,您可以通过切换 TFJS 后端来加快预处理速度。默认后端是 WebGL,适合大型并行操作,但此应用在预处理阶段不会执行很多这样的操作(它使用的唯一操作是 expandDims,它不是并行操作)。您可以切换为 CPU 后端,以避免在文件顶部导入后添加此行,从而将张量移入和移出 GPU 会产生额外的延迟。

tf.setBackend(‘cpu');

这也会对 TFLite CPU 模型的预处理进行(并行处理),使模型在此更改的运行速度显著减慢。

6.使用 WebNN 加速 CPU 模型

如果您没有 Coral 加速器,或者您只是想尝试其他方式来加速模型,则可以使用 WebNN TFLite 代理。此代理使用 Intel 处理器内置的机器学习硬件,通过 OpenVINO 工具包加速模型推断。因此,此 Codelab 的设置部分并未涵盖其他要求,您需要安装 OpenVINO 工具包。请务必先对照受支持的目标系统平台检查您的设置,但请注意,WebNN 代理尚不支持 macOS。

安装 OpenVINO 工具包

OpenVINO 工具包使用内置于 Intel 处理器中的机器学习硬件来加速模型。您可以从 Intel 下载预编译版本,也可以从源代码构建它。有几种安装 OpenVINO 的方法,但在此 Codelab 中,我们建议您使用适用于 WindowsLinux 的安装程序脚本。请务必安装 2021.4.2 LTS 运行时版本,因为其他版本可能不兼容。运行安装程序后,请确保按照 LinuxWindows永久性解决方案)安装说明中的说明配置 shell 的环境变量。 ),也可以通过运行位于 webnn-tflite-delegate 目录中的 setupvars.sh (Linux) 或 setupvars.bat (Windows) 命令来实现。

验证 WebNN 代理是否正常工作

如需验证 WebNN 代理是否正常运行,请运行存储库根目录中 webnn-tflite-delegate 软件包的集成测试。如需运行集成测试,请在软件包的目录中运行以下命令:

# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration

您应该会看到如下所示的输出:

WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score:  0.934505045413971
.

1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.

如果您看到这样的输出,则表示配置错误:

Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

此输出很可能表示您尚未设置 OpenVINO 环境变量。目前,您可以通过运行 setupvars.sh (Linux) 或 setupvars.bat (Windows) 命令对其进行设置,但建议您按照 Linux中的说明永久性设置这些内容。 Windows永久解决方案)说明。如果您使用的是 Windows,

setupvars.bat

命令不支持 Git bash,因此请确保在 Windows 命令提示符中运行此 Codelab 和其他 Codelab。

安装 WebNN 代理

安装 OpenVINO 后,您现在可以使用 WebNN 加速 CPU 模型。此 Codelab 的这一部分以您在“运行您的应用中的 CPU 模型”部分编写的代码为基础。您可使用在此步骤中编写的代码,不过,如果您已完成 Coral 部分,请改用 cpu_inference_working 检查点,以便从头开始。

WebNN 代理的 Node.js 部分在 npmjs 上分发。如需进行安装,请运行以下命令:

npm install --save webnn-tflite-delegate

然后,将以下行添加到 renderer.js 文件顶部,以导入代理:

CODELAB 第 2 部分:在此处导入代理。

const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');

WebNN 代理支持在 CPU 或 GPU 上运行; WebNNDevice 可让您选择使用哪个。

加载模型

现在,您已准备好在启用 WebNN 代理的情况下加载模型。对于 Coral,您必须加载不同的模型文件,但 WebNN 支持的模型格式与 TFLite 相同。将 WebNNDelegate 添加到传递给该模型的代理列表中以启用该模型:

CODELAB 第 2 部分:在此处加载代理模型。

let webnnModel = await loadTFLiteModel(modelPath, {
  delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});

您无需再次加载标签,因为这是同一个模型。

添加用于在 TfLite CPU 和 WebNN 之间切换的按钮

现在,模型的 WebNN 版本已准备就绪,添加一个按钮以在 WebNN 和 TfLite CPU 推断之间切换。同时运行这两个版本会让性能难以区分。

使用以下代码添加此按钮(请注意,该按钮实际上尚未切换模型):

第 2 部分代码:在此处创建代理按钮。

let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
  useWebNNDelegate = !useWebNNDelegate;
  toggleWebNNButton.innerHTML = useWebNNDelegate
      ? 'Using WebNN. Press to switch to TFLite CPU.'
      : 'Using TFLite CPU. Press to switch to WebNN.';
  divElem.hidden = useWebNNDelegate ? false : true;
}

toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);

此代码还会添加一个 div 元素,用于在下一部分中配置 WebNN 设置。

添加用于在 WebNN 设备之间切换的下拉菜单

WebNN 支持在 CPU 和 GPU 上运行,因此请添加下拉菜单,以便在它们之间切换。将以下代码添加到创建该按钮的代码之后:

// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);

const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
  var optionElem = document.createElement('option');
  optionElem.value = i;
  optionElem.text = webnnDevices[i];
  selectElem.appendChild(optionElem);
}

现在,如果您运行应用,会看到下拉列表,其中列出了“Default”、“GPU”和“CPU”。选择其中的任一项目前不会执行任何操作,因为下拉菜单尚未连接。 应用显示一个下拉菜单,可从中选择“Default”、“GPU”或“CPU”。

让下拉菜单更改设备

要附加下拉菜单以便更改所用的 WebNN 设备,请为下拉选择器元素的 change 事件添加监听器。当所选值发生更改时,请使用代理选项中的相应 WebNN 设备重新创建 WebNN 模型。

在添加下拉菜单的代码之后添加以下代码:

selectElem.addEventListener('change', async () => {
  let webnnDevice;
  switch(selectElem.value) {
    case '1':
      webnnDevice = WebNNDevice.GPU;
      break;
    case '2':
      webnnDevice = WebNNDevice.CPU;
      break;
    default:
      webnnDevice = WebNNDevice.DEFAULT;
      break;
  }
  webnnModel = await loadTFLiteModel(modelPath, {
    delegates: [new WebNNDelegate({webnnDevice})],
  });
});

进行此项更改后,每次创建新模型时,下拉列表都会使用正确的设置创建模型。现在,您需要连接 WebNN 模型并将其用于推断。

运行 WebNN 模型

WebNN 模型可供使用,但用于在 WebNN 和 TfLite CPU 之间切换的按钮实际上并不会切换模型。如需切换模型,您首先需要在加载此 Codelab 的第一部分时加载 TfLite CPU 模型时重命名 model 变量。

更改以下行...

const model = await loadTFLiteModel(modelPath);

...使其与以下代码行一致。

const cpuModel = await loadTFLiteModel(modelPath);

model 变量重命名为 cpuModel,将其添加到 run 函数中,以根据按钮的状态选择正确的模型:

第 2 部分代码:检查是否在此处使用代理。

let model;
if (useWebNNDelegate) {
  model = webnnModel;
} else {
  model = cpuModel;
}

现在,当您运行应用时,该按钮会在 TfLite CPU 和 WebNN 之间切换。 该 TFLite CPU 模型以及 WebNN CPU 和 GPU 模型在应用中运行。当其中一个 WebNN 模型处于活动状态时,下拉菜单会在它们之间切换。CPU 模型大约为 15 FPS,WebNN CPU 模型大约为 40。

如果您拥有集成的 Intel GPU,还可以在 WebNN CPU 和 GPU 推断之间切换。

性能注意事项

您看到的帧速率包括预处理和后期处理,因此并不能代表 WebNN 的能力。您可以点击 FPS 计量器,直到显示延迟时间(以毫秒为单位),从而仅衡量对 model.predict 的调用,从而更好地了解性能。不过,这仍需要将张量移到 TFLite 原生 C 绑定所用的时间,因此这并非完美的衡量方法。

7. 恭喜

恭喜!您刚刚在 Electron 中使用 tfjs-tflite-node 完成了第一个 Coral / WebNN 项目。

请对各种图片进行测试。您还可以在 TeachableMachine 上训练新模型,以对完全不同的内容进行分类。

回顾

在本 Codelab 中,您学习了以下内容:

  • 如何安装和设置 tfjs-tflite-node npm 软件包以在 Node.js 中运行 TFLite 模型。
  • 如何安装 Edge TPU 运行时库以在 Coral 设备上运行模型。
  • 如何使用 Coral Edge TPU 加快模型推断速度。
  • 如何使用 WebNN 加速模型推断。

接下来做什么?

现在,您已拥有一个良好的起点,您可以想出什么创意来将这个机器学习模型运行程序扩展到您可能在实际工作中的实际用例?也许您可以通过快速且经济实惠的推断,彻底改变您所从事的行业;或者,您可以修改烤面包机,让面包看起来刚刚好,再烤一次。无限可能。

如需进一步详细了解 TeachableMachine 如何训练您使用的模型,请查看我们关于迁移学习的 Codelab。如果您正在寻找可与 Coral 搭配使用的其他模型(例如语音识别和姿态估计),请参阅 coral.ai/models。您还可以在 TensorFlow Hub 中找到这些模型的 CPU 版本和许多其他版本。

与我们分享您的成果

您也可以轻松地将今天创作的内容用于其他创意用例,并鼓励您跳出思维定式并继续进行创作。

记得使用 #MadeWithTFJS 标签在社交媒体上关注我们,争取让您的项目有机会在我们的 TensorFlow 博客甚至 将来举办的活动。我们期待看到您的作品。

要结算的网站