当微信小程序遇上TensorFlow - tensorflow.js篇

Posted 云水木石

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当微信小程序遇上TensorFlow - tensorflow.js篇相关的知识,希望对你有一定的参考价值。

在上一篇推送《重磅好消息!TensorFlow开始支持微信小程序》中,介绍了TensorFlow开始支持微信小程序平台,并计划将我之前开发的人工智能微信小程序识狗君使用tensorflow js改写。

这个端午节,趁着放假,空余时间比较多,开始研究微信小程序中如何使用tensorflow.js。

在写下上一篇推送后,我简单尝试过在微信小程序中使用tensorflow.js,发现直接使用还是存在一点问题,所以本次的目标是走通简单的流程:加载预训练模型mobilenet,可以用来识别图片所属分类。

示例代码位于: https://github.com/mogoweb/aidog  

请切换到tfjs分支

运行起来,效果是这样的:

嗯,示例是简单了一点,但所有使用tensorflow js的关键步骤都包括。

下面就简要描述一下我所遇到的坑及解决之道:

loadLayersModel无法加载模型

使用tfjs定义模型,训练模型并进行预测都没问题,但是使用 loadLayersModel 加载预训练模型,却出现如下错误:

为什么会出现这个问题呢,原来tfjs-core为了可移植性,平台相关的操作,由各平台自行实现。从网络上获取数据就是这样的平台相关操作,浏览器、Node各有自己的实现方法。浏览器的实现依赖于fetch API,而微信小程序上,非常遗憾的看到了一条更新日志:

微信小程序中,网络请求可以通过 wx.request 实现,问题是如何实现全局的fetch函数呢?这可难倒了我。在网上搜索的时候,发现了一个项目:

https://github.com/HunterXuan/wx-tfjs-core.git

原来这哥们早就研究过将tfjs移植倒微信小程序平台,写了几篇博客,值得看一看。参考了他的修改,我也完成了tfjs-core的改造,参考我在GitHub上建的项目:

https://github.com/mogoweb/wechat-tfjs-core.git

我的修改有点不同,新定义了PlatformMP,主要是考虑到微信小程序和普通浏览器还有一些差异,以后存在差异的代码都放到PlatformMP里面实现。

是不是还有更好的方法,比如不需要修改tfjs的代码,在微信小程序里面实现全局fetch函数?我不太确定,希望前端高手指点。

预训练模型被墙

由于一些众所周知的原因,访问Google的服务总是不顺畅。我长期挂VPN,这倒不是问题。关键是,如果在微信小程序中访问Google,这就有些麻烦,不可能期望用户能够个个玩转VPN。

幸运的是,tfjs上有一个issue:Model accessibility issues in China #1375 。里面给出了临时解决方案,我们可以通过镜像:https://cnpmjs.org/mirrors/tfjs-models/ 获取模型。

这个镜像能够存在多久还是个未知数,可能最靠谱的还是将模型同步下来,自己存储。这种方式还没有来得及研究,有时间再看看。

获取图像数据

在tfjs-examples中,是通过:tf.browser.fromPixels 接口获取图像数据,但在微信小程序中却行不通,因为微信小程序平台中移除掉了document对象。好在以前在开发识狗君微信小程序识研究过通过wx canvas获取图像数据,具体实现请参考源码。

有一点需要注意,通过canvas获取到的图像数据是RGBA格式,而mobilenet模型接收的却是RGB,为此我写了一个转换函数:

// RGBA to RGB
var rgbData = new Uint8Array(res.width * res.height * 3);
let idx = 0;
for (let i = 0; i < res.data.length; i +=4)
rgbData[idx] = res.data[i];
rgbData[idx + 1] = res.data[i + 1];
rgbData[idx + 2] = res.data[i + 2];
idx += 3;

感觉这个函数实现得效率有些低,是否有更好的方法,还请高手指教。

async / await

作为一名浏览器内核开发人员,平常也接触一些js代码,但前端发展实在太迅猛了,好些新式的js代码已经完全看不懂。比如在tfjs-examples代码中,就有许多async / await等用法,模块导出也有好几种方式,Promise又是什么鬼?搞的我头晕脑胀,多亏了知识搜索能力还不错,遇到问题就Google,每次都能逢凶化吉。

要在微信小程序中使用async / await,需要打开项目配置的增强编译开关:

待完善问题

  1. 模型每次都需要从网络加载,需要研究如何利用微信小程序的storage,这样模型可以缓存到本地,避免每次从网络加载。由于微信小程序包有大小限制,所以将模型打包到小程序不可能。

  2. 将自己的模型转化为tfjs模型,并在微信小程序中使用。

  3. 不修改tfjs-core,将平台相关代码放到微信小程序中实现。

你还可以看:

当微信小程序遇上TensorFlow:Server端实现

当微信小程序遇上TensorFlow:Server端实现补充

当微信小程序遇上TensorFlow:小程序实现

当微信小程序遇上TensorFlow:接收base64编码图像数据

当微信小程序遇上TensorFlow:终章

识狗君微信小程序的部署


以上是关于当微信小程序遇上TensorFlow - tensorflow.js篇的主要内容,如果未能解决你的问题,请参考以下文章

当微信小程序遇到AR

当微信和支付宝遇上友盟

微信小程序 navigateTo 传对象参数

微信小程序和具有权限认证CSRF机制的Django服务端交流

HBuilder 下运行uniapp(微信小程序)时,微信开发者工具进入游客模式

HBuilder 下运行uniapp(微信小程序)时,微信开发者工具进入游客模式