从字符串重新创建张量

时间:2019-05-01 14:13:07

标签: tensorflow javascript-objects knn tensorflow.js

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

 "aggregations":{
      "weeks_avg":{
         "buckets":[
            {
               "key_as_string":"2019-03-28 00:00:00 UTC",
               "key":1553731200000,
               "doc_count":147,
               "week":{
                  "values":{
                     "95.0":24.0078125
                  }
               }
            },
            {
               "key_as_string":"2019-04-04 00:00:00 UTC",
               "key":1554336000000,
               "doc_count":1815,
               "week":{
                  "values":{
                     "95.0":23.0078125
                  }
               }
            },
            {
               "key_as_string":"2019-04-11 00:00:00 UTC",
               "key":1554940800000,
               "doc_count":1821,
               "week":{
                  "values":{
                     "95.0":22.0078125
                  }
               }
            },
            {
               "key_as_string":"2019-04-18 00:00:00 UTC",
               "key":1555545600000,
               "doc_count":1815,
               "week":{
                  "values":{
                     "95.0":22.0078125
                  }
               }
            },
            {
               "key_as_string":"2019-04-25 00:00:00 UTC",
               "key":1556150400000,
               "doc_count":1671,
               "week":{
                  "values":{
                     "95.0":24.0078125
                  }
               }
            }
         ]
      }
   }
}

创建分类器时,它会将Tensor类对象另存为key:value对。创建该对象后,我将其进行字符串化,然后将其写入文件中,以便以后使用。

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')
{ '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 } }

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

fs.writeFileSync("test", util.inspect(classifier.getClassifierDataset(), false, 2, false))

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

编辑:

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

将该张量保存为字符串

从存储位置中提取字符串

重新创建张量

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

将推荐tensorflow模型KnnClassifier与其.getClassifierDataset自动做到这一点

1 个答案:

答案 0 :(得分:0)

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

让我们以您提供的第一个数据为例:

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

关于张量,我能说的是它的等级为2,形状为5x1024。总大小为5120(因此具有与该张量关联的5120值)。但是实际的张量数据不存在。

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

  

util.inspect()方法返回用于调试的对象的字符串表示形式。 util.inspect的输出可能随时更改,因此不应以编程方式依赖它。

您应该改用JSON.stringify

正确的方法

下次要保存张量时,请使用tensor.array()(或tensor.arraySync())功能。

示例

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

这将返回:[[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]]