专栏首页大龄程序员的人工智能之路当微信小程序遇上TensorFlow - 本地缓存模型

当微信小程序遇上TensorFlow - 本地缓存模型

从明天开始,我开始休年假,准备去云南逛一逛,估计这段时间又无法更新公众号,还请大家谅解。

在《当微信小程序遇上TensorFlow - tensorflow.js篇》一文中,我介绍了在微信小程序中使用TensorFlow.js,有朋友可能注意到,小程序每次都需要从网络加载模型。虽然tensorflow.js官方声称利用了浏览器的缓存技术,并不会每次都从网络下载。但在微信小程序中,使用的是wx.request接口下载文件,测试下来发现,似乎没有缓存机制。虽然小程序号称即用即走,但每次都需要从网络下载模型,完全体现不出端推断的优点,况且深度学习模型通常也不小,通常有好几M。那我们能否将模型存储到本地呢?

查阅tfjs的文档,在浏览器中,提供了几种本地存储的方式:

  1. 将模型保存到浏览器的local storage,后续可以从local storage加载
  2. 将模型保存到浏览器的IndexDB,然后从IndexDB加载
  3. 将模型通过下载方式保存到本地,然后可以通过文件上载方式加载模型

微信小程序支持两种形式的本地存储:数据缓存和本地文件。为此,我参考了 browser_files.ts 的实现,实现了微信小程序平台下的本地文件存储 mp_files.ts 。具体代码可以参考:https://github.com/mogoweb/wechat-tfjs-core

实现上并没什么特别的难度,但是栽在微信小程序的坑里,爬了好几天才找到原因。具体说来就是 FileSystemManager.readFile(Object object) 这个接口,不要想当然的认为将 encoding 设为 binary,就会返回 ArrayBuffer 类型数据,文档对 encoding 参数的说明是:

指定读取文件的字符编码,如果不传 encoding,则以 ArrayBuffer 格式读取文件的二进制内容

所以为了以二进制字节读取文件内容,千万不要传 encoding 参数,否则永远返回的是 string 类型数据。

至于模型保存,可以参考如下代码,为此我为小程序定义了一个 mp:// 前缀:

const save_model = async model => {

  const saveResult = await model.save('mp://' + wx.env.USER_DATA_PATH + '/mymodel');
  console.log(saveResult);
}

加载模型,文件路径请指定正确的json和权重文件,无需加上 mp:// 前缀:

const load_model = async () => {

  let model_files = [wx.env.USER_DATA_PATH + '/mymodel.json', wx.env.USER_DATA_PATH + '/mymodel.weights.bin'];
  var model = await tf.loadLayersModel(tf.io.mpFiles(model_files));
  return model;
}

示例代码可以参考:https://github.com/mogoweb/wechat-tfjs-examples

需要注意的是,微信小程序对于本地文件总大小有10M的限制,所以这种方法只适合比较小的模型,如果那种几十M的深度学习模型,还是尽量部署到服务器。毕竟小程序的初衷就是小巧、轻便,如果过重,就背离了小程序的设计理念。

本文分享自微信公众号 - 云水木石(ourpoeticlife)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • TypeScript简介_TypeScript笔记1

    TypeScript 最初是个微软内部项目,叫 Strada,致力于提升大型 JS 项目(当时内部需求是 Bing Maps、 Office Web Apps ...

    ayqy贾杰
  • this类型_TypeScript笔记11

    返回类型是this,表示所属类或接口的子类型(称之为有界多态性(F-bounded polymorphism)),例如:

    ayqy贾杰
  • TypescriptServerPlugin_VSCode插件开发笔记3

    VS Code能够正确支持JS/TS跳转到定义、补全提示等功能,但仅限于符合Node Module Resolution以及TypeScript Module ...

    ayqy贾杰
  • 接口_TypeScript笔记3

    对于对象等复杂结构的类型,TypeScript的理念是鸭子类型(duck typing),即值的“形状”:

    ayqy贾杰
  • 基本类型_TypeScript笔记2

    JavaScript有7种类型:Boolean、Number、String、Undefined、Null、Object,以及ES6新增的Symbol

    ayqy贾杰
  • 模块解析机制_TypeScript笔记14

    模块化机制让我们能够把代码拆分成多个模块(文件),而编译时需要知道依赖模块的确切类型,那么首先要找到它(建立模块名到模块文件路径的映射)

    ayqy贾杰
  • React Suspense

    前端应用达到一定规模时(比如bundle size以MB为单位),势必面临代码拆分的强需求:

    ayqy贾杰
  • 组合类型与类型保护_TypeScript笔记9

    Object.assign能把source: U身上的可枚举属性浅拷贝到target: T上,因此返回值类型为T & U

    ayqy贾杰
  • 函数_TypeScript笔记5

    带类型的函数声明足够表达一个函数的类型信息,但无法复用。那么有办法复用一个函数的类型吗?

    ayqy贾杰
  • 模块_TypeScript笔记13

    简单来讲,如果一个文件中含有合法的import或export语句,就会被当做模块(拥有模块作用域),否则就将在运行在全局作用域下。例如:

    ayqy贾杰

扫码关注云+社区

领取腾讯云代金券