1
votes

I want to manipulate a subtensor (like a column or a row) of a tensor using another tensor as index. So I am given three tensors:

tensor = tf.constant([[1,2,3], [4,5,6]])
r = tf.constant(0)
new_row = tf.constant([-3,-2,-1])

and I need some function or something that applied to those three tensors, gives me

new_tensor = tf.constant([[-3,-2,-1],[4,5,6]])

So I want to replace the r-th row of the tensor 'tensor' by 'new_row'. Is that even possible?

UPDATE:

Ok, so I found the following solution that works for replacing columns in a matrix dynamically, that is, neither do we know the dimensions of the matrix nor the index of the column to be replaced nor the actual replacement column during graph construction time.

import tensorflow as tf


# matrix: 2D-tensor of shape (m,n)
# new_column: 1D-tensor of shape m
# r: 0D-tensor with value from { 0,...,n-1 }
# Outputs 2D-tensor of shape (m,n) with the same values as matrix, except that the r-th column has been replaced by new_column
def replace_column(matrix, new_column, r):
    num_rows,num_cols = tf.unstack(tf.shape(matrix))
    index_row = tf.stack( [ tf.eye(num_cols,dtype=tf.float64)[r,:] ] )
    old_column = matrix[:,r]
    new = tf.matmul( tf.stack([new_column],axis=1), index_row )
    old = tf.matmul( tf.stack([old_column],axis=1), index_row )
    return (matrix-old)+new


matrix = [[1,2,3],[4,5,6],[7,8,9]]
column = [-1,-2,-3]
pos = 1

dynamic = tf.placeholder(tf.float64, shape=[None,None])
pos_tensor = tf.placeholder(tf.int32,shape=[])
column_tensor = tf.placeholder(dtype=tf.float64,shape=[None])

result_dynamic = replace_column(dynamic, column_tensor, pos_tensor)

with tf.Session() as sess:
    print "Input matrix, column, position: ", matrix, column, pos
    print "Dynamic result: ", sess.run([result_dynamic], { dynamic: matrix, pos_tensor: pos, column_tensor: column })

It uses the outer product operation to do this job, which is also the reason I haven't been able to generalize this to general tensors (and also because I only need it for matrices ;-) ).

1
It would be more helpful if you could post an example of using replace_column on tensors of both static and dynamic shapes.Maosi Chen
done :-)) I did only for dynamic shapes because if it works for them it obviously also works for static shapes!D. Rusin

1 Answers

0
votes
import tensorflow as tf

sess = tf.InteractiveSession()

tensor = tf.constant([[1,2,3], [4,5,6]])
r = tf.constant(0)
new_row = tf.constant([-3,-2,-1])

shp1 = tensor.get_shape()

unpacked_tensor = tf.unstack(tensor, axis=0)
new_tensor_list = []
for iiR in list(range(shp1[0])):
    new_tensor_list.append(tf.where(tf.equal(r, iiR), new_row, unpacked_tensor[iiR]))

new_tensor = tf.stack(new_tensor_list, axis = 0)

print(new_tensor.eval())

Outputs:

[[-3 -2 -1]
 [ 4  5  6]]