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)>
Related
I have a 2d dataframe:
C1. C2. C3
0. 2. 3. 6
1. 8. 2. 1
2. 8. 6. 2
3. 4. 9. 0
4. 6. 7. 1
5. 2. 3. 0
I want it to be a 3d data with <num_windows, window_size, num_features>
So if window size is 5, the shape of the 3d data will be <2,5,3> and will be:
[[2,3,4],[8,2,1],[8,6,2],[4,9,0],[6,7,1]] , [[8,2,1],[8,6,2],[4,9,0],[6,7,1],[2,3,0]]
What is the best way to do it?
You can use sliding_window_view:
num_windows = 2
window_size = 5
num_features = 3
np.lib.stride_tricks.sliding_window_view(df, (window_size, num_features))[:num_windows,0,:,:]
gives a 3D array of shape (num_windows, window_size, num_features):
array([[[2., 3., 6.],
[8., 2., 1.],
[8., 6., 2.],
[4., 9., 0.],
[6., 7., 1.]],
[[8., 2., 1.],
[8., 6., 2.],
[4., 9., 0.],
[6., 7., 1.],
[2., 3., 0.]]])
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.
I want to convert a 1-D tensor to 2-D shape in Tensorflow 2, with the number of elements in each row is given. I found a solution using the RaggedTensor like this
numbers = tf.constant([1,3,2,5,4])
c0 = tf.ones(shape=(15,)) # the tensor need to be reshape
rc0 = tf.RaggedTensor.from_row_lengths(values=c0, row_lengths=numbers)
c1 = rc0.to_tensor()
The final value of c1 should be
<tf.Tensor: shape=(5, 5), dtype=float32, numpy=
array([[1., 0., 0., 0., 0.],
[1., 1., 1., 0., 0.],
[1., 1., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 0.]], dtype=float32)>
I found it refused to work when the size of the input tensor is large, and the performance is not good enough.
Is there any other high performance solution?
Given tensor data
[[[ 0., 0.],
[ 1., 1.],
[-1., -1.]],
[[-1., -1.],
[ 4., 4.],
[ 5., 5.]]]
I want to remove [-1,-1] and get
[[[ 0., 0.],
[ 1., 1.]],
[[ 4., 4.],
[ 5., 5.]]]
How to get the above without using ragged feature in tensorflow?
You can try this:
x = tf.constant(
[[[ 0., 0.],
[ 1., 1.],
[-1., -2.]],
[[-1., -2.],
[ 4., 4.],
[ 5., 5.]]])
mask = tf.math.not_equal(x, np.array([-1, -1]))
result = tf.boolean_mask(x, mask)
shape = tf.shape(x)
result = tf.reshape(result, (shape[0], -1, shape[2]))
You could do it like this:
import tensorflow as tf
import numpy as np
data = [[[ 0., 0.],
[ 1., 1.],
[-1., -1.]],
[[-1., -1.],
[ 4., 4.],
[ 5., 5.]]]
data = tf.constant(data)
indices = tf.math.not_equal(data, tf.constant([-1., -1.]))
res = data[indices]
shape = tf.shape(data)
total = tf.reduce_sum(
tf.cast(tf.math.logical_and(indices[:, :, 0], indices[:, :, 1])[0], tf.int32))
res = tf.reshape(res, (shape[0], total, shape[-1]))
with tf.Session() as sess:
print(sess.run(res))
# [[[0. 0.]
# [1. 1.]]
# [[4. 4.]
# [5. 5.]]]
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])