7

I used the outerProduct function in the TensorFlow.js framework on two 1D arrays (a,b), but I am finding it difficult to get the values of the resulting tensor in the regular javascript format.

Even after using .dataSync and Array.from(), I am still unable to get the expected output format. The resulting outer product between the two 1D arrays should give one 2D array, but I am getting 1D array instead.

const a = tf.tensor1d([1, 2]);
const b = tf.tensor1d([3, 4]);
const tensor = tf.outerProduct(b, a);
const values = tensor.dataSync();
const array1 = Array.from(values);

console.log(array1);

The expected result is array1 = [ [ 3, 6 ] , [ 4, 8 ] ], but I am getting array1 = [ 3, 6, 4, 8 ]

Isaac
  • 396
  • 3
  • 13

3 Answers3

7

Version < 15

The result of tf.data or tf.dataSync is always a flatten array. But one can use the shape of the tensor to get a multi-dimensional array using map and reduce.

const x = tf.tensor3d([1, 2 , 3, 4 , 5, 6, 7, 8], [2, 4, 1]);

x.print()

// flatten array
let arr = x.dataSync()

//convert to multiple dimensional array
shape = x.shape
shape.reverse().map(a => {
  arr = arr.reduce((b, c) => {
  latest = b[b.length - 1]
  latest.length < a ? latest.push(c) : b.push([c])
  return b
}, [[]])
console.log(arr)
})
<html>
  <head>
    <!-- Load TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.14.1"> </script>
  </head>

  <body>
  </body>
</html>

From version 0.15

One can use tensor.array() or tensor.arraySync()

edkeveked
  • 17,989
  • 10
  • 55
  • 93
2

As of tfjs version 0.15.1 you can use await tensor.array() to get the nested array.

Nikhil
  • 485
  • 1
  • 4
  • 16
0

you can take your values and do something like

const values = [3, 6, 4, 8];

let array1 = []

for (var i = 0; i < values.length; i += 2) {
  array1.push([values[i], values[i + 1]])
}

console.log(array1)
Aziz.G
  • 3,599
  • 2
  • 17
  • 35
  • thanks. I am trying to generalize your suggestion to n-element in a and m-element in b arrays, that will give a 2D array of n x m. I have figured out that the 2 increment is the number of columns, in this case it will be the number of elements in a; but would have to add array1(i+m-1) times, which will not make the code dynamic. Do you know how to make it more dynamic? For example consider this modification to the above code: const a = tf.tensor1d([1, 2, 3]); const b = tf.tensor1d([3, 4]); const tensor = tf.outerProduct(b, a). – Isaac Feb 07 '19 at 21:38
  • 1
    The for loop becomes: for (var i = 0; i < array1.length; i += 3) { res.push([array1[i], array1[i + 1], array1[i + 2]]) } – Isaac Feb 07 '19 at 21:39
  • you can just make a dynamic increment instead of 2 :) – Aziz.G Feb 07 '19 at 21:42
  • If I adjust the increment, I will still need to add more arguments to push manually =>([array1[i], array1[i + 1], array1[i + 2], array1[i+3]...,array1[i+m-2], array1[i+m-1]]). That's the issue. – Isaac Feb 07 '19 at 21:46