我正在尝试使用padding = same(类似于keras)实现2D卷积的块Toeplitz矩阵。我看到,阅读和搜索了很多信息,但没有实现。
我已经摘录了一些参考资料(也正在阅读论文,但是任何人都在谈论用填充填充convd,只有完整或有效):
麦克劳伦斯的答案:answer。他从字面上说:“他用于填充= 0,但可以通过更改h_blocks和w_blocks以及W_conv [i + j,:,j,:]轻松地进行调整。”但是我不知道如何实现这种改变。
Warren的Weckesser答案:answer:解释什么是块矩阵。
萨尔瓦多(Salvador)的达利(Dali)答案:answer:介绍了执行padTeedplitz矩阵以进行padding =“ valid”的方法, 阿里·萨利希(Ali Salehi)解释了填充“完整”的方法。
修改McLawrence答案的代码,我获得了与padas =“ same”的keras conv2d相同的结果,但仅适用于2x2内核尺寸和平方输入矩阵。代码是:
k_h,k_w = kernel.shape
i_h,i_w = input.shape
o_h,o_w = input.shape
s_c = o_h-o_w
# construct 1d conv toeplitz matrices for each row of the kernel
toeplitz = []
for r in range(k_h):
toeplitz.append(linalg.toeplitz(c=(kernel[r,0],*np.zeros(i_w-1)),r=(*kernel[r],*np.zeros(i_w-k_w))) )
# construct toeplitz matrix of toeplitz matrices (just for padding=0)
h_blocks,w_blocks = input.shape
h_block,w_block = toeplitz[0].shape
W_conv = np.zeros((h_blocks,h_block,w_blocks,w_block))
for i,B in enumerate(toeplitz):
for j in range(o_h):
if i == len(toeplitz)-1 and j == o_h-1:
continue
W_conv[j,:,i+j,:] = B
W_conv.shape = (h_blocks*h_block,w_blocks*w_block)
return W_conv
任何论文或参考文献可能会有所帮助?