首页 > 解决方案 > 如何在客户端 Tensorflow.js 中重新分配“let”变量?

问题描述

我正在 Udemy 上一门关于 Tensorflow.js 的课程,我一直很喜欢,但我遇到了一个让我完全脱轨的错误,即我似乎无法重新分配用let关键字声明的任何内容.

据我所知,这是在这里提出的一个问题,但以清除缓存和 cookie 的“修复”结束,这对我没有影响。然而,在我提出另一个问题之前,我想在这里检查一下我没有做任何完全愚蠢的事情。对于上下文,这只是html文件中的一个大内联脚本。声明了let一些用于全局范围的变量,但是每当我尝试重新分配它们时,Tensorflow 都认为它们是未定义的。

有趣的是,我在 Chrome 和 Firefox 上收到两条不同的错误消息: Chrome: Type Error: Cannot set property 'undefined' of undefined Firefox: console.log(...) is undefined(尝试记录其中一个变量时)

相关代码片段如下:

// very top of script here
let points
let normalisedFeature, normalisedLabel
let trainingFeatureTensor, testingFeatureTensor, trainingLabelTensor, testingLabelTensor

async function normalise(tensor, previousMin = null, previousMax = null) {
  const min = previousMin || tensor.min()
  const max = previousMax || tensor.max()
  const normalisedTensor = tensor.sub(min).div(max.sub(min))
  normalisedTensor.print(true)
  return {
    tensor: normalisedTensor,
    min,
    max
  }
}

// function that takes two of the problematic variables as args
async function trainModel (model, trainingFeatureTensor, trainingLabelTensor) {
  // not actually making it to here
}

// function that does some reassigning of the problematic variables
async function run () {
  // do some TF stuff, e.g. get a dataset


  const featureValues = points.map(p => p.x)
  const featureTensor = tf.tensor2d(featureValues, [featureValues.length, 1])

  // Extract Labels (outputs)
  const labelValues = points.map(p => p.y)
  const labelTensor = tf.tensor2d(labelValues, [labelValues.length, 1])

  // Normalise features and labels
  normalisedFeature = normalise(featureTensor)
  normalisedLabel = normalise(labelTensor)
  featureTensor.dispose()
  labelTensor.dispose()

  /**
  * I believe it's erroring here on Firefox
  * in Chrome this logs:
  * {tensor: e, min: e, max: e}
  */
  console.log('Normalised feature:\n', normalisedFeature)

  /**
  * I believe it's erroring here on Chrome
  */
  [trainingFeatureTensor, testingFeatureTensor] = tf.split(normalisedFeature.tensor, 2)
  [trainingLabelTensor, testingLabelTensor] = tf.split(normalisedLabel.tensor, 2)

  // Update status and enable train button
  document.getElementById("model-status").innerHTML = "No model trained"
  document.getElementById("train-button").removeAttribute("disabled")
  document.getElementById("load-button").removeAttribute("disabled")
}

请注意,为简洁起见,我省略了一些代码,但希望所有相关的内容都在那里。

如果有人能指出我正确的方向,那将不胜感激。

PS 我已经从本课程之前的模块中获得了代码,所以我相信我可以让 Tensorflow 在浏览器中正常工作。

PPS 我当前版本的代码是从课程解决方案中复制/粘贴的 - 我一直在编写自己的代码,但是当我的代码不起作用时尝试了提供的解决方案(我在这个问题中描述了错误)。

PPS整个代码的要点

标签: javascripttensorflowtensorflow.js

解决方案


因此,您实际上是在尝试访问该值normalisedTensor,但您访问的是从函数返回的整个对象normalise。要获得normalisedTensor唯一的,您可以像这样从返回的对象中解构值const { normalisedTensor: normalisedFeature } = normalise(featureTensor);,我还将它重命名为normalisedFeature. 这应该修复日志记录和使用tf.split()normalisedFeaturenormalisedLabel.

在映射时,points我还曾经points && points.map()确保仅在值是真实值时才映射它们。

async function normalise(tensor, previousMin = null, previousMax = null) {
  const min = previousMin || tensor.min()
  const max = previousMax || tensor.max()
  const normalisedTensor = tensor.sub(min).div(max.sub(min))
  normalisedTensor.print(true)
  return {
    normalisedTensor,
    min,
    max
  }
}

async function run() {
  // "&&" is used to map over the points if it is a truthy value only
  const featureValues = points && points.map((p) => p.x);
  const featureTensor = tf.tensor2d(featureValues, [featureValues.length, 1]);

  const labelValues = points && points.map((p) => p.y);
  const labelTensor = tf.tensor2d(labelValues, [labelValues.length, 1]);

  // Rename the returned value of normalisedTensor
  const { normalisedTensor: normalisedFeature } = normalise(featureTensor);
  const { normalisedTensor: normalisedLabel } = normalise(labelTensor);

  console.log("Normalised feature:\n", normalisedFeature);

  featureTensor.dispose();
  labelTensor.dispose();

  [(trainingFeatureTensor, testingFeatureTensor)] = tf.split(
    x = normalisedFeature,
    numOrSizeSplits = 2,
    axis = 0
  )
  [(trainingLabelTensor, testingLabelTensor)] = tf.split(
    x = normalisedLabel,
    numOrSizeSplits = 2,
    axis = 0
  );

  document.getElementById("model-status").innerHTML = "No model trained";
  document.getElementById("train-button").removeAttribute("disabled");
  document.getElementById("load-button").removeAttribute("disabled");
}

推荐阅读