AI Pocket 支持手势识别和面部识别

更新概要

长话短说,本次代码主要更新了以下几点:

  1. 用 TS 重构小程序,使用 rollup 编译打包
  2. 小程序支持 handpose 模型,可以识别出手势(21 个关键点)
  3. 小程序支持 facemesh 模型,可以识别出人脸和五官的关键点共 468 个(我也没具体数

背后的故事

巧妇难为无米之炊

我希望把更多的 AI 模型装到 AI Pocket 上,在小程序上就可以跑机器学习/深度学习模型,打造一个「流弊」的 AI 口袋。

正如之前立的 Flag,我老早就想把 handpose、facemesh 等模型移植过来。

然而,小程序有 2M 的包大小限制,tfjs 的核心库再加上各模型库的大小已经逼近/超过了这个上限。而使用分包并不能有效解决这个问题,因为 npm 包默认安装在主包中(主要是懒得折腾)。

所以,支持更多模型和应用的想法,就暂时搁置了。

一个 Issue 引发的思考

某一天,一个少年给我提了个 Issue,里面提到了他使用 tfjs 3.x 的 custom tfjs 特性进行体积裁剪的实践。当时我眼前一亮,觉得又双叒叕可以搞事情了。

总结一下这位少年的实践经验,主要在于两点:custom-tfjs 和 tree-shaking,或者强行归类一下,其实都是 tree-shaking。

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 importexport。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

tfjs 体积之所以大,是因为包含了巨多的方法;然而实际进行模型预测时,我们仅需要其中的少量 API。

若能使用 tree-shaking 技术精简代码,便可以大幅度减少小程序体积,利用有限体积的代码包,做更多有趣的事情。

以下图为例,使用小程序的构建工具得到的 miniprogram_npm 代码共 1.36MB,而使用 tree-shaking 手段得到的代码(主要是 chunks 和 app.js)共 640KB,体积减少 50%。

代码体积

一个假期

尽管这个想法很好,但是一直没啥时间去尝试,也就又搁置了几个月,直到最近的中秋假期。

虽然技术手段是明确的,但改造点带来的工作量也是不小的:

  1. 为了方便地使用上 rollup 的 tree-shaking 能力,需要使用 TS 重构小程序
  2. 调试两个新模型

所以,中秋节前一周,几乎每天晚上加完班回来,我还要 Debug 搞到 12 点多才休息(其中有几次是因为接到同事咨询电话,整个人清醒了,干脆接着肝一会)。

直到今天晚上,终于把重构的第一个版本肝出来了!欢迎使用体验!

AI Pocket 小程序码

一些总结

我发现,在优化体积这方面:

  1. 其实使用 custom-tfjs 和不使用的差别并不大,至少在我的场景里只有不到 5KB 的差别(前提是 rollup 中使用了 tree-shaking)
  2. 开发者工具中,把「上传代码时自动压缩混淆(Terser)」勾选上,对实际代码包体积也有优化效果,比如 AI Pocket 从 1587KB 降为 1160KB

再聊聊 rollup 的一些其它作用:

  1. tfjs 默认加载的模型地址在国内访问非常慢,使用 rollup 插件可以将模型地址换为国内 CDN 地址,或者是私人模型地址,非常的方便
  2. body-pix 模型的一个 getInputSize 优先判断输入是否为 HTMLCanvasElement,在安卓端运行时会产生错误(迷之 Bug),同样也是使用 rollup 插件,可以非常方便地偷梁换柱,让该方法直接返回 Tensor 的大小,完美解决兼容性问题

一些规划

补充文档

也许是我文档和教程的不完善,有不少的同学联系到我,咨询我如何快速把源代码玩起来,就还挺烦的。

计划有时间补一下文档和教程(或者出个小册子/教学视频),方便众多学生和相关从业者快速上手。

完善错误处理

目前代码写得比较赶,有些异常/错误没处理,需要逐渐优化补齐。

探索趣味篇应用

目前,趣味篇除了一个「初识 AI」,一直没有新增。

现在基础的模型都算补齐了,接下来重点结合具体场景,出一些有趣的应用。比如:手机算力测试、在线试妆、舞姿测试等等。

也欢迎有想法的同学提 Issue/MR,一起共建 AI Pocket,再次附上开源代码地址:HunterXuan/wx-tfjs-demo

参考资料

  1. Tree Shaking
  2. deepkolos/wxmp-tensorflow
  3. Generating size-optimized browser bundles with TensorFlow.js
  4. Custom Module Demo
  5. rollup.js 文档