作者:围城之上 编辑:夏歌
偶然间看到了 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 模型输出中以最高概率打印出对象标签。
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
点击阅读原文,查看文中所附链接