如何在tensorflow.js中广播矩阵/矢量点积

时间:2018-10-01 12:21:08

标签: javascript tensorflow broadcast tensorflow.js

如何使用Javascript在Tensorflow中广播矩阵A与多个向量的乘法? 让我们定义一个:

A = tf.tensor2d([1, 0, 0, 2], [2, 2])
A.print()
Tensor
    [[1, 0],
     [0, 2]]

让我们将b个向量定义为列向量(矩阵):

b = Array.apply({}, new Array(10)).map(_ => tf.tensor2d([[Math.floor(Math.random() * 100)], [Math.floor(Math.random() * 100)]]));
b[0].print()
Tensor
    [[90 ],
     [122]]

尝试.matMul

A.matMul(b)
tfjs@latest:2 Uncaught Error: Error in matMul: inputs must have the same rank of at least 2, got ranks 2 and 1.

.dot

A.dot(b)
tfjs@latest:2 Uncaught Error: Error in dot: inner dimensions of inputs must match, but got 2 and 10

还尝试使用b作为常规1d张量:

b = Array.apply({}, new Array(10)).map(_ => tf.tensor1d([Math.floor(Math.random() * 100), Math.floor(Math.random() * 100)]));

结果相同。此外,从文档上看,这些操作似乎不可广播。我不明白为什么不能像numpy那样播放它们。

我对python的同一问题看到了一些答案,建议使用einsum。但这似乎仅适用于python,而不适用于javascript。

1 个答案:

答案 0 :(得分:1)

这不是广播问题。 b是普通的JavaScript数组。在这种情况下,它是张量数组。 要在dotmatMul操作中使用b,b必须是张量。这里情况不同。 对于matMul运算,给定两个张量x (shape [p,q])y (shape [r, s]),q应等于r。这就是矩阵乘法的定义,即在tensorflow.js或tensorflow.py中都没有针对matMul的广播。点操作非常相似。唯一的区别是,一个操作数可以是矩阵,第二个可以是向量。

请考虑以下内容:为简单起见,括号中的是该形状的张量。

[4, 5].matMul([5, 6]) = [4, 5].dot([5, 4]) => [4, 6]
[4, 5].matMul([4, 5]) => error 

因为4和5(即为什么做矩阵的平方有时被定义为矩阵与其转置之间的乘积。对于给定的矩阵A,除非A是平方,否则不能总是计算A * A矩阵)

[5].dot([5, 4]) => [4]
[5, 4].dot([4]) => [5, 1]
[5].dot([4, 5]) => error
[5, 4].dot([5]) => error

要计算b和a的乘积,您将需要遍历b并执行matMul操作。

a = tf.tensor2d([1, 0, 0, 2], [2, 2])

// there is much simpler way to create an array of 10 tensors without apply function
const b = Array.from({length:10}, _ => tf.tensor2d([[Math.floor(Math.random() * 100)], [Math.floor(Math.random() * 100)]]))
// Matmul operation
const prod = b.map(t => a.matMul(t))
prod.forEach(t => t.print())
<html>
  <head>
    <!-- Load TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"> </script>
  </head>

  <body>
  </body>
</html>