从字符串重新创建张量

Recreate Tensor From String

我正在使用 tensorflow.js(node) 作为将图像文件预处理为张量的一种方式。

const tf = require('@tensorflow/tfjs');
require("@tensorflow/tfjs-node")
const mobilenetModule = require('@tensorflow-models/mobilenet');
const knnClassifier = require('@tensorflow-models/knn-classifier'); 
const { loadImage, createCanvas } = require('canvas')

当我创建一个 classifier 时,它将张量 class 对象保存为 key:value 对。创建此对象后,我将其字符串化,并将其写入文件以便稍后使用。

{ '0':
   Tensor {
     kept: true,
     isDisposedInternal: false,
     shape: [ 5, 1024 ],
     dtype: 'float32',
     size: 5120,
     strides: [ 1024 ],
     dataId: {},
     id: 1333,
     rankType: '2',
     scopeId: 728 },
  '1':
   Tensor {
     kept: true,
     isDisposedInternal: false,
     shape: [ 5, 1024 ],
     dtype: 'float32',
     size: 5120,
     strides: [ 1024 ],
     dataId: {},
     id: 2394,
     rankType: '2',
     scopeId: 1356 } }
fs.writeFileSync("test", util.inspect(classifier.getClassifierDataset(), false, 2, false))

当我解析该字符串时,因为它不是标准的 JSON,.parse() 方法发现文件有错误

(node:14780) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token ' in JSON at position 2

如何将这种格式的字符串转换回完全相同格式的对象?

编辑:

已解决: 将我的张量转换为数组

将该张量保存为字符串

从它的存储位置中提取该字符串

重新创建张量

let tensorArr = tensor.arraySync()
fs.writeFileSync("test", JSON.stringify(tensorArr))
 let test = JSON.parse(classifierFile)
tf.tensor(test)

将推荐 tensorflow-model KnnClassifier 使用他们的 .getClassifierDataset

自动执行此操作

不可能将该字符串转换回其原始张量。这样做的原因是数据不包含张量的实际数据。这只是一些元数据。

我们以您给出的第一个数据为例:

Tensor {
    kept: true,
    isDisposedInternal: false,
    shape: [ 5, 1024 ],
    dtype: 'float32',
    size: 5120,
    strides: [ 1024 ],
    dataId: {},
    id: 1333,
    rankType: '2',
    scopeId: 728
}

关于张量,我能说的是它是二阶的,形状为 5x1024。总大小为 5120(因此它有 5120 个值与该张量相关联)。然而,实际的张量数据不存在于此数据中。

另一个错误也是你使用了util.inspect函数,它应该只用于调试目的和保存数据。引用 docs:

The util.inspect() method returns a string representation of object that is intended for debugging. The output of util.inspect may change at any time and should not be depended upon programmatically.

您应该改用 JSON.stringify

正确的做法

下次要保存张量时使用 tensor.array() (or tensor.arraySync()) 函数。

例子

const t = tf.tensor2d([[1,2], [3,4]]);
const dataArray = t.arraySync();
const serializedString = JSON.stringify(dataArray);
console.log(serializedString);

这将 return:[[1,2],[3,4]]

要反序列化数据,您可以使用 tf.tensor 函数:

const serializedString = '[[1,2],[3,4]]';
const dataArray = JSON.parse(serializedString);
const t = tf.tensor(dataArray);
t.print();

t 就是和上面一样的张量,输出将是:

Tensor
    [[1, 2],
     [3, 4]]