不仅仅是美食,我们的目标是通用物体识别

2021-04-02 16:11:05 浏览数 (1)

作者:围城之上 编辑:夏歌

偶然间看到了 Second State 和腾讯云联合举办的 AI 推理函数活动,试了一下食物识别的模板函数,识别结果还是挺准确的。而且听说来了就有奖品,作为资深动手实践者(羊毛党)怎么能错过?这是第一次使用云函数部署 AI 模型,不用自己搭建服务器,还挺有意思的。正好利用周末时间,经过一番学习和摸索终于完成任务:做了一个通用物体识别的 Serverless AI 推理函数。我们的征途是星辰大海,可不能被美食所阻挡。

先让我们来看看效果图吧,第一位萌物嘉宾闪亮登场。

(Haru是 Second State 台北办公室的团宠 ,Haru在日语里是春天的意思)

Haru 是混种猫,你能看出 Haru 是什么品种的猫吗?动物识别已经是老生常谈,但是可不可以识别出特定种类呢?首先来试一试这个 Serverless AI 推理函数可不可以识别出猫的特定种类。

(经过咨询 Haru 的主人,主人也不知道 Haru 是什么品种了,毕竟是混种猫,AI 说是埃及猫,那就是吧)

再来试试我的 Mac Book 吧,同时出镜的还有与我朝夕相处的搭档。你也可以在线体验一下,看看这个 TensorFlow 模型准不准。

https://sls-website-ap-shanghai-4lgfl0s-1305260968.cos-website.ap-shanghai.myzijiebao.com/

甚至连火车都可以识别出来。

这是如何做到的

这个 Serverless AI 推理函数的想法源自于《全新开发体验!腾讯云 serverless 助力你的 AI 模型进入生产环境》这篇文章。

想直接看源码的朋友,点击这里。

https://github.com/yumingle/tencent-tensorflow-scf

在这里,我选用了 tensorflow 提供的 mobiletnet 中的量化模型 mobilenet_v1_1.0_224_quant,这个模型可以识别1000多种物品,除了我们身边常见的小动物和日用品,识别楼房飞机也不在话下。

但是毕竟是受模型精度所限,可能对某些细分种类做不到很高的覆盖,大家如果有兴趣,可以自己做迁移学习来训练地标建筑的模型,或者是找到其他具体种类的模型,来生成一个 Serverless AI 推理函数。比如 Second State 出的鸟类识别 Serverless 函数和昆虫类识别 Serverless 函数。

代码逻辑并不复杂,准备模型,上传图片 、运行TensorFlow 模型、返回结果都是由 Rust 实现的。

代码语言:javascript复制
// 加载训练好的 TensorFlow lite 模型。
let model_data: &[u8] = include_bytes!("mobilenet_v1_1.0_224_quant.tflite");
// 上传图像的格式是 base64 编码,并通过腾讯云 API 网关封装在 JSON 对象中。
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer).expect("Error reading from STDIN");
let obj: FaasInput = serde_json::from_str(&buffer).unwrap();
let img_buf = base64::decode_config(&(obj.body), base64::STANDARD).unwrap();
// 加载上传图像并将其调整为224x224,这是这个 MobileNet 模型所需的尺寸,后面会介绍如何快速获得这个数据
let flat_img = ssvm_tensorflow_interface::load_jpg_image_to_rgb8(&img_buf, 224, 224);
// 用图像作为输入张量运行模型,并获取模型输出张量。
let mut session = ssvm_tensorflow_interface::Session::new(&model_data, ssvm_tensorflow_interface::ModelType::TensorFlowLite);
session.add_input("input", &flat_img, &[1, 224, 224, 3])
.run();
let res_vec: Vec<u8> = session.get_output("MobilenetV1/Predictions/Reshape_1");`

res_vec 向量包含图像中每个对象的概率列表(例如,该图像中蛋糕的概率为0.8)。下面的 Rust 代码读取这些对象的标签,并从 Tensorflow 模型输出中以最高概率打印出对象标签。

代码语言:javascript复制
let labels = include_str!("labels_mobilenet_quant_v1_224.txt");

    let mut i = 0;
    let mut max_index: i32 = -1;
    let mut max_value: u8 = 0;
    while i < res_vec.len() {
        let cur = res_vec[i];
        if cur > max_value {
            max_value = cur;
            max_index = i as i32;
        }
        i  = 1;
    }

    let mut label_lines = labels.lines();
    for _i in 0..max_index {
      label_lines.next();
    }
    let class_name = label_lines.next().unwrap().to_string();
    if max_index != 0 {
      println!("上传的图片里面{} <a href='https://www.google.com/search?q={}'>{}</a>", confidence.to_string(), class_name, class_name);
    } else {
      println!("上传的图片里面没有检测到任何物体");
    }
}`

这里的代码逻辑与模板函数基本一致,只是替换了模型与图像参数。整体来说,这个模板函数可以快速将 AI 推理带到可使用的状态,且腾讯云每月会给个人开发者一定额度,所以使用这个模板函数做一个自己的 side project ,可以说是既省心又省钱。

使用过程中的一些 Tips

在这一部分,我来分享一些替换 TensorFlow 模型过程中的一些小建议,希望大家少走弯路,可以快速做出自己的 Serverless AI 推理函数。

如何获取 TensorFlow 模型中 input 和 output 的 tensor 维度信息以及 layer name

Wasm 的库还不太完善,这一步可以先用 python 实现。

代码语言:javascript复制
python model_test.py

然后会得到下面的信息,这里的信息对应了 main.rs 文件的重要参数,可以直接进行修改。否则 output 的 res_vec 一直都是 0。

Item

Value

input demension

[1, 224, 224, 3]

input layer name

input

output layer name

MobilenetV1/Predictions/Reshape_1

bootstrap 没有权限

在部署过程中,文件 permission 发生了改变,变成了 Bootstrap not executable。这个问题有 Serverless 社区的开发者提供了一种解决方案,我这里再提供一种解决方案。

在腾讯云 console 中,进入“函数服务” -- “函数管理”,右键一个文件,选择 “在集成终端中打开”, 确保自己在文件目录下,然后执行下面的命令,让 bootstrap 文件有执行权限,最后 deploy 就好了。

代码语言:javascript复制
chmod -R 777 .

不过,根据腾讯云 serverless 产品经理的最新说法,这个问题已经得到了解决,更新到最新版本的 cli 就可以啦。如果还出现了 Bootstrap not executable 的问题,可以用 sls deploy —force 部署。

在这个过程中还有环境搭建与本地测试的小建议,详细过程可以去 readme 文件阅读。

小结

本文项目里使用的模型是很多人做移动端物体识别的“启蒙”模型。借助本次 Second State 的 Serverless AI 推理函数模板非常简单方便地就在云函数服务上部署了 AI 应用,同时在这个过程也看到了 Rust 编译成的 WASM 提供前端 JS 调用的高性能解决方案的广阔前景。

References

  • 识别物体的源码
  • Serverless AI 推理函数模板
  • WebAssembly 虚拟机 SSVM

点击阅读原文,查看文中所附链接

0 人点赞