作为一个最小的例子,假设我有一个形式为的张量
[[ 1. 0. 3. ]
[ 7. 5. 6. ]
[ 0. 0. 0. ]
[ 0. 11. 1. ]
[ 0. 0. 0. ]
[ 0. 0. 0. ]
[13. 14. 16.5]]
是否有一种方法(在tensorflow中原生(来估算完全归零的行,使其值等于最后一个非完全归零行?即->:
[[ 1. 0. 3. ]
[ 7. 5. 6. ]
[ 7. 5. 6. ]
[ 0. 11. 1. ]
[ 0. 11. 1. ]
[ 0. 11. 1. ]
[13. 14. 16.5]]
我曾想过使用tf.tensor_scatter_nd_update
,但没有成功。
我们可以使用tf.gather(a, indices)
来获得上述输出。
indices
需要是[0, 1, 1, 3, 3, 3, 6]
,可以通过以下代码获得:
mask = tf.cast(tf.cast(tf.reduce_sum(a, axis=1), dtype=tf.bool), tf.float32)
#[1., 1., 0., 1., 0., 0., 1.] where non-zero sum
mask_range = (mask*tf.range(a.shape[0], dtype=tf.float32))
#[0., 1., 0., 3., 0., 0., 6.] apply mask on range()
indices =tf.cast(tf.scan(lambda a, b: tf.maximum(a, b), mask_range, initializer=tf.reduce_min(mask_range)), tf.int32)
# cumulative max [0, 1, 1, 3, 3, 3, 6]
tf.gather(a, indices)
[[ 1. , 0. , 3. ], [ 7. , 5. , 6. ], [ 7. , 5. , 6. ], [ 0. , 11. , 1. ], [ 0. , 11. , 1. ], [ 0. , 11. , 1. ], [13. , 14. , 16.5]]
此代码也可以在GPU上运行。
data = tf.constant([[ 1., 0., 3. ],
[ 7., 5., 6. ],
[ 0., 0., 0. ],
[ 0., 11., 1. ],
[ 0., 0., 0. ],
[ 0., 0., 0. ],
[13., 14., 16.5]])
rows_length = data.shape[-1]
i = tf.constant(0)
c = lambda i: tf.less(i, len(data))
tf.while_loop(c, find_zeros_and_update, [i])
def find_zeros_and_update(i):
global _data
if(i == 0):
_data = data
if(tf.reduce_sum(_data[i]) == 0):
rows = tf.ones(shape=(rows_length,1), dtype=tf.int32) + (i-1)
columns = tf.split(tf.range(0,rows_length),rows_length)
indices = tf.concat((rows , columns), axis=1)
update = _data[i-1]
_data = tf.tensor_scatter_nd_update(_data, indices, update,)
return (tf.add(i,1),)
输出:
<tf.Tensor: shape=(7, 3), dtype=float32, numpy=
array([[ 1. , 0. , 3. ],
[ 7. , 5. , 6. ],
[ 7. , 5. , 6. ],
[ 0. , 11. , 1. ],
[ 0. , 11. , 1. ],
[ 0. , 11. , 1. ],
[13. , 14. , 16.5]], dtype=float32)>