我正在尝试在2D数组的单个轴上使用指定的切片执行局部归约。
我使用numpy的UIStatusBarManager *manager = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager;
CGRect statusBarFrame = manager.statusBarFrame;
或numpy.ufunc.reduceat
实现了这一点,但是我想在tensorflow中做同样的事情,因为此reduce操作的输入是tensorflow卷积的输出。
我遇到了numpy.add.reduceat
,但不确定如何在我的情况下使用。
如果我可以在Tensorflow中执行tf.math.reduce_sum
操作,那将非常好,因为我可以利用GPU。
答案 0 :(得分:1)
您可以使用tf.math.segment_sum
做几乎相同的事情:
import tensorflow as tf
import numpy as np
def add_reduceat_tf(a, indices, axis=0):
a = tf.convert_to_tensor(a)
indices = tf.convert_to_tensor(indices)
# Transpose if necessary
transpose = not (isinstance(axis, int) and axis == 0)
if transpose:
axis = tf.convert_to_tensor(axis)
ndims = tf.cast(tf.rank(a), axis.dtype)
a = tf.transpose(a, tf.concat([[axis], tf.range(axis),
tf.range(axis + 1, ndims)], axis=0))
# Make segment ids
r = tf.range(tf.shape(a, out_type=indices.dtype)[0])
segments = tf.searchsorted(indices, r, side='right')
# Compute segmented sum and discard first unused segment
out = tf.math.segment_sum(a, segments)[1:]
# Transpose back if necessary
if transpose:
out = tf.transpose(out, tf.concat([tf.range(1, axis + 1), [0],
tf.range(axis + 1, ndims)], axis=0))
return out
# Test
np.random.seed(0)
a = np.random.rand(5, 10).astype(np.float32)
indices = [2, 4, 7]
axis = 1
# NumPy computation
out_np = np.add.reduceat(a, indices, axis=axis)
# TF computation
with tf.Graph().as_default(), tf.Session() as sess:
out = add_reduceat_tf(a, indices, axis=axis)
out_tf = sess.run(out)
# Check result
print(np.allclose(out_np, out_tf))
# True
您可以将上面的tf.math.segment_sum
替换为您要使用的归约函数。它与实际的np.ufunc.reduceat
之间的唯一区别是特殊情况indices[i] >= indices[i + 1]
。发布的函数要求对indices
进行排序,并且如果存在indices[i] == indices[i + 1]
在输出中对应的i
位置为零而不是a[indices[i]]
的情况。