pytorch tensor stride - how it works - numpy

PyTorch doesn't seem to have documentation for tensor.stride().
Can someone confirm my understanding?
My questions are three-fold.
Stride is for accessing an element in the storage. So stride size will be the same as the dimension of the tensor. Correct?
For each dimension, the corresponding element of stride tells how much it takes to move along the 1-dimensional storage. Correct?
For example:
In [15]: x = torch.arange(1,25)
In [16]: x
Out[16]:
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
, 19, 20, 21, 22, 23, 24])
In [17]: a = x.view(4,3,2)
In [18]: a
Out[18]:
tensor([[[ 1, 2],
[ 3, 4],
[ 5, 6]],
[[ 7, 8],
[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16],
[17, 18]],
[[19, 20],
[21, 22],
[23, 24]]])
In [20]: a.stride()
Out[20]: (6, 2, 1)
How does having this information help perform tensor operations efficiently? Basically this is showing the memory layout. So how does it help?

Related

Convert 2D numpy array into 3D numpy array with 3rd dimension

I have a numpy array of 2D shape
a=np.array([[1,2,3,4,5,6],
[7,8,9,10,11,12],
[13,14,15,16,17,18]])
and trying to convert into 3D shape of dimension (3,3,2) i.e,
np.array([[ 1,2,3],
[7,8,9],
[13,14,15]])
in 3rd dimension with index 1 and
np.array([[4,5,6],
[10,11,12],
[16,17,18]])
in 3rd dimension with index 2.
I tried to reshape as a.reshape(3,3,2) and getting this
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18]]])
Any suggestions to convert this?
Use swapaxes:
a.reshape(3,2,3).swapaxes(0,1)
output:
array([[[ 1, 2, 3],
[ 7, 8, 9],
[13, 14, 15]],
[[ 4, 5, 6],
[10, 11, 12],
[16, 17, 18]]])

Fastest way to do vectorized reduce product with boolean mask

I have a 3D numpy array A and 2D numpy boolean mask B.
The first two dimensions of A matches B
And I'm wondering if there is any fast way for each first dimension of A, select the third dimension along second based on B, perform a reduced product over the second dimension.
My expected out C would be a 2D numpy array, with the first dimension of A and the second dimension from the third of A.
My current solution is C = np.prod(A*np.repeat(B[...,np.newaxis], A.shape[-1], 2), 1)
Is there any better alternative?
With concrete example:
In [364]: A=np.arange(1,25).reshape(2,3,4); B=np.arange(1,7).reshape(2,3)
In [365]: C = np.prod(A*np.repeat(B[...,np.newaxis], A.shape[-1], 2), 1)
That repeat does:
In [366]: np.repeat(B[...,np.newaxis], A.shape[-1], 2)
Out[366]:
array([[[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]],
[[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6]]])
In [367]: _.shape
Out[367]: (2, 3, 4)
In [368]: A*np.repeat(B[...,np.newaxis], A.shape[-1], 2)
Out[368]:
array([[[ 1, 2, 3, 4],
[ 10, 12, 14, 16],
[ 27, 30, 33, 36]],
[[ 52, 56, 60, 64],
[ 85, 90, 95, 100],
[126, 132, 138, 144]]])
But by broadcasting rules, the repeat is no needed:
In [369]: A*B[...,np.newaxis]
Out[369]:
array([[[ 1, 2, 3, 4],
[ 10, 12, 14, 16],
[ 27, 30, 33, 36]],
[[ 52, 56, 60, 64],
[ 85, 90, 95, 100],
[126, 132, 138, 144]]])
In [371]: np.prod(_369, axis=1)
Out[371]:
array([[ 270, 720, 1386, 2304],
[556920, 665280, 786600, 921600]])
You could apply prod to A and B individually, but I don't know if that makes much of a difference:
In [373]: np.prod(A,1)*np.prod(B,1)[:,None]
Out[373]:
array([[ 270, 720, 1386, 2304],
[556920, 665280, 786600, 921600]])

Combination of slicing and array index in numpy

Looking at the answers to this question: How to understand numpy's combined slicing and indexing example
I'm still unable to understand the result of indexing with a combination of a slice and two 1d arrays, like this:
>>> m = np.arange(36).reshape(3,3,4)
>>> m
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]],
[[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35]]])
>>> m[1:3, [2,1],[2,1]]
array([[22, 17],
[34, 29]])
Why is the result equivalent to this?
np.array([
[m[1,2,2],m[1,1,1]],
[m[2,2,2],m[2,1,1]]
])

Convert 2d tensor to 3d in tensorflow

I need to convert 2d tensor to a 3d tensor. how can I transfer this in tensor flow.
[[30, 29, 19, 17, 12, 11],
[30, 27, 20, 16, 5, 1],
[28, 25, 17, 14, 7, 2],
[28, 26, 21, 14, 6, 4]]
to this
[[[0,30], [0,29], [0,19], [0,17], [0,12], [0,11]],
[[1,30], [1,27], [1,20], [1,16],[1,5], [1,1]],
[[2,28], [2,25], [2,17], [2,14], [2,7], [2,2]],
[[3,28], [3,26], [3,21], [3,14], [3,6], [3,4]]]
Thanks! I am doing this to implement asked in How to select rows from a 3-D Tensor in TensorFlow? #kom
Here's a workaround to achieve the 3D tensor from 2D tensor
a = tf.constant([[30, 29, 19, 17, 12, 11],
[30, 27, 20, 16, 5, 1],
[28, 25, 17, 14, 7, 2],
[28, 26, 21, 14, 6, 4]], dtype=tf.int32)
a = tf.expand_dims(a, axis=2)
b = tf.constant(np.asarray([i*np.ones(a.shape[1]) for i in range(0, a.shape[0])], dtype=np.int32), dtype=tf.int32)
b = tf.expand_dims(b, axis=2)
final_ids = tf.concat([b, a], axis=2)

numpy: Efficient way to use a 1D array as an index into 2D array

X.shape == (10,4)
y.shape == (10)
I'd like to produce M, where each entry in M is defined as M[r,c] == X[r, y[r]]; that is, use y to index into the appropriate column of X.
How can I do this efficiently (without loops)?
M could have a single column, though eventually I need to broadcast it so that it has the same shape as X. c starts from the first col of X (0) and goes to the last (9).
Just do :
X=np.arange(40).reshape(10,4)
Y=np.random.randint(0,4,10)
M=X[range(10),Y]
for
In [8]: X
Out[8]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35],
[36, 37, 38, 39]])
In [9]: Y
Out[9]: array([1, 1, 3, 3, 1, 2, 2, 3, 2, 1])
In [10]: M
Out[10]: array([ 1, 5, 11, 15, 17, 22, 26, 31, 34, 37])