Python 提取最大和子矩阵

Python 提取最大和子矩阵,python,python-3.x,tensorflow,conv-neural-network,Python,Python 3.x,Tensorflow,Conv Neural Network,我有一个2DNxN矩阵,它包含一组实数的元素。我需要从中识别topnDxD子矩阵,使它们的和最大,并返回子矩阵的左上索引。我需要用Tensorflow来做 例如,我有以下4x4矩阵: [1 1 4 4] [1 1 4 4] [3 3 2 2] [3 3 2 2] 我需要识别两个子矩阵,它们的和最大,并返回它们的左上角索引。在上述情况下,具有最大和第二大和的2个子矩阵为: [[4 4] [[3 3] [4 4]] & [3 3]] 我需要返回[[0,2],[2,0]],两个矩

我有一个
2D
NxN
矩阵,它包含一组实数的元素。我需要从中识别top
n
DxD
子矩阵,使它们的和最大,并返回子矩阵的左上索引。我需要用Tensorflow来做

例如,我有以下
4x4
矩阵:

[1 1 4 4]
[1 1 4 4]
[3 3 2 2]
[3 3 2 2]
我需要识别两个子矩阵,它们的和最大,并返回它们的左上角索引。在上述情况下,具有最大和第二大和的2个子矩阵为:

[[4 4]    [[3 3]
 [4 4]] &  [3 3]]

我需要返回
[[0,2],[2,0]]
,两个矩阵的左上角索引。谢谢。

您可以通过下面的代码片段获得。其思想是建立一个包含每个子矩阵的每个元素的行和列索引的张量,然后对子矩阵求和并找到最大和

import tensorflow as tf

# Input data
input = tf.placeholder(tf.int32, [None, None])
# Submatrix dimension
dims = tf.placeholder(tf.int32, [2])
# Number of top submatrices to find
k = tf.placeholder(tf.int32, [])
# Sizes
input_shape = tf.shape(input)
rows, cols = input_shape[0], input_shape[1]
d_rows, d_cols = dims[0], dims[1]
subm_rows, subm_cols = rows - d_rows + 1, cols - d_cols + 1
# Index grids
ii, jj = tf.meshgrid(tf.range(subm_rows), tf.range(subm_cols), indexing='ij')
d_ii, d_jj = tf.meshgrid(tf.range(d_rows), tf.range(d_cols), indexing='ij')
# Add indices
subm_ii = ii[:, :, tf.newaxis, tf.newaxis] + d_ii
subm_jj = jj[:, :, tf.newaxis, tf.newaxis] + d_jj
# Make submatrices tensor
subm = tf.gather_nd(input, tf.stack([subm_ii, subm_jj], axis=-1))
# Add submatrices
subm_sum = tf.reduce_sum(subm, axis=(2, 3))
# Use TopK to find top submatrices
_, top_idx = tf.nn.top_k(tf.reshape(subm_sum, [-1]), tf.minimum(k, tf.size(subm_sum)))
# Get row and column
top_row = top_idx // subm_cols
top_col = top_idx % subm_cols
result = tf.stack([top_row, top_col], axis=-1)

# Test
with tf.Session() as sess:
    mat = [
        [1, 1, 4, 4],
        [1, 1, 4, 4],
        [3, 3, 2, 2],
        [3, 3, 2, 2],
    ]
    print(sess.run(result, feed_dict={input: mat, dims: [2, 2], k: 2}))
输出:

[[0 2]
[1 2]]

注意,这种情况下的输出是
[0,2]
[1,2]
,但不是
[2,0]
。这是因为从
[1,2]
开始的子矩阵与在
[2,0]
处的子矩阵的总和相同,如果按行迭代,它在矩阵中位于前面。如果在测试中通过<代码> k:3 < /代码>,结果中也会得到<代码>(2, 0)< /代码>。

我想你需要考虑所有可能的子矩阵,而不仅仅是不重叠的子矩阵,对吗?也就是说,在您的示例中,
[[1,4],[1,4]]
[[1,4],[3,2]]
是有效的子矩阵,对吗?是的,所有大小为2x2的子矩阵。它们可能会重叠-很像卷积中的滑动窗口操作,我需要“查看”所有子矩阵并按和查找前n个。我想知道是否有办法在可训练网络中使用这段代码?换句话说,如果我能将“结果”传递给损失函数并进行训练。当我现在这样做的时候,我得到了一个错误,我认为这是因为top_k是一个不可微函数。@Ahsan是的,我认为是这样的。然而,我不清楚你究竟如何区分这一点。
result
中的值是指数,那么它们的导数应该基于什么?您将在<代码>输入< /代码>上使用<代码> TF.DIF.<代码>(即,考虑<代码>输入<代码>作为连续函数的评价)?