Press "Enter" to skip to content

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

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

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

 

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

 

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

 

请切换到tfjs分支。

 

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

 

 

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

 

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

 

loadLayersModel无法加载模型

 

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

 

Uncaught (in promise) Error: Unable to find the fetch() method. Please add your own fetch() function to the global namespace.

 

为什幺会出现这个问题呢,原来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,需要打开项目配置的增强编译开关:

 

 

待完善问题

 

 

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

 

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

 

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

 

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注