如何计算张量中的相似度窗口?

时间:2019-01-02 06:59:45

标签: python tensorflow

我有一个张量为(None,3)edittext.setOnTouchListener且步长为a的张量,我想计算每个元素及其左2个元素和右2个元素的余弦相似度矢量,如果没有,则与[0,0,0]比较,输出的形状为k=2 例如:

(None, k*2)

2 个答案:

答案 0 :(得分:3)

尝试一下:

UIStackView

答案 1 :(得分:1)

假设您在构造图形时知道k,这是做到这一点的一种方法:

import tensorflow as tf

a = tf.placeholder(tf.float32, shape=[None, 3])
k = 2
# Number of input vectors
n = tf.shape(a)[0]
# Normalize
a_norm = tf.math.l2_normalize(a, axis=-1)
# Add zero vectors at beginning and end
a_norm_pad = tf.pad(a_norm, [[k, k], [0, 0]])
# Build array of multiplied vectors
b = []
# From k before to k after
for i in range(0, 2 * k + 1):
    # Skip self
    if i == k: continue
    # Take window of vectors
    b.append(tf.slice(a_norm_pad, [i, 0], [n, -1]))
# Stack windows
b = tf.stack(b, axis=1)
# Dot product
r = tf.reduce_sum(tf.expand_dims(a_norm, 1) * b, axis=-1)
# Test
with tf.Session() as sess:
    v = sess.run(r, feed_dict={a: [[1, 2, 3],
                                   [4, 5, 6],
                                   [4, 5, 6],
                                   [0, 0, 0],
                                   [3, 4, 5],
                                   [1, 1, 1]]})
    print(v)

输出:

[[0.         0.         0.9746318  0.9746318 ]
 [0.         0.9746318  1.         0.        ]
 [0.9746318  1.         0.         0.9992205 ]
 [0.         0.         0.         0.        ]
 [0.9992205  0.         0.97979593 0.        ]
 [0.         0.97979593 0.         0.        ]]

编辑:这是同一件事,但具有动态k值。据我所知,目前尚没有创建滑动窗口的好方法,因此您可以使用循环来创建b数组,然后其余的将是相同的。

import tensorflow as tf

# Starts as before
a = tf.placeholder(tf.float32, shape=[None, 3])
k = tf.placeholder(tf.int32, shape=[])
a_shape = tf.shape(a)
n = a_shape[0]
d = a_shape[1]
a_norm = tf.math.l2_normalize(a, axis=-1)
a_norm_pad = tf.pad(a_norm, [[k, k], [0, 0]])
# Build second array in a TensorFlow loop
b = tf.TensorArray(a.dtype, size=1, dynamic_size=True,
                   element_shape=[None, 3], clear_after_read=True)
def build_b(i, b):
    # Pick before or after self
    idx = tf.cond(i < k, lambda: i, lambda: i + 1)
    # Add window
    b = b.write(i, tf.slice(a_norm_pad, [idx, 0], [n, -1]))
    return i + 1, b
# Loop and collect
_, b = tf.while_loop(lambda i, b: i < 2 * k, build_b, [0, b])
b = b.stack()
# Fix axes
b = tf.transpose(b, [1, 0, 2])
# Continues as before
r = tf.reduce_sum(tf.expand_dims(a_norm, 1) * b, axis=-1)
with tf.Session() as sess:
    v = sess.run(r, feed_dict={a: [[1, 2, 3],
                                   [4, 5, 6],
                                   [4, 5, 6],
                                   [0, 0, 0],
                                   [3, 4, 5],
                                   [1, 1, 1]],
                               k: 2})
    print(v)
    # Same output as before