I have a 2d tensor and I would like to get the value of the element of index i,j value.
问题:
回答1:
There are many ways one can retrieve the value of the element [i,j] of a tensor2d
Consider the following:
Using slice to retrieve directly the tensor2d starting at the coordinate [i, j] that has the size [1, 1]
h.slice([i, j], 1).as1D().print()
Get the row i as a tensor2d with gather and then the element j with slice
h.gather(tf.tensor1d([i], 'int32')).slice([0, j], [1, 1]).as1D().print()
Using stack to retrieve the row i as tensor1d and slice to retrieve the desired element
h.unstack()[i].slice([j], [1]).print()
const h = tf.tensor2d([45, 48, 45, 54, 5, 7, 8, 10, 54], [3, 3]);
// get the element of index [1, 2]
h.print()
h.gather(tf.tensor1d([1], 'int32')).slice([0, 2], [1, 1]).as1D().print()
h.slice([1, 2], 1).as1D().print()
h.unstack()[1].slice([2], [1]).print()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"> </script>
</head>
<body>
</body>
</html>
If the goal is to get the element [i, j] in order to use it in other tensor computation like divide/multiply the matrix by the element, you will need to convert the element to a scalar.
h.slice([i, j], 1).as1D().asScalar()
If you want to return that value to a javascript variable (of type number), then you will need dataSync() or data() as described in this answer
h.slice([i, j], 1).as1D().dataSync()[0]
// or
const data = await h.slice([i, j], 1).as1D().data()
const h = tf.tensor2d([45, 48, 45, 54, 5, 7, 8, 10, 54], [3, 3]);
// get the element of index [1, 2]
h.print()
// sync method
const val = h.unstack()[1].slice([2], [1]).dataSync()
console.log(val[0]);
// async method
(async () => {
const val = await h.slice([1, 2], 1).as1D().data()
console.log(val[0])
})()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.12.4/tf.js"> </script>
</head>
<body>
</body>
</html>
回答2:
You can use .dataSync()
or if you can wait for it .data()
to retrieve an 1d array containing all values of a tensor.
Now we only have to calculate an 1d-index from the 2d-coordinates using the formula:
index = rowlength * rownumber + columnnumber
The following code shows how to use each version.
Notice the async
and await
in the asynchronous method: async
makes the function async, so we can use await
to wait for another promise to resolve (.data()
retuns a promise). Because an async function returns a promise we have to wait for it before logging it using .then()
function getValSync(t, i, j) {
const data = t.dataSync();
return data[t.shape[0] * j + i]; //Or *i+j, depending on what the dimension order is
}
async function getValAsync(t, i, j) {
const data = await t.data();
return data[t.shape[0] * j + i];
}
const t2d = tf.tensor2d([1, 2, 3, 4], [2, 2]);
t2d.print();
console.log("1,0:", getValSync(t2d, 1, 0));
console.log("1,1:", getValSync(t2d, 1, 1));
getValAsync(t2d, 0, 0).then(v => console.log("0,0:", v));
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0">
</script>