Я пытаюсь выполнить обратную корреляцию (по крайней мере, так я думаю, это называется) для 2 матриц, чтобы получить результирующую матрицу.
Примечание: обратная свертка тоже работает, потому что я применяю это к CNN.
У меня есть следующие две матрицы:
vals
:
[[ 2 1 -3 -4 -4]
[ 2 -3 3 1 2]
[ 2 5 -6 6 -2]
[-5 4 1 5 4]
[ 0 0 1 -3 -4]]
w0
:
[[[0, 1, -1],
[1, -1, 0],
[0, 0, 0]],
[[1, 0, 0],
[0, -1, 1],
[1, 0, 1]],
[[ 1, -1, 0],
[-1, 0, -1],
[-1, 0, 1]]]
Я по существу хотите применить скользящее окно, за исключением того, что в этом случае все значения w0
умножаются на скалярное значение в каждой точке в vals
, а затем добавляются со смежными значениями.
При условии шага 1 и заполнение того же (wrt vals
), следующий код дает желаемый результат:
concat = np.zeros((3,7,7))
for k in range(len(w0)):
for i in range(len(vals)):
for j in range(len(vals[i])):
v = w0[k] * vals[i][j]
concat[k][i:i+v.shape[0], j:j+v.shape[1]] += v
print(concat)
В результате:
[[[ 0. 2. -1. -4. -1. 0. 4.]
[ 2. 1. -9. 5. -2. 5. -2.]
[ 2. -3. 9. -13. 13. -10. 2.]
[ 2. -2. -2. 9. -4. 1. -4.]
[ -5. 9. -3. 5. -5. -5. 4.]
[ 0. 0. 1. -4. -1. 4. 0.]
[ 0. 0. 0. 0. 0. 0. 0.]]
[[ 2. 1. -3. -4. -4. 0. 0.]
[ 2. -5. 4. 5. 3. 0. -4.]
[ 4. 4. -2. -3. -7. -5. -2.]
[ -3. -1. 3. 14. -3. 9. 0.]
[ 2. 10. -12. 11. -16. 7. 2.]
[ -5. 4. -4. 8. 9. 6. 0.]
[ 0. 0. 1. -3. -3. -3. -4.]]
[[ 2. -1. -4. -1. 0. 4. 0.]
[ 0. -6. 7. 1. 8. 2. 4.]
[ -2. 5. -11. 19. -12. -3. -6.]
[ -9. 7. 0. -11. 8. -9. 4.]
[ 3. -9. 13. -14. -10. 5. -6.]
[ 5. -4. -7. 2. 0. 8. 8.]
[ 0. 0. -1. 3. 5. -3. -4.]]]
, который я бы затем уменьшил, чтобы исключить заполнение , так:
print(concat[:,1:-1, 1:-1])
>>> [[[ 1. -9. 5. -2. 5.]
[ -3. 9. -13. 13. -10.]
[ -2. -2. 9. -4. 1.]
[ 9. -3. 5. -5. -5.]
[ 0. 1. -4. -1. 4.]]
[[ -5. 4. 5. 3. 0.]
[ 4. -2. -3. -7. -5.]
[ -1. 3. 14. -3. 9.]
[ 10. -12. 11. -16. 7.]
[ 4. -4. 8. 9. 6.]]
[[ -6. 7. 1. 8. 2.]
[ 5. -11. 19. -12. -3.]
[ 7. 0. -11. 8. -9.]
[ -9. 13. -14. -10. 5.]
[ -4. -7. 2. 0. 8.]]]
Подойдет любой из двух результатов для concat
, но желательно тот, который включает отступы.
Кто-нибудь знает способ сделать это без используя python петли? Я бы предпочел использовать numpy или какую-либо другую библиотеку, поскольку она должна выполнять те же вычисления быстрее, чем мой код.
РЕДАКТИРОВАТЬ:
Я также хочу выполнить тот же вид обратная корреляция на w0
, поэтому снова используется vals
, но вместо этого:
a
:
[[[2, 0, 2, 2, 2],
[1, 1, 0, 2, 0],
[0, 0, 1, 2, 2],
[2, 2, 2, 0, 0],
[1, 0, 1, 2, 0]],
[[1, 2, 1, 0, 1],
[0, 2, 0, 0, 1],
[0, 0, 2, 2, 1],
[2, 0, 1, 0, 2],
[0, 1, 2, 2, 2]],
[[0, 0, 2, 2, 2],
[0, 1, 2, 1, 0],
[0, 0, 0, 2, 0],
[0, 2, 0, 0, 2],
[0, 0, 2, 2, 1]]]
И в этом случае выполняется скользящее окно 3x3 вдоль a
с заполнение 1, и умножение всех значений в скользящем окне на связанный индекс скалярного значения в vals
, и, наконец, получение вывода того же размера, что и w0
. Следующий код достигает этого:
concat = np.zeros((3,3,3))
for k in range(len(w0)):
f = np.pad(a[k], 1)
for i in range(len(vals)):
for j in range(len(vals[i])):
v = f[i:i+w0.shape[1], j:j+w0.shape[2]] * vals[i][j]
concat[k] += v
с:
print(concat)
>>>[[[ 4. 56. 8.]
[ 1. -20. 1.]
[ 22. 12. 21.]]
[[ 7. 18. 21.]
[ 5. -22. 20.]
[ 35. 26. 33.]]
[[ 20. 13. 4.]
[-25. 2. -26.]
[ -5. 15. 38.]]]