Извлечь подматрицы максимальной суммы

1

У меня есть 2D матрица NxN которой есть элементы из набора действительных чисел. Мне нужно определить из него верхние n DxD -подматриц, чтобы их сумма была максимальной и возвращала верхний левый индекс подматриц. Мне нужно сделать это в Tensorflow.

Например, у меня есть следующая матрица 4x4:

[1 1 4 4]
[1 1 4 4]
[3 3 2 2]
[3 3 2 2]

Мне нужно определить 2 подматрицы, которые имеют наибольшую сумму и возвращают их верхний левый индекс. В приведенном выше случае 2 подматрицы с наибольшей и второй по величине суммой:

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

Мне нужно вернуть [[0,2],[2,0]], верхние левые индексы к обеим матрицам. Благодарю.

  • 1
    Я полагаю, вам нужно рассмотреть все возможные подматрицы, а не только непересекающиеся, верно? То есть в вашем примере [[1, 4], [1, 4]] и [[1, 4], [3, 2]] являются действительными подматрицами, верно?
  • 0
    Да, все подматрицы размером 2х2. Они могут перекрываться - почти как операция со скользящим окном в свертке, мне нужно «увидеть» все подматрицы и найти верхний n по сумме.
Теги:
tensorflow
python-3.x
conv-neural-network

1 ответ

1
Лучший ответ

Вы можете получить это со следующим фрагментом. Идея состоит в том, чтобы построить тензор, содержащий индексы строк и столбцов каждого элемента каждой подматрицы, а затем суммировать подматрицы и найти наибольшие суммы.

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] в результате.

  • 0
    Мне было интересно, есть ли способ использовать этот кусок кода в обучаемой сети? Другими словами, если я могу передать «результат» функции потери и провести тренировку. Когда я делаю это сейчас, я получаю сообщение об ошибке, и я думаю, что это потому, что top_k - это недифференцируемая функция.
  • 0
    @ Ахсан Да, я думаю, что это так. Однако мне не ясно, как бы вы на самом деле это дифференцировали. Значения в result являются индексами, так на чем же должна основываться их производная? Вы бы взяли tf.diff на input (то есть рассматриваете input как оценку непрерывной функции)?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню