如何使用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。
答案 0 :(得分:1)
这不是广播问题。 b
是普通的JavaScript数组。在这种情况下,它是张量数组。
要在dot
或matMul
操作中使用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>