错误:io_utils.ts:116 未捕获(承诺) 范围错误:Float32Array 的字节长度应为 4 的倍数



TensorFlow.js版本

TensorFlow/TFJS-core@0.15.2

浏览器版本

Chrome 72.0.3626.109 for Mac

描述问题或功能请求

我尝试了在tensorflow/tfjs-examples中演示tfjs-examples-web-web-transfer-learning。在文件索引.js中,tensorflow尝试加载模型,如下所示:

const mobilenet = await tf.loadModel(
'https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json'
);

但是每次我运行这个演示时,它都会运行这个句子并下载模型。我想让它从本地服务器加载。所以我下载了 model.json 并将其放在资产文件夹中。然后,我将资产部署在本地服务器中的端口 1234。 像这样加载它:

const mobilenet = await tf.loadModel(
'http://localhost:1234/json/model.json'
);

但它没有用,安慰了

io_utils.ts:116 Uncaught (in promise) RangeError: byte length of Float32Array should be a multiple of 4
at new Float32Array (<anonymous>)
at o (io_utils.ts:116)
at Object.decodeWeights (io_utils.ts:79)
at models.ts:318
at common.ts:14
at Object.next (common.ts:14)
at o (common.ts:14)

我真的很确定 model.json 与 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json 中的相同,但为什么 id 不起作用?

谢谢你帮助我。

您必须在本地服务器上提供文件,以便浏览器无法直接访问文件系统。这里和那里都问过同样的问题

这真的不应该是一个问题,因为您的浏览器将缓存下载的模型及其所有权重。 因此,您可以只使用公共 URL。 第一次之后的任何访问都将从浏览器缓存中提供,而不是真正再次下载。


如果你真的想在本地服务,或者至少理解为什么它以前不起作用:

model.json 文件不是故事的全部 - 它包含一个 weightsManifest 部分,其中包含权重文件的相对路径。 当您从原始 URL 加载 model.json 时,它会解析并下载所有相邻的权重文件。 因此,若要在本地提供模型,还需要提供所有这些文件。

不幸的是,获取权重文件列表并不完全简单,因为Google Cloud Storage没有以易于访问的方式提供目录列表。 当然,您可以从model.json中捞出文件名(查找诸如"paths": ["group47-shard1of1"]之类的内容。 第二种选择是从命令行使用 gsutil,这应该可以让您下载整个文件夹。 第三个选项是使用 REST API 列出目录内容:https://www.googleapis.com/storage/v1/b/tfjs-models/o?prefix=tfjs/mobilenet_v1_0.25_224,并在那里查找"名称"条目。

第四个也是最简单的选择是从头开始构建 URL:在这种情况下,有 55 个权重组,因此 URL 的范围从 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/group1-shard1of1 到 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/group55-shard1of1。 没有一个组具有多个分片。

最新更新