how to do slice assignment while the slice itself

2019-07-30 18:16发布

问题:

I want to do slice assignment in tensorflow. I got to know that I can use:

my_var = my_var[4:8].assign(tf.zeros(4))

base on this link.

as you see in my_var[4:8] we have specific indices 4, 8 here for slicing and then assignment.

My case is different I want to do slicing based on a tensor and then do the assignment.

out = tf.Variable(tf.zeros(shape=[8,4], dtype=tf.float32))

 rows_tf = tf.constant (
[[1, 2, 5],
 [1, 2, 5],
 [1, 2, 5],
 [1, 4, 6],
 [1, 4, 6],
 [2, 3, 6],
 [2, 3, 6],
 [2, 4, 7]])

columns_tf = tf.constant(
[[1],
 [2],
 [3],
 [2],
 [3],
 [2],
 [3],
 [2]])

changed_tensor = [[8.3356,    0.,        8.457685 ],
                  [0.,        6.103182,  8.602337 ],
                  [8.8974,    7.330564,  0.       ],
                  [0.,        3.8914037, 5.826657 ],
                  [8.8974,    0.,        8.283971 ],
                  [6.103182,  3.0614321, 5.826657 ],
                  [7.330564,  0.,        8.283971 ],
                  [6.103182,  3.8914037, 0.       ]]

Also, this is the sparse_indices tensor, which is the concat of rows_tf and columns_tf making the whole indices that need to be updated(in case it can help:)

sparse_indices = tf.constant(
[[1 1]
 [2 1]
 [5 1]
 [1 2]
 [2 2]
 [5 2]
 [1 3]
 [2 3]
 [5 3]
 [1 2]
 [4 2]
 [6 2]
 [1 3]
 [4 3]
 [6 3]
 [2 2]
 [3 2]
 [6 2]
 [2 3]
 [3 3]
 [6 3]
 [2 2]
 [4 2]
 [4 2]])

What I want to do is to do this simple assignment:

out[rows_tf, columns_tf] = changed_tensor

for that I am doing this:

out[rows_tf:column_tf].assign(changed_tensor)

However, I received this error:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected begin, end, and strides to be 1D equal size tensors, but got shapes [1,8,3], [1,8,1], and [1] instead. [Op:StridedSlice] name: strided_slice/

this is the expected output:

[[0.        0.        0.        0.       ]
 [0.        8.3356    0.        8.8974   ]
 [0.        0.        6.103182  7.330564 ]
 [0.        0.        3.0614321 0.       ]
 [0.        0.        3.8914037 0.       ]
 [0.        8.457685  8.602337  0.       ]
 [0.        0.        5.826657  8.283971 ]
 [0.        0.        0.        0.       ]]

Any idea how can I finish this mission?

Thank you in advance:)

回答1:

This example (extended from tf documentation tf.scatter_nd_update here) should help.

You want to first combine your row_indices and column_indices into a list of 2d indices, which is indices argument to tf.scatter_nd_update. Then you fed a list of expected values, which is updates.

ref = tf.Variable(tf.zeros(shape=[8,4], dtype=tf.float32))
indices = tf.constant([[0, 2], [2, 2]])
updates = tf.constant([1.0, 2.0])

update = tf.scatter_nd_update(ref, indices, updates)
with tf.Session() as sess:
  sess.run(tf.initialize_all_variables())
  print sess.run(update)
Result:

[[ 0.  0.  1.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  2.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]

Specifically for your data,

ref = tf.Variable(tf.zeros(shape=[8,4], dtype=tf.float32))
changed_tensor = [[8.3356,    0.,        8.457685 ],
                  [0.,        6.103182,  8.602337 ],
                  [8.8974,    7.330564,  0.       ],
                  [0.,        3.8914037, 5.826657 ],
                  [8.8974,    0.,        8.283971 ],
                  [6.103182,  3.0614321, 5.826657 ],
                  [7.330564,  0.,        8.283971 ],
                  [6.103182,  3.8914037, 0.       ]]
updates = tf.reshape(changed_tensor, shape=[-1])
sparse_indices = tf.constant(
[[1, 1],
 [2, 1],
 [5, 1],
 [1, 2],
 [2, 2],
 [5, 2],
 [1, 3],
 [2, 3],
 [5, 3],
 [1, 2],
 [4, 2],
 [6, 2],
 [1, 3],
 [4, 3],
 [6, 3],
 [2, 2],
 [3, 2],
 [6, 2],
 [2, 3],
 [3, 3],
 [6, 3],
 [2, 2],
 [4, 2],
 [4, 2]])

update = tf.scatter_nd_update(ref, sparse_indices, updates)
with tf.Session() as sess:
  sess.run(tf.initialize_all_variables())
  print sess.run(update)

Result:

[[ 0.          0.          0.          0.        ]
 [ 0.          8.3355999   0.          8.8973999 ]
 [ 0.          0.          6.10318184  7.33056402]
 [ 0.          0.          3.06143212  0.        ]
 [ 0.          0.          0.          0.        ]
 [ 0.          8.45768547  8.60233688  0.        ]
 [ 0.          0.          5.82665682  8.28397083]
 [ 0.          0.          0.          0.        ]]