Python 如何在Tensorflow张量中的每一行和每一列中选取顶部的q元素?
我在Tensorflow中实现了一个特殊的损失函数。下面是一个特殊函数的numpy样式代码,该函数拾取顶部的q元素并屏蔽每行和每列中的其他元素。注意Python 如何在Tensorflow张量中的每一行和每一列中选取顶部的q元素?,python,tensorflow,deep-learning,Python,Tensorflow,Deep Learning,我在Tensorflow中实现了一个特殊的损失函数。下面是一个特殊函数的numpy样式代码,该函数拾取顶部的q元素并屏蔽每行和每列中的其他元素。注意A是n*n矩阵,q是小于n的整数 def阈值(A,q): A_uuz=A.copy() n=一个形状[1] 对于范围(n)中的i: A_[i,:][A_[i,:].argsort()[0:n-q]]=0 A_[:,i][A_[:,i].argsort()[0:n-q]]=0 归还_ 现在的问题是,我有一个张量流张量a,它的形状是(n,n),我想实现
A
是n*n
矩阵,q
是小于n
的整数
def阈值(A,q):
A_uuz=A.copy()
n=一个形状[1]
对于范围(n)中的i:
A_[i,:][A_[i,:].argsort()[0:n-q]]=0
A_[:,i][A_[:,i].argsort()[0:n-q]]=0
归还_
现在的问题是,我有一个张量流张量a
,它的形状是(n,n)
,我想实现与numpy相同的逻辑。但是,我不能使用索引直接为张量A
赋值。是否有人对此有一些解决方案?TLDR;
我们可以创建一个函数,按如下方式屏蔽除顶部k
元素之外的所有元素:
def mask_all_但_top_k(X,k):
n=X.形状[1]
top_k_index=tf.math.top_k(X,k).index
掩码=tf.减少总和(tf.one\u hot(top\u k\u索引,n),轴=1)
返回掩码*X
不幸的是,tf.map.top_k
不允许我们指定维度,但我们当然可以通过先将X
转置,然后将结果转置为tf.transpose()
解释
我们可以通过创建一个由1和0组成的掩码,然后按元素相乘来实现
例如,考虑到n=4,k=2的情况,我们有以下矩阵:
array([[0.67757607, 0.74070597, 0.89508283, 0.11858773],
[0.7661159 , 0.8737055 , 0.73599136, 0.1552105 ],
[0.7093129 , 0.44203556, 0.48861897, 0.83231044],
[0.24682868, 0.36648738, 0.92984104, 0.9881872 ]], dtype=float32)
然后我们可以使用tf.math.top_k
函数来获得矩阵每行中前2个值的索引:
top_k_index=tf.math.top_k(X,2).index
现在,我们使用一个小技巧首先对以下内容进行编码:
tf.one_hot(top_k_indices, 4)
array([[[0., 0., 1., 0.],
[0., 1., 0., 0.]],
[[0., 1., 0., 0.],
[1., 0., 0., 0.]],
[[0., 0., 0., 1.],
[1., 0., 0., 0.]],
[[0., 0., 0., 1.],
[0., 0., 1., 0.]]], dtype=float32)>
然后在从第二个维度到最后一个维度上减少它们,以创建我们的掩码:
tf.reduce\u sum(tf.one\u hot(top\u k\u索引,4),轴=1)
数组([[0,1,1,0.]),
[1., 1., 0., 0.],
[1., 0., 0., 1.],
[0,0,1,1.]],dtype=float32)>
现在,我们只需执行Hadamard(元素)乘法即可获得所需的结果:
array([[0. , 0.74070597, 0.89508283, 0. ],
[0.7661159 , 0.8737055 , 0. , 0. ],
[0.7093129 , 0. , 0. , 0.83231044],
[0. , 0. , 0.92984104, 0.9881872 ]], dtype=float32)>
综上所述,我们可以创建一个函数来屏蔽除顶部k
元素外的所有元素,如下所示:
def mask_all_but_top_k(X, k):
n = X.shape[1]
top_k_indices = tf.math.top_k(X, k).indices
mask = tf.reduce_sum(tf.one_hot(top_k_indices, n), axis=1)
return mask * X