Хорошо, я думаю, что у меня есть решение, но оно включает в себя использование как простых операций (например, np.repeat
), так и операций TensorFlow 2.0 (например, tf.segment_sum
). И, чтобы предупредить вас, это не самое ясное элегантное решение в мире, но оно было самым элегантным, которое я мог придумать. Итак, вот так.
Главный виновник в вашей проблеме - это весовая матрица. Если вы манипулируете этой весовой матрицей, чтобы она была матрицей 4х4 (с правильной суммой весов в каждой позиции), у вас есть хорошая весовая матрица, которую вы можете выполнять поэлементным умножением с помощью входных данных. И это мое решение. Обратите внимание, что это разработано для проблемы 4x4, и вы сможете относительно легко расширить ее до матрицы 500x500.
import numpy as np
import tensorflow as tf
a = np.array([[1,2,3,4],[4,3,2,1],[1,2,3,4],[4,3,2,1]])
w = np.array([[5,4,3],[3,4,5],[5,4,3]])
# We make weights to a 6x6 matrix by repeating 2 times on both axis
w_rep = np.repeat(w,2,axis=0)
w_rep = np.repeat(w_rep,2,axis=1)
# Let's now jump in to tensorflow
tf_a = tf.constant(a)
tf_w = tf.constant(w_rep)
tf_segments = tf.constant([0,1,1,2,2,3])
# This is the most tricky bit, here we use the segment_sum to achieve what we need
# You can use segment_sum to get the sum of segments on the very first dimension of a matrix.
# So you need to do that to the input matrix twice. One on the original and the other on the transpose.
tf_w2 = tf.math.segment_sum(tf_w, tf_segments)
tf_w2 = tf.transpose(tf_w2)
tf_w2 = tf.math.segment_sum(tf_w2, tf_segments)
tf_w2 = tf.transpose(tf_w2)
print(tf_w2*a)
PS: я постараюсь включить иллюстрацию того, что происходит здесь в будущемредактировать. Но я считаю, что это займет некоторое время.