【问题标题】:How to load model with tf.loadModel from firebase storage?如何使用 tf.loadModel 从 Firebase 存储加载模型?
【发布时间】:2019-06-07 03:57:06
【问题描述】:

我正在 ionic3 框架中开发一个用于识别绘制字符的应用程序,但我在导入模型时遇到了问题。我已通过两种不同的方式将 Keras 中的模型(使用 tensorflowjs_converter 转换)导入到我的 ionic3 应用程序中:

  1. model.json 和权重文件(分片)被放入文件夹 /assets/models
  2. model.json 和权重文件(分片)托管在 Firebase 存储中。

当使用 first 方法在浏览器中启动应用程序时,模型和权重已正确加载,并且我能够预测类。但是当使用ionic cordova run android --device在我的Android设备中启动应用程序时,模型似乎没有从权重文件中检索数据,因为它给出了以下错误:

Based on the provided shape, [3, 3, 32, 64], the tensor should have 18432 values but has 917.

现在,我尝试将文件托管在 Firebase 存储中以尝试解决此问题。我从存储中检索model.json,但我仍然得到与上述相同的错误在浏览器和设备中

根据在应用程序中本地存储碎片和模型的经验,我得出的结论是,无论哪种方式,设备都无法识别碎片。

另外,当使用 Firebase 存储方法 in device 时,尝试从 url 获取模型时,我发现以下错误:Failed to fetch

这是检索分片和模型的代码:

const modelURL: string = await this.db.getModel();
const shards: string[] = await this.db.getShards();

modelURLshards 包含来自 firebase 存储的下载 url。模型和分片保持在同一级别:

/* Firebase Storage hierarchy */

https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fmodel.json?alt=media&token=******
https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fgroup1-shard1of4?alt=media&token=******
https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fgroup1-shard2of4?alt=media&token=******
https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fgroup1-shard3of4?alt=media&token=******
https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fgroup1-shard4of4?alt=media&token=******

因此,我将模型的下载网址传递给tf.loadModel

import * as tf from '@tensorflow/tfjs';    

await tf.loadModel(modelURL).then(model => {
    const output: any = model.predict(img);
});

那么,有什么方法可以将分片传递到从 firebase 存储中获取的 tf.loadModel(),以便在我的设备和浏览器中检索从模型进行预测所需的所有数据?

感谢您的帮助。

【问题讨论】:

  • 我刚刚遇到了一个关于这个 [github.com/tensorflow/tfjs/issues/272] 的 GitHub 问题。似乎在本地保存模型时,在浏览器中运行良好,但在设备上尚不支持。同时,在问题 [github.com/tensorflow/tfjs/issues/410] 中指出,Node.js(设备 - 本机)上的 loadModel 不起作用,因为在尝试从 url 获取模型时节点中缺少获取。有一种解决方法,但我不明白。希望这会有所帮助。

标签: typescript ionic-framework firebase-storage tensorflow.js tensorflowjs-converter


【解决方案1】:

tf.loadModel() 调用的 http 加载器假定 model.json 和相应的权重文件 (group1-shard1of1,...) 共享相同的 url 路径前缀。例如: 给定的模型文件位于: https://foo.bar/path/model.json 加载程序尝试在以下位置检索权重文件: https://foo.bar/path/group1-shard1of1, ...

在你的情况下 const modelURL: string = await this.db.getModel(); const shards: string[] = await this.db.getShards();

如果 modelUrl 和 shards 不共享相同的路径,您可能需要创建自己的 BrowserHttp IOHandler 以进行加载: const model = await tf.loadModel(new MyOwnHttpIOLoader(modelUrl, shards));

如果是这样,您也许可以通过手动编辑 model.json 文件来对齐它们。在model.json文件中,有一个权重文件路径数组。

使用 firebase 存储的问题是模型文件的 url 是:https://firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fmodel.json 有路径 firebasestorage.googleapis.com/v0/b/project-foo.com/o 加载器将使用该路径并尝试在firebasestorage.googleapis.com/v0/b/project-foo.com/o/group1-shard1of4 处加载权重文件。但它与您的体重 url firebasestorage.googleapis.com/v0/b/project-foo.com/o/model%2Fgroup1-shard1of4 不匹配,它缺少 model%2F 前缀。

为了让加载器工作,你可以手动更新model.json添加前缀。 在文件中搜索“weightsManifest”,编辑“paths”数组,使其类似于 ["model%2Fgroup1-shard1of4", ...]

【讨论】:

  • 感谢您的回答!我根据您的要求更新了问题。我已经从我的存储中编写了路径,从中检索模型和分片。如您所见,它们处于同一级别。
  • 您需要将 gs:// url 转换为 http url,我认为这个 SO stackoverflow.com/questions/41763973/… 可能有用。基本上这个想法是当前的 loadModel api 查看模型文件链接的协议并确定如何加载文件。目前不支持 gs://。通过将其转换为 https://,无需创建自己的 IOHandler 即可加载它。
  • 如果您可以添加一个新的 IOHandler 来加载和保存 gs 文件并为 tensorflow.js 做出贡献,那就太棒了。
  • 实际上,我正在从 firebase 存储 .getDownloadURL() 检索带有内置函数的 url,它已经为您提供了 https:// 格式的下载 url。我会更新我的问题,给您带来的不便,我深表歉意。
  • 所以,正如你所说,它应该在设备上按预期检索模型,但由于某种原因,failed to fetch 错误弹出。
猜你喜欢
  • 2021-02-07
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 2019-08-19
  • 2020-02-14
  • 2023-03-22
  • 2018-04-23
  • 2020-09-02
相关资源
最近更新 更多