我有一个类似的用例,需要在一批多通道图像上创建滑动窗口,最终编写了以下函数。
我撰写了一篇更深入的博客文章,介绍了手动创建卷积层的相关内容。该函数实现了滑动窗口,并可对输入数组进行膨胀或添加填充。
该函数的输入为:
input - (Batch, Channel, Height, Width) 的大小
output_size - 取决于使用情况,下面有注释。
kernel_size - 您希望创建的滑动窗口的大小(正方形)
padding - 添加到(H,W)维度外部的零填充量
stride - 滑动窗口在输入上应采取的步幅
dilate - 扩展输入单元格的数量。这会在元素之间添加0填充的行/列
通常,在执行前向卷积时,您不需要执行膨胀,因此可以使用以下公式找到输出大小(将x替换为输入维度):
(x-kernel_size+2*padding)//stride+1
使用此函数执行卷积的反向传递时,步长为1,并将输出大小设置为正向传递的x输入大小。
使用此函数的示例代码可在此链接中找到。
def getWindows(input, output_size, kernel_size, padding=0, stride=1, dilate=0):
working_input = input
working_pad = padding
if dilate != 0:
working_input = np.insert(working_input, range(1, input.shape[2]), 0, axis=2)
working_input = np.insert(working_input, range(1, input.shape[3]), 0, axis=3)
if working_pad != 0:
working_input = np.pad(working_input, pad_width=((0,), (0,), (working_pad,), (working_pad,)), mode='constant', constant_values=(0.,))
in_b, in_c, out_h, out_w = output_size
out_b, out_c, _, _ = input.shape
batch_str, channel_str, kern_h_str, kern_w_str = working_input.strides
return np.lib.stride_tricks.as_strided(
working_input,
(out_b, out_c, out_h, out_w, kernel_size, kernel_size),
(batch_str, channel_str, stride * kern_h_str, stride * kern_w_str, kern_h_str, kern_w_str)
)
这篇文章
可能值得一看,它使用了步幅。 - Divakar