how to interpret shape of array in numpy - numpy

import numpy as np
a1 = np.array([1, 2, 3])
a1.shape # (3,)
a2 = np.array([[1, 2, 3]])
a2.shape # (1, 3)
b = np.array([[1, 2, 3], [2,3,4], [ 1,2,2]])
np.dot(a1,b) # array([ 8, 14, 17])
np.dot(a1,b) # array([[ 8, 14, 17]])
I have been thinking a1 as 'row vector' shaped as 1 by 3.
However shape is (3,).
Instead of this, the shape of a2 is (1,3) and it looks like more row vector.
Both (a1, a2) can be inner producted(np.dot()) and result in same figures. ( only except for shape )
Is there any difference to interpret these two?
Is it proper to interpret a1 as row vector ?

Related

How to create a Tensor with specific values?

I have a tensor with shape NxM.
I'd like to create another tensor with the same shape, filled with ones up until a certain column (might be different for each row) and the rest of it filled with another value (let's say 10 for the example).
How I do that?
Something like this can help you:
input = tf.Variable([[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]], dtype = tf.float32)
indices = tf.constant([1, 4, 2])
X = tf.ones_like(input)
Y = tf.constant(10, dtype = tf.float32, shape = input.shape)
result = tf.where(tf.sequence_mask(indices, tf.shape(input)[1]), X, Y)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(input))
print(sess.run(indices))
print(sess.run(result))

Getting all possible permutations along an axis with tf.gather_nd

I'm trying to extract all the possible permutations from a Tensor along a specific axis. My input is a [B, S, L] tensor (B batches of S vectors of length L) and I want to extract all the possible permutations among these vectors (the S! permutations) namely a [B, S!, S, L] Tensor as output.
That's what I tried for now but I'm struggling getting the right output shape. I think my mistake might be that I'm creating a batch_range, but I should create a permutation_range as well.
import tensorflow as tf
import numpy as np
from itertools import permutations
S = 3
B = 5
L = 10
input = tf.constant(np.random.randn(B, S, L))
perms = list(permutations(range(S))) # ex with 3: [0, 1, 2], [0, 2 ,1], [1, 0, 2], [1, 2, 0], [2, 1, 0], [2, 0, 1]
length_perm = len(perms)
perms = tf.reshape(tf.constant(perms), [1, length_perm, S, 1])
perms = tf.tile(perms, [B, 1, 1, 1])
batch_range = tf.tile(tf.reshape(tf.range(B, dtype=tf.int32), shape=[B, 1, 1, 1]), [1, length_perm, S, 1])
indicies = tf.concat([batch_range, perms], axis=3)
permutations = tf.gather_nd(tf.tile(tf.reshape(input, [B, 1, S, L]), [1, length_perm, 1, 1]), indicies) #
# I get a [ B, P, S, S, L] instead of the desired [B, P, S, L]
I posted one possible 'solution' just below, but I think there is still a problem with this one. I tested it, and if B>1 it's not going very well.
I just found an answer I think, please correct me if you think I'm wrong or if there is an easier way to do this:
import tensorflow as tf
import numpy as np
from itertools import permutations
S = 3
B = 5
L = 10
input = tf.constant(np.random.randn(B, S, L))
perms = list(permutations(range(S))) # ex with 3: [0, 1, 2], [0, 2 ,1], [1, 0, 2], [1, 2, 0], [2, 1, 0], [2, 0, 1]
length_perm = len(perms)
perms = tf.reshape(tf.constant(perms), [1, length_perm, S, 1])
perms = tf.tile(perms, [B, 1, 1, 1])
batch_range = tf.tile(tf.reshape(tf.range(B, dtype=tf.int32), shape=[B, 1, 1, 1]), [1, length_perm, S, 1])
perm_range = tf.tile(tf.reshape(tf.range(length_perm, dtype=tf.int32), shape=[1, length_perm, 1, 1]), [B, 1, S, 1])
indicies = tf.concat([batch_range, perm_range, perms], axis=3)
permutations = tf.gather_nd(tf.tile(tf.reshape(input, [B, 1, S, L]), [1, length_perm, 1, 1]), indicies) #
print permutations
I know this is late, but I came across the same problem and wanted to share my solution.
I also generate the permutation list. Then I build a permutation tensor from it.
Then I multiply it with the tensor. It doesn't use tf.gather_nd(), but a clean matrix multiplcation.
import tensorflow as tf
import numpy as np
from itertools import permutations
B = 5 # batch size
S = 3 # here permutations
L = 10 # length of the S vecors
data = tf.constant(np.random.randn(B, S, L))
perms = list(permutations(range(S))) # ex with 3: [0, 1, 2], [0, 2 ,1], [1, 0, 2],[1, 2, 0], [2, 1, 0], [2, 0, 1]
N= len(perms)
# from here new code:
eye = tf.eye(S,dtype=tf.int32) # creates eye matrix of [S x S]
# now we cast the eye matrix and permutation matrix, so that they give a [N,S,S] matrix, which are basically N eye matrcices with the permutation indices on the diagonal
perm_mat = tf.constant(np.eye(S)[np.array(perms)],dtype= tf.float64)
# this can be now multiplied to the tensor and gives the permutated output. We just need to broadcast the permutation dimension here
res = tf.linalg.matmul(perm_mat, data[:,tf.newaxis,...])
print(res)

reshape tensor between two layers

I have a neural network in which I built my own layer and it gives result with the shape A = [10, 5].
I want to feed the result to another layer which takes input with shape B = [10, 9, 5].
The input B is based on the previous result A, for example, selecting 9 different rows from A for 10 times,making a new tensor with the shape [10, 9, 5].
Is there a way to do that?
for loop will do:
a = tf.constant([[1, 2, 7], [3, 4, 8], [5, 6, 9]])
tensor_list = []
pick_times = 3
for i in range(pick_times):
pick_rows = [j for j in range(pick_times) if i != j]
tensor_list.append(tf.gather(a, pick_rows))
concated_tensor = tf.concat(tensor_list, 0)
result = tf.reshape(concated_tensor, [3, 2, 3])
Convert the tensor A (output of the layer) into a numpy array with:
a=sess.run(A.eval())
For the sake of the example I'll use:
a=np.random.uniform(0,5,[10])
Then:
#choose wich element will be left out
out = np.random.randint(5, size=[10])
#array of different output layers without one random element
b=[]
for i in range(10):
b.append(np.delete(a,out[i]))
#Stack them all together
B = tf.stack(b[:])

Tensorflow: index per row

Suppose I have a Tensor of shape (100,20). Now I also have a Tensor of indices of shape (100,). How to obtain now a Tensor of shape (100,) or (100,1) with per row (100 rows) the right value (selected by the corresponding index in indices?
Small example:
So let's say tensor A is
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
and tensor B is
[0,2,1]
then I want as output
[1,6,8]
You can join your B tensor with an appropriate range to create two-dimensional indices (in your example [[0, 0], [1, 2], [2, 1]]) and then extract the elements using tf.gather_nd:
b_2 = tf.expand_dims(b, 1)
range = tf.expand_dims(tf.range(tf.shape(b)[0]), 1)
ind = tf.concat(1, [range, b_2])
res = tf.gather_nd(a, ind)

How to flatten along 3rd dimension in numpy?

I have a 3d array in numpy that I want to flatten into a 1d array. I want to flatten each 2d "layer" of the array, copying each successive layer into the 1d array.
e.g., for an array with arr[:, :, 0] = [[1, 2], [3, 4]] and arr[:, :, 1] = [[5, 6], [7, 8]], I want the output to be [1, 2, 3, 4, 5, 6, 7, 8].
Currently I have the following code:
out = np.empty(arr.size)
for c in xrange(arr.shape[2]):
layer = arr[:, :, c]
out[c * layer.size:(c + 1) * layer.size] = layer.ravel()
Is there a way to accomplish this efficiently in numpy (without using a for loop)? I have tried messing around with reshape, transpose, and flatten to no avail.
I figured it out:
out = arr.transpose((2, 0, 1)).flatten()
Or (the last axe will be first) : np.rollaxis(a,-1).ravel()