# 使用 eKuiper 函数插件运行TensorFlow Lite 模型

LF Edge eKuiper (opens new window) 是一款边缘轻量级物联网数据分析/流软件,可在各种资源受限的物联网设备上运行。

TensorFlow Lite (opens new window) 是一组帮助开发人员在移动端、嵌入式和物联网设备上运行 TensorFlow 模型的工具,它使得设备上的机器学习预测具有低延迟和较小的二进制容量。

通过集成 eKuiper 和 TensorFlow Lite,用户只需要上传预先构建的 TensorFlow 模型, 即可在规则中使用该模型来分析流中的数据。 在本教程中,我们将演示如何通过 ekuiper 快速调用已预先训练好的 TensorFlow 模型。 4

# 先决条件

# 模型下载

如需运行 TensorFlow Lite 解释器,我们需要一个经过训练的模型。在本教程中,我们将不介绍如何训练和涵盖这个模型,您可以通过查看 tflite converter (opens new window) 了解如何做到这一点。我们既可以训练一个新的模型,也可以在线选择已训练好的模型。 在本教程中,我们将使用 mattn/go tflite (opens new window)sin (opens new window) 模型和 mobilenet_v1_1.0_224 (opens new window) 演示。

# 运行 eKuiper

本教程使用团队发布的 eKuiper Docker 镜像 lfedge/ekuiper:1.8.0-slim 和 eKuiper manager Docker 镜像 emqx/ekuiper-manager:1.8.0 演示,安装方法及简单使用方法请参考这里 (opens new window)

# TensorFlow Lite 插件下载

TensorFlow Lite 以预编译插件的形式提供,用户需自行下载安装。 下载插件 注册函数

# Sin 模型运行

请自行下载 sin 模型 (opens new window), 此模型根据输入值返回推理结果。例如用户输入 π/2, 取 1.57, 则计算结果 sin 1.57 约为 1。 用户需准备 MQTT Broker 并自行创建 MQTT 源用于向 eKuiper rule 发送待处理的数据并将推理结果发送回 MQTT Broker。

# MQTT 源

注意模型输入数据格式必须为字节数组, 而 json 不支持字节类型,因此需要在数据源中指定数据类型,由源将其预处理为字节数组。 源设置

# 模型上传

用户可以通过 eKuiper manager 上传模型文件到 eKuiper。如下图所示。 模型上传

# 调用模型

用户安装完 TensorFlow Lite 插件后,可以在 SQL 中按正常内置函数那样调用模型。第一个参数为模型名称,第二个参数为待处理数据。 模型调用

# 验证结果

结果如下图所示,当输入为 1.57 时,推导结果约为 1。 结果查询

# MobileNet V1 模型运行

请自行下载 MobileNet V1 模型 (opens new window), 此模型输入 224 * 224 像素的图像信息,返回大小为 1001 的 float 数组。 为了获取图片信息,我们利用另一个预编译 video 插件从直播源中定时提取图片作为规则的输入,并将推理结果发送到 MQTT Broker 中。

# video 源安装与配置

video 源定期从直播源中拉取数据并从中抽取图片数据。直播源可以采用此链接 (opens new window)。下图分别为 video 插件下载与配置。 video 源安装 video 配置

注意: 源数据格式部分应选为 binary 类型。

# image 函数插件安装

由于预编译模型需要 224 * 224 像素的图片数据,因此需要安装另一个预编译插件 image 来对图片进行 resize。 image 安装 resize 注册

# 模型上传

用户可以通过 eKuiper manager 上传模型文件到 eKuiper。如下图所示。 模型上传

# 调用模型

用户安装完 TensorFlow Lite 插件后,可以在 SQL 中按正常内置函数那样调用模型。第一个参数为模型名称,第二个参数为调用 resize 函数的返回结果。其中 self 为二进制数据对应的 key。 模型调用

# 验证结果

结果如下图所示,图片数据经过推理后,返回结果为字节数组(经过 base64 编码)。 结果查询

以下为经过 base64 译码后得到的字节数组,共有 1001 个元素。需要结合所测试模型来解释其意义。 在本例中,测试模型为图像识别模型,此模型共支持 1001 种物品分类,因此推导结果中的 1001 个元素与 1001 种物品按照顺序一一对应。例如第一个数组元素匹配第一个物品,其中元素的值代表匹配程度,值越大匹配度越高。 物品的列表可从此处 (opens new window)获得。 结果解释

用户可编写代码从中筛选出匹配度最高的物品标签,以下为示例代码

package demo

import (
    "bufio"
    "os"
    "sort"
)

func loadLabels() ([]string, error) {
    labels := []string{}
    f, err := os.Open("./labels.txt")
    if err != nil {
        return nil, err
    }
    defer f.Close()
    scanner := bufio.NewScanner(f)
    for scanner.Scan() {
        labels = append(labels, scanner.Text())
    }
    return labels, nil
}

type result struct {
    score float64
    index int
}

func bestMatchLabel(keyValue map[string]interface{}) (string, bool) {
    labels, _ := loadLabels()
    resultArray := keyValue["tfLite"].([]interface{})
    outputArray := resultArray[0].([]byte)
    outputSize := len(outputArray)
  
    var results []result
    for i := 0; i < outputSize; i++ {
        score := float64(outputArray[i]) / 255.0
        if score < 0.2 {
            continue
        }
        results = append(results, result{score: score, index: i})
    }
    sort.Slice(results, func(i, j int) bool {
        return results[i].score > results[j].score
    })
    // output is the biggest score labelImage
    if len(results) > 0 {
        return labels[results[0].index], true
    } else {
        return "", true
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 结论

在本教程中,我们通过预编译的 TensorFlow Lite 插件,在 ekuiper 中直接调用预先训练好的 TensorFlow Lite 模型,避免了编写代码,简化了推理步骤。