Tensorflow 如何通过在给定张量的某些值周围选择窗口,从该张量创建子张量?

Tensorflow 如何通过在给定张量的某些值周围选择窗口,从该张量创建子张量?,tensorflow,keras,slice,embedding,Tensorflow,Keras,Slice,Embedding,我的问题与你所问的问题相似。不同的是,我想要一个新的张量B,它是从初始张量a中选择的一些窗口的串联。目标是用一个先验未知的张量,即:输入层。下面是一个使用已定义常量的示例,仅用于解释我想做的事情: 给定2个3维嵌入的输入张量: A = K.constant([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6, 6, 6], [7, 7, 7], [2, 2, 2], [8, 8, 8], [9, 9, 9], [10, 10, 1

我的问题与你所问的问题相似。不同的是,我想要一个新的张量B,它是从初始张量a中选择的一些窗口的串联。目标是用一个先验未知的张量,即:输入层。下面是一个使用已定义常量的示例,仅用于解释我想做的事情:

给定2个3维嵌入的输入张量:

A = K.constant([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6, 6, 6], [7, 7, 7], [2, 2, 2], [8, 8, 8], [9, 9, 9], [10, 10, 10]])
t = K.constant([[2, 2, 2], [6, 6, 6], [10, 10, 10]])
我想创建一个张量B,它是从a中选择的下列子张量或窗口的串联,对应于t中每个元素的出现邻域:

我们的目标是应用这个过程来重新构造模型的输入张量,而不是预定义的常数。那么,考虑到我的模型的两个输入,我如何做到这一点:

in_A = Input(shape=(10,), dtype="int32")
in_t = Input(shape=(3,), dtype="int32")
embed_A = Embedding(...)(in_A)
embed_t = Embedding(...)(in_t)
B = ...  # some function or layer to create the tensor B as described in the example above using embed_A and embed_t
# B will be used then on the next layer like this:
# next_layer = some_other_layer(...)(embed_t, B)
或者选择次张量元素,然后应用嵌入层:

in_A = Input(shape=(10,), dtype="int32")
in_t = Input(shape=(3,), dtype="int32")
B = ...  # some function to select the desired element windows as described above
embed_B = Embedding(...)(B)
embed_t = Embedding(...)(in_t)
# then add the next layer like this:
# next_layer = some_other_layer(...)(embed_t, embed_B)
提前谢谢

import tensorflow as tf
from tensorflow.contrib import autograph
# you can uncomment next line to enable eager execution to see what happens at each step, you'd better use the up-to-date tf-nightly to run this code
# tf.enable_eager_execution()
A = tf.constant([[1, 1, 1],
                 [2, 2, 2],
                 [3, 3, 3],
                 [4, 4, 4],
                 [5, 5, 5],
                 [6, 6, 6],
                 [7, 7, 7],
                 [2, 2, 2],
                 [8, 8, 8],
                 [9, 9, 9],
                 [10, 10, 10]])

t = tf.constant([[2, 2, 2],
                 [6, 6, 6],
                 [10, 10, 10]])

# expand A in axis 1 to compare elements in A and t with broadcast
expanded_a = tf.expand_dims(A, axis=1)

# find where A and t are equal with each other
equal = tf.equal(expanded_a, t)
reduce_all = tf.reduce_all(equal, axis=2)
# find the indices
where = tf.where(reduce_all)
where = tf.cast(where, dtype=tf.int32)

# here we want to a function to find the indices to do tf.gather, if a match 
# is found in the start or
# end of A, then pick up the two elements after or before it, otherwise the 
# left one and the right one along with itself are used
@autograph.convert()
def _map_fn(x):
    if x[0] == 0:
        return tf.range(x[0], x[0] + 3)
    elif x[0] == tf.shape(A)[0] - 1:
        return tf.range(x[0] - 2, x[0] + 1)
    else:
        return tf.range(x[0] - 1, x[0] + 2)


indices = tf.map_fn(_map_fn, where, dtype=tf.int32)

# reshape the found indices to a vector
reshape = tf.reshape(indices, [-1])

# gather output with found indices
output = tf.gather(A, reshape)

只要您理解此代码,就可以轻松编写自定义层

w1,…,w4来自哪里?@Jie.Zhou我刚刚添加了对不同元素w1…w4的解释感谢您的回答。然而,我无法理解所有的细节,代码到底做了什么?请对您提出的解决方案添加一些意见好吗?此外,如何使其直接适应网络输入?正如我在问题中提到的:B=。。。求和函数fin_A,in_t,用于如上所述选择所需的元素窗口。再次感谢。感谢您的澄清,我现在可以更好地理解了,但我还有两个问题:第一,来自tensorflow.contrib import autograph的行生成错误,无法使用tensorflow 1.7.0导入python3.5的autograph。第二个问题是:我如何使此解决方案适应未知输入,如:in_A=Inputshape=10,dtype=int32,in_t=Inputshape=3,dtype=int32,然后B=。。。连接选定的Windows T,A?是所需的输出。谢谢。@BelkacemThiziri亲笔签名最早出现在TensorFlow 1.8中,但从那时起已经有了很多改进,我推荐1.10版本。谢谢@alexbw,你能给我一些例子的链接吗?嗨@BelkacemThiziri,我们在TensorFlow网站上有一些文档:
import tensorflow as tf
from tensorflow.contrib import autograph
# you can uncomment next line to enable eager execution to see what happens at each step, you'd better use the up-to-date tf-nightly to run this code
# tf.enable_eager_execution()
A = tf.constant([[1, 1, 1],
                 [2, 2, 2],
                 [3, 3, 3],
                 [4, 4, 4],
                 [5, 5, 5],
                 [6, 6, 6],
                 [7, 7, 7],
                 [2, 2, 2],
                 [8, 8, 8],
                 [9, 9, 9],
                 [10, 10, 10]])

t = tf.constant([[2, 2, 2],
                 [6, 6, 6],
                 [10, 10, 10]])

# expand A in axis 1 to compare elements in A and t with broadcast
expanded_a = tf.expand_dims(A, axis=1)

# find where A and t are equal with each other
equal = tf.equal(expanded_a, t)
reduce_all = tf.reduce_all(equal, axis=2)
# find the indices
where = tf.where(reduce_all)
where = tf.cast(where, dtype=tf.int32)

# here we want to a function to find the indices to do tf.gather, if a match 
# is found in the start or
# end of A, then pick up the two elements after or before it, otherwise the 
# left one and the right one along with itself are used
@autograph.convert()
def _map_fn(x):
    if x[0] == 0:
        return tf.range(x[0], x[0] + 3)
    elif x[0] == tf.shape(A)[0] - 1:
        return tf.range(x[0] - 2, x[0] + 1)
    else:
        return tf.range(x[0] - 1, x[0] + 2)


indices = tf.map_fn(_map_fn, where, dtype=tf.int32)

# reshape the found indices to a vector
reshape = tf.reshape(indices, [-1])

# gather output with found indices
output = tf.gather(A, reshape)