张量和操作

TensorFlow.js 是一个框架,用于使用 JavaScript 中的张量定义和运行计算。张量是向量和矩阵到更高维度的推广。

张量

TensorFlow.js 中的数据中心单元是 tf.Tensor:一组值,形状为一个或多个维度的数组。 tf.Tensor 与多维数组非常相似。

一个 tf.Tensor 还包含以下属性

  • rank:定义张量包含的维度数
  • shape:定义数据的每个维度的尺寸
  • dtype:定义张量的类型。

一个 tf.Tensor 可以使用 tf.tensor() 方法从数组创建

// Create a rank-2 tensor (matrix) matrix tensor from a multidimensional array.
const a = tf.tensor([[1, 2], [3, 4]]);
console.log('shape:', a.shape);
a.print();

// Or you can create a tensor from a flat array and specify a shape.
const shape = [2, 2];
const b = tf.tensor([1, 2, 3, 4], shape);
console.log('shape:', b.shape);
b.print();

默认情况下, tf.Tensor 将具有 float32 dtype. tf.Tensor 也可以使用 bool、int32、complex64 和 string 类型创建

const a = tf.tensor([[1, 2], [3, 4]], [2, 2], 'int32');
console.log('shape:', a.shape);
console.log('dtype', a.dtype);
a.print();

TensorFlow.js 还提供了一组方便的方法来创建随机张量、填充特定值的张量、从 HTMLImageElement 创建张量,以及更多您可以在 此处 找到的方法。

更改张量的形状

tf.Tensor 中的元素数量是其形状中尺寸的乘积。由于通常可以有多种具有相同尺寸的形状,因此能够将 tf.Tensor 重塑为具有相同尺寸的另一种形状通常很有用。这可以通过 reshape() 方法实现

const a = tf.tensor([[1, 2], [3, 4]]);
console.log('a shape:', a.shape);
a.print();

const b = a.reshape([4, 1]);
console.log('b shape:', b.shape);
b.print();

从张量获取值

您还可以使用 Tensor.array()Tensor.data() 方法从 tf.Tensor 获取值

 const a = tf.tensor([[1, 2], [3, 4]]);
 // Returns the multi dimensional array of values.
 a.array().then(array => console.log(array));
 // Returns the flattened data that backs the tensor.
 a.data().then(data => console.log(data));

我们还提供了这些方法的同步版本,它们更易于使用,但在您的应用程序中会导致性能问题。在生产应用程序中,您应该始终优先使用异步方法。

const a = tf.tensor([[1, 2], [3, 4]]);
// Returns the multi dimensional array of values.
console.log(a.arraySync());
// Returns the flattened data that backs the tensor.
console.log(a.dataSync());

操作

虽然张量允许您存储数据,但操作(op)允许您操作该数据。TensorFlow.js 还提供各种适合线性代数和机器学习的操作,这些操作可以在张量上执行。

示例:计算 tf.Tensor 中所有元素的 x2

const x = tf.tensor([1, 2, 3, 4]);
const y = x.square();  // equivalent to tf.square(x)
y.print();

示例:逐元素添加两个 tf.Tensor 的元素

const a = tf.tensor([1, 2, 3, 4]);
const b = tf.tensor([10, 20, 30, 40]);
const y = a.add(b);  // equivalent to tf.add(a, b)
y.print();

由于张量是不可变的,因此这些操作不会更改它们的值。相反,操作始终返回新的 tf.Tensor

您可以在 此处 找到 TensorFlow.js 支持的操作列表。

内存

在使用 WebGL 后端时,必须显式管理 tf.Tensor 内存(让 tf.Tensor 超出范围以释放其内存 **是不够的**)。

要销毁 tf.Tensor 的内存,可以使用 dispose() 方法或 tf.dispose()

const a = tf.tensor([[1, 2], [3, 4]]);
a.dispose(); // Equivalent to tf.dispose(a)

在应用程序中将多个操作链接在一起非常常见。持有对所有中间变量的引用以处置它们会降低代码可读性。为了解决这个问题,TensorFlow.js 提供了一个 tf.tidy() 方法,该方法会在执行函数后清理所有未由函数返回的 tf.Tensor,类似于在执行函数时清理局部变量的方式

const a = tf.tensor([[1, 2], [3, 4]]);
const y = tf.tidy(() => {
  const result = a.square().log().neg();
  return result;
});

在此示例中,square()log() 的结果将自动处置。 neg() 的结果不会被处置,因为它 是 tf.tidy() 的返回值。

您还可以获取 TensorFlow.js 跟踪的张量数量

console.log(tf.memory());

tf.memory() 打印的对象将包含有关当前分配了多少内存的信息。您可以在 此处 找到更多信息。