我试图使用tensorflow将点列表移动到原点,数学上最好的方法是找到点列表的质心,然后通过该质心减去点列表。
问题:在运行时之前,点列表中包含的行数是未知的。
到目前为止代码:
import tensorflow as tf
example_point_list = tf.constant([[3., 3.], [.2, .2], [.1, .1]]) // but with any number of points
centroid = tf.reduce_mean(example_point_list, 0)
// subtract???
origin_point_list = tf.sub(example_point_list, centroid)
问题是减法在逐个元素的基础上工作,所以我必须创建一个与点列表具有相同行数的质心张量,但是没有方法可以做到这一点。
(用数学术语表示)
A = [[1, 1],
[2, 2]
[3, 3]]
B = avg(A) // [2, 2]
// step I need to do but do not know how to do it
B -> B1 // [[2, 2], [2, 2], [2, 2]]
Result = A - B1
感谢任何帮助!
答案 0 :(得分:5)
由于broadcasting,您不需要平铺行。事实上,不平铺它们并直接从矩阵中减去矢量效率更高。在你的情况下,它看起来像这样
tf.reset_default_graph()
example_points = np.array([[1, 1], [2, 2], [3, 3]], dtype=np.float32)
example_point_list = tf.placeholder(tf.float32)
centroid = tf.reduce_mean(example_point_list, 0)
result = example_point_list - centroid
sess = tf.InteractiveSession()
sess.run(result, feed_dict={example_point_list: example_points})
结果
array([[-1., -1.],
[ 0., 0.],
[ 1., 1.]], dtype=float32)
如果你真的想明确地平铺质心向量,你可以使用shape
运算符来实现它,它可以在运行时获得形状
tf.reset_default_graph()
example_point_list0 = np.array([[1, 1], [2, 2], [3, 3]], dtype=np.float32)
example_point_list = tf.placeholder(tf.float32)
# get number of examples from the array: [3]
num_examples = tf.slice(tf.shape(example_points), [0], [1])
# reshape [3] into 3
num_examples_flat = tf.reshape(num_examples, ())
centroid = tf.reduce_mean(example_point_list, 0)
# reshape centroid vector [2, 2] into matrix [[2, 2]]
centroid_matrix = tf.reshape(centroid, [1, -1])
# assemble 3 into vector of dimensions to tile: [3, 1]
tile_shape = tf.pack([num_examples_flat, 1])
# tile [[2, 2]] into [[2, 2], [2, 2], [2, 2]]
centroid_tiled = tf.tile(centroid_matrix, tile_shape)
sess = tf.InteractiveSession()
sess.run(centroid_tiled, feed_dict={example_point_list: example_point_list0})
结果
array([[ 2., 2.],
[ 2., 2.],
[ 2., 2.]], dtype=float32)