我正在try 制作一个包含并可以运行TensorFlow js模型的自含式html文档.我将我的模型从python保存为.h5,然后将其转换为tensorflowjs_convert --input_format keras ....这导致了一个包含model.json的目录(据我所知,它看起来和加载都很好)和权重都存储在一个文件group1-shard1of1.bin中.

我获取每个文件的内容,对它们进行Base64编码,然后将它们作为两个数据URI插入到我的html文件中.

const modelURI = "data:application/json;base64,<Data Here>";
const weightsURI = "data:application/octet-stream;base64,<Data Here>";

Promise.all([fetch(modelURI), fetch(weightsURI)])
    .then(function(resp) {
        return Promise.all([resp[0].json(), resp[1].arrayBuffer()]);
    })
    .then(function(data) {
        tf.loadGraphModelSync([data[0], data[1]]);
    });

问题是,loadGraphModelSync人一直在抱怨

Uncaught (in promise) TypeError: n is null
    value graph_model.js:212
    value graph_model.js:180
    value graph_model.js:167
    loadGraphModelSync graph_model.js:699

我非常确定问题出在我传入的ArrayBuffer上,但我对tfjs甚至是普通的TensorFlow没有足够的经验来了解.

我查看了添加到选项中的pull request,它提到"ArrayBuffer是模型的连接权重的列表",但我找不到任何关于这到底是什么样子的可用信息.有人知道我在这里传递的权重应该是什么格式吗?另一种加载Base64编码数据的方法也会很有帮助.

Edit 1: 在找不出导致缩小的TensorFlow js包中的问题的原因后,我创建了一个快速BUN项目并安装了TensorFlow js NPM包,这使我能够获得一个更有用的错误:

32091 |             if (metadata.structuredOutputKeys != null) {
32092 |                 this.structuredOutputKeys = metadata.structuredOutputKeys;
32093 |             }
32094 |         }
32095 |         this.signature = signature;
32096 |         this.version = "".concat(graph.versions.producer, ".").concat(graph.versions.minConsumer);
                                         ^
TypeError: null is not an object (evaluating 'graph.versions')
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32096:34
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32063:16
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32053:16
      at loadGraphModelSync (.../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32577:5)
      at .../src/index.ts:14:9

推荐答案

该问题与模型权重无关,因为KERAS模型格式是仅限权重的格式(source).因此,model.json中的modelTopology字段为空,这是导致错误的原因.

当我阅读tfjs源代码时,我偶然发现了两个相关的函数: encodeWeightsdecodeWeights文档注释超过decodeWeights条,并通读了函数,这给了我想要的理解.在我看来,"一个平面的ArrayBuffer或一个ArrayBuffer数组,它携带的张量的二进制值按照specs中指定的顺序连接在一起."是一个更精确的解释函数期望什么,并通过扩展loadGraphModelSync期望的ArrayBuffer应该是什么样子.一旦我将我的模型保存为SavedModel,然后重新转换,模型现在似乎可以毫无问题地加载.

Javascript相关问答推荐

如何在NightWatch.js测试中允许浏览器权限?

如何分配类型脚本中具有不同/额外参数的函数类型

yarn安装一个本地npm包,以便本地包使用main项目的node_modules(ckeditor-duplicated-modules错误)

Google图表时间轴—更改hAxis文本 colored颜色

在服务器上放置了Create Reaction App Build之后的空白页面

如何让npx在windows中运行js脚本?

查找最长的子序列-无法重置数组

为什么我的导航条打开状态没有在窗口addeventlistener(Reaction Js)中更新?

我正在建立一个基于文本的游戏在react ,我是从JS转换.我怎样才能使变量变呢?

在运行时使用Next JS App Router在服务器组件中运行自定义函数

如何在使用rhandsontable生成表时扩展数字输入验证?

如何在Svelte中从一个codec函数中调用error()?

输入的值的类型脚本array.排序()

如果NetSuite中为空,则限制筛选

使用API调用的VUE 3键盘输入同步问题

JavaScript:多个图像错误处理程序

使用静态函数保存 node 前的钩子

如何处理不带参数的redux thunk payloadCreator回调函数?

检测带有委托的元素内部的点击,以及元素何时按其类名被选中

为什么我的Reaction组件不能使用createBrowserRouter呈现?