2D 卷积核,K
,形状(k1, k2, n_channel, n_filter)
适用于 2D 矢量,A
,形状(m1, m2, n_channel)
并生成另一个 2D 向量,B
,形状(m1 - k1 + 1, m2 - k2 + 1, n_filter)
(with valid填充)。
这也是事实,对于每个K
,存在一个W_K
形状的(m1 - k1 + 1, m2 - k2 + 1, n_filter, m1, m2, n_channel)
,使得张量点为W_K
and A
等于B
. i.e. B = np.tensordot(W_K, A, 3)
.
我正在尝试找到一个纯 NumPy 解决方案来生成这个W_K
from K
不使用任何 python 循环。
我可以看到W_K[i,j,f] == np.pad(K[...,f], ((i,m1-i-k1), (j,m2-j-k2)), 'constant', constant_values=0)
或者简单地W_K[i, j, f, i:i+k1, j:j+k2, ...] == K[..., f]
.
我正在寻找的几乎类似于托普利茨矩阵。但我需要它是多维度的。
循环代码示例:
import numpy as np
# 5x5 image with 3-channels
A = np.random.random((5,5,3))
# 2x2 Conv2D kernel with 2 filters for A
K = np.random.random((2,2,3,2))
# It should be of (4,4,2,5,5,3), but I create this way for convenience. I move the axis at the end.
W_K = np.empty((4,4,5,5,3,2))
for i, j in np.ndindex(4, 4):
W_K[i, j] = np.pad(K, ((i, 5-i-2),(j, 5-j-2), (0, 0), (0, 0)), 'constant', constant_values=0)
# above lines can also be rewritten as
W_K = np.zeros((4,4,5,5,3,2))
for i, j in np.ndindex(4, 4):
W_K[i, j, i:i+2, j:j+2, ...] = K[...]
W_K = np.moveaxis(W_K, -1, 2)
# now I can do
B = np.tensordot(W_K, A, 3)