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

1. 简介

54e81d02971f53e8

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

在此 Codelab 中,您将学习如何使用 Teachable Machine 训练图片分类模型,以及如何使用 TensorFlow.js(一款强大且灵活的 JavaScript 机器学习库)通过 Coral 硬件加速运行该模型。您将构建一个 Electron 应用,该应用会显示来自摄像头的图像,并使用 Coral Edge TPU 对图像进行分类。sig-tfjs GitHub 代码库中提供了此 Codelab 的完全正常运行版本

我需要珊瑚设备吗?

不需要。您可以在没有 Coral 设备的情况下尝试此 Codelab,并且通过改用 WebNN 加速器,仍然可以在桌面设备上获得良好的性能。

构建内容

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

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

学习内容

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

此 Codelab 重点介绍 Node.js 中的 TFLite。对于不相关的概念,我们仅会略作介绍,但是会提供代码块供您复制和粘贴。

所需条件

要完成此 Codelab,您需要:

2. 进行设置

获取代码

我们已将此项目所需的所有代码放入一个 Git 代码库中。首先,请获取代码,并在您喜爱的开发环境中将其打开。对于此 Codelab,我们建议使用在桌面设备上运行 Raspberry 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 上,该库从 Google 的 PPA 中以 Debian 软件包 libedgetpu1-std 的形式提供,适用于 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 版本可以正常运行,但这些测试仍然失败,请通过提交 bug 报告告知我们。

运行起始代码

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

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

我们从何处入手?

我们首先为本 Codelab 设计了一个基本的 Electron 相机应用。代码已经过简化,可以展示 Codelab 中的概念,并且几乎没有错误处理。如果您选择在正式版应用中重复使用任何代码,请确保能处理所有错误并全面测试所有代码。

一个基本 electron 应用,具有设备相机的实时 Feed。

查看起始代码

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

打开调试程序

在按照此 Codelab 进行操作时,您可能需要调试您的应用。由于此应用基于 Electron,因此内置了 Chrome 调试程序。在大多数平台上,您可以按 Ctrl + Shift + i 打开该菜单。点击 Console 标签页,查看应用的日志和错误消息。

这里没有太多其他内容需要探索,因此我们直接训练图像分类器!

3. 训练图像分类器

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

训练分类器

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

现在,您可以开始训练模型了。如果您不确定要训练哪种模型,不妨使用人物检测器,它只检测人物是否在取景框内。

  1. 在新标签页中打开 Teachable Machine 训练页面
  2. 选择图片项目,然后选择标准图片模型
  3. 为每个类别添加图片样本。使用摄像头输入是最简单的方法。您还可以重命名类。
  4. 为每个类别收集足够的数据(通常 50 个样本足够)后,按训练模型

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

一个模型基于两类图像进行训练,

尝试为模型提供不同的输入。如果您发现某个输入被错误分类,请将其添加到训练数据中并重新训练模型。

  1. 如果您对模型的准确度感到满意,请点击导出模型。您需要下载该模型的两个不同版本。
  2. 将模型导出为 Tensorflow Lite 浮点模型。此操作会下载名为 converted_tflite.zip 的文件。在 CPU 上运行的应用
  3. 将模型导出为 Tensorflow Lite EdgeTPU 模型。此操作会下载在 Coral Edge TPU 上运行的名为 converted_edgetpu.zip 的文件。

4. 在您的应用中运行 CPU 型号

现在您已经训练了模型,是时候将模型添加到您的应用中了。学完此部分后,应用将能够使用设备的 CPU 运行您的模型。

将模型文件添加到应用

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

安装依赖项

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

  • tfjs-tflite-node:TensorFlow.js 的软件包,用于在 Node.js 中运行 TFLite 模型。
  • @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 函数中:

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

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

运行模型

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

对摄像头输入进行预处理

目前,摄像头只是一个 HTML 元素,它显示的帧不可用于 JavaScriptrenderer.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 来测量预测所需的时间。

CODELAB 第 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_edgetpu.zip 模型文件。归档文件中包含两个文件。model_edgetpu.tflite 是已保存的 TFLite 模型,包括模型图和权重。labels.txt 包含模型所预测类的人类可读标签。将模型文件放在 coral_model 目录中。

安装依赖项

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

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

npm install --save coral-tflite-delegate

然后,将下面这行代码添加到 renderer.js 文件的顶部来导入委托:

CODELAB 第 2 部分:在此处导入委托。

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

加载模型

现在,您可以加载 Coral 模型了。您可以采用与 CPU 型号相同的方式执行此操作,但现在您需要将选项传递给 loadTFLiteModel 函数以加载 Coral delegate。

CODELAB 第 2 部分:在此处加载委托模型。

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

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

添加一个用于在 CPU 和 Coral 之间切换的按钮

除了在上一部分中添加的 CPU 模型外,您还需要添加 Coral 模型。同时运行这两者会导致很难看出性能差异,因此使用切换按钮可在 Coral 和 CPU 执行之间切换。

使用以下代码添加按钮:

CODELAB 第 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 版本(但目前它不会执行任何操作)。将运行 CPU 模型的代码封装在 if 语句中。请注意,if 语句中省略了 expanded 张量,因为 Coral 模型使用了该张量。

CODELAB 第 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 版本的模型需要 uint8 张量,范围为 0 到 255,因此其输入不需要归一化。不过,输出也是 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 FPS。

您可以按此按钮在 Coral 推断和 CPU 推断之间切换。您可能会注意到,Coal 模型的置信度排名不如 CPU 模型的置信度低,并且通常以偶数位小数结尾。这种精确率损失是在 Coral 上运行量化模型时权衡取舍。在实际使用中通常无关紧要,但需要牢记。

性能注意事项

您看到的帧速率包括预处理和后处理,因此并不能代表 Coral 硬件的功能。您可以通过点击 FPS 计量器更好地了解性能,直到延迟(以毫秒为单位)显示对 model.predict 的调用。不过,这仍然包括将张量移至 TFLite 原生 C 绑定,然后再移至 Coral 设备所需的时间,因此,这并非完美的测量结果。如需获取使用 C++ 编写的更准确的性能基准,请参阅 EdgeTPU 基准页面

另请注意,由于该视频是用笔记本电脑(而非 Raspberry Pi)录制的,因此您看到的 FPS 可能有所不同。

加快 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) 命令来设置它们,但最好按照 LinuxWindows永久性解决方案)说明永久设置它们。如果您使用的是 Windows,

setupvars.bat

命令不支持 Git bash,因此请确保通过 Windows 命令提示符运行该命令以及此 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 推理之间切换。同时运行这两者会导致很难看出效果差异。

使用以下代码添加按钮(请注意,它不会实际切换模型):

CODELAB 第 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 设备。

使用下拉菜单更改设备

要连接下拉菜单以更改使用的 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 函数,以根据按钮状态选择正确的模型:

CODELAB 第 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 FPS。

如果您有集成的 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 博客甚至未来活动上获得特别推介。我们很期待看到你的成果。

可以结账的网站