My current tensor has shape of (3, 2), e.g.,
[[ 1. 2.]
[ 2. 1.]
[-2. -1.]]
I would like to expand to a shape of (1, 3, 2) with each second dimension a replica of the entire tensor, e.g.,
[[[ 1. 2.]
[ 2. 1.]
[ -2. -1.]]
[[ 1. 2.]
[ 2. 1.]
[ -2. -1.]]
[[ 1. 2.]
[ 2. 1.]
[ -2. -1.]]]
I tried the folllowing code but it only replicate each row instead.
tiled_vecs = tf.tile(tf.expand_dims(input_vecs, 1), [1, 3, 1])
Results in
[[[ 1. 2.]
[ 1. 2.]
[ 1. 2.]]
[[ 2. 1.]
[ 2. 1.]
[ 2. 1.]]
[[-2. -1.]
[-2. -1.]
[-2. -1.]]]
This should work,
tf.ones([tf.shape(A)[0], 1, 1]) * A
# Achieved by creating a 3d matrix as shown below
# and multiplying it with A, which is `broadcast` to obtain the desired result.
[[[1.]],
[[1.]], * A
[[1.]]]
Code Sample:
#input
A = tf.constant([[ 1., 2.], [ 2. , 1.],[-2., -1.]])
B = tf.ones([tf.shape(A)[0], 1, 1]) * A
#output
array([[[ 1., 2.],
[ 2., 1.],
[-2., -1.]],
[[ 1., 2.],
[ 2., 1.],
[-2., -1.]],
[[ 1., 2.],
[ 2., 1.],
[-2., -1.]]], dtype=float32)
Also using tf.tile, we can obtain the same:
tf.tile(tf.expand_dims(A,0), [tf.shape(A)[0], 1, 1])
Related
Similar to this question, I want to convert this tensor
tensor = tf.ones((5, 5))
tf.Tensor(
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]], shape=(5, 5), dtype=float32)
to an upper triangular tensor with ones and zeros everywhere else:
tf.Tensor(
[[1. 1. 1. 1. 1.]
[0. 1. 1. 1. 1.]
[0. 0. 1. 1. 1.]
[0. 0. 0. 1. 1.]
[0. 0. 0. 0. 1.]], shape=(5, 5), dtype=float32)
any ideas?
You can use tf.linalg.band_part:
>>> tensor = tf.ones((5, 5))
>>> tf.linalg.band_part(tensor, 0, -1)
<tf.Tensor: shape=(5, 5), dtype=float32, numpy=
array([[1., 1., 1., 1., 1.],
[0., 1., 1., 1., 1.],
[0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1.],
[0., 0., 0., 0., 1.]], dtype=float32)>
Note that you can use that function to extract an arbitrary number of diagonals from the tensor. Useful cases include:
tf.linalg.band_part(input, 0, -1) ==> Upper triangular part.
tf.linalg.band_part(input, -1, 0) ==> Lower triangular part.
tf.linalg.band_part(input, 0, 0) ==> Diagonal.
A simple example of the following use of tf.tensor_scatter_nd_add is giving me problems.
B = tf.tensor_scatter_nd_add(A, indices, updates)
tensor A is (1,4,4)
A = [[[1. 1. 1. 1.],
[1. 1. 1. 1.],
[1. 1. 1. 1.],
[1. 1. 1. 1.]]]
the desired result is tensor B:
B = [[[1. 1. 1. 1.],
[1. 2. 3. 1.],
[1. 4. 5. 1.],
[1. 1. 1. 1.]]]
i.e. I want to add this smaller tensor to just the 4 inner elements of tensor A
updates = [[[1, 2],
[3, 4]]]
Tensorflow 2.1.0. I've tried a number of ways of constructing indices. The call to tensor_scatter_nd_add returns an error saying the inner dimensions don't match.
Do the updates tensor need to be the same shape as A?
Planaria,
Try passing indices and updates the following way: updates with shape (n), indices with shape (n,3) where n is number of changed items.
Indices should point to individual cells that you want to change:
A = tf.ones((1,4,4,), dtype=tf.dtypes.float32)
updates = tf.constant([1., 2., 3., 4])
indices = tf.constant([[0,1,1], [0,1,2], [0,2,1], [0,2,2]])
tf.tensor_scatter_nd_add(A, indices, updates)
<tf.Tensor: shape=(1, 4, 4), dtype=float32, numpy=
array([[[1., 1., 1., 1.],
[1., 2., 3., 1.],
[1., 4., 5., 1.],
[1., 1., 1., 1.]]], dtype=float32)>
I have a numpy question
I have a 2D array of values
vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32)
And a 2D array of scale factors
factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]])
I want to multiply every row in vals with every row in factors to end up with a "scaled_vals" array like the one below
NOTE : This output has been corrected form my original post - my apologies for this goof up
[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]
I'm showing factors with just two columns of data but in actuality it is 'n'.
Any help will be gratefully received.
Doug
===
copied from the comment:
for step in range(2):
scaled_vals = np.multiply(vals, factors[0:,step:step+1])
Playing with broadcasting:
vals[:, None, None, :] * factors.T[None, :, :, None]
Output:
array([[[[ 1., 2., 3.],
[ 2., 4., 6.],
[ 3., 6., 9.]],
[[ 4., 8., 12.],
[ 5., 10., 15.],
[ 6., 12., 18.]]],
[[[ 4., 5., 6.],
[ 8., 10., 12.],
[12., 15., 18.]],
[[16., 20., 24.],
[20., 25., 30.],
[24., 30., 36.]]],
[[[ 7., 8., 9.],
[14., 16., 18.],
[21., 24., 27.]],
[[28., 32., 36.],
[35., 40., 45.],
[42., 48., 54.]]]])
The (2,3,3) block that you show can be produced with:
In [267]: vals[0,:]*factors.T[:,:,None]
Out[267]:
array([[[ 1., 2., 3.],
[ 2., 4., 6.],
[ 3., 6., 9.]],
[[ 4., 8., 12.],
[ 5., 10., 15.],
[ 6., 12., 18.]]])
but the comment loop is;
In [268]: for step in range(2):
...: print(np.multiply(vals, factors[0:,step:step+1]))
...:
[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]
In [269]: vals*factors.T[:,:,None]
Out[269]:
array([[[ 1., 2., 3.],
[ 8., 10., 12.],
[21., 24., 27.]],
[[ 4., 8., 12.],
[20., 25., 30.],
[42., 48., 54.]]])
You can use einsum one liner (without loop) to multiply your indices in any shape you desire:
output = np.einsum('ij,kl->ilkj',vals,factors)
this multiplies [i,j] from vals into [k,l] from factors and put it at [i,l,k,j] in output. Note #Quan Hoang's answer (upvoted) does the same without looping. However, this is somewhat more readable I think and you can extend it to any other combination you desire.
output:
[[[[ 1. 2. 3.]
[ 2. 4. 6.]
[ 3. 6. 9.]]
[[ 4. 8. 12.]
[ 5. 10. 15.]
[ 6. 12. 18.]]]
[[[ 4. 5. 6.]
[ 8. 10. 12.]
[12. 15. 18.]]
[[16. 20. 24.]
[20. 25. 30.]
[24. 30. 36.]]]
[[[ 7. 8. 9.]
[14. 16. 18.]
[21. 24. 27.]]
[[28. 32. 36.]
[35. 40. 45.]
[42. 48. 54.]]]]
UPDATE: Per new multiplication mentioned in comments, solution would be:
output = np.einsum('ij,ik->kij',vals,factors)
this multiplies [i,j] from vals into [i,k] from factors and put it at [k,i,j] in output.
output:
[[[ 1. 2. 3.]
[ 8. 10. 12.]
[21. 24. 27.]]
[[ 4. 8. 12.]
[20. 25. 30.]
[42. 48. 54.]]]
The only I can make sense of the inputs and outputs is if you multiply each row of vals with the corresponding index of all factors but you need to match the dimensions of factors and vals.
import numpy as np
vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32) # shape = mxn
print(vals.shape)
factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]) # shape = nxk increasing dim to match with vals.shape
m = vals.shape[0]
n = vals.shape[1]
k = factors.shape[1]
print(factors.shape)
result = np.array([np.array([vals[j]*np.repeat(factors[:,i], n).reshape(n,n) for i in range(k)]) for j in range(m)])
print(result[0])
(3, 3)
(3, 2)
[[[ 1. 2. 3.]
[ 2. 4. 6.]
[ 3. 6. 9.]]
[[ 4. 8. 12.]
[ 5. 10. 15.]
[ 6. 12. 18.]]]
Can someone explain to me why does this example have a shape of [2,1,3], i just don't see it?
[[[1., 2., 3.]], [[7., 8., 9.]]] # a rank 3 tensor with shape [2, 1, 3]
Indentation does wonders:
[ # this one contains 2 items
[ # each of this contains 1 item
[1., 2., 3.] # each of this contains 3 items
],
[
[7., 8., 9.]
]
]
Thus, shape is [2,1,3]
I got some sparse matrix like this
>>>import numpy as np
>>>from scipy.sparse import *
>>>A = csr_matrix((np.identity(3)))
>>>print A
(0, 0) 1.0
(1, 1) 1.0
(2, 2) 1.0
For better understanding A is something like this:
>>>print A.todense()
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
And I would like to have an operator (let us call it op1(n) ) doing this:
>>>A.op1(1)
[[ 0. 1. 0.]
[ 0. 0. 1.]
[ 1. 0. 0.]]
=> makes the last n columns the first n ones,
so
>>>A == A.op1(3)
true
. Is there some build-in solution, (EDIT:) that returns a sparse matrix again?
The solution with roll:
X = np.roll(X.todense(),-tau, axis = 0)
print X.__class__
returns
<class 'numpy.matrixlib.defmatrix.matrix'>
scipy.sparse doesn't have roll, but you can simulate it with hstack:
from scipy.sparse import *
A = eye(3, 3, format='csr')
hstack((A[:, 1:], A[:, :1]), format='csr') # roll left
hstack((A[:, -1:], A[:, :-1]), format='csr') # roll right
>>> a = np.identity(3)
>>> a
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> np.roll(a, -1, axis=0)
array([[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.]])
>>> a == np.roll(a, 3, axis=0)
array([[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)