经过卷积后输出的尺寸是MxM,假设输入的是spatial size是N x N,kernel size是 K,步幅stride是S,填充padding为P,那么:
M = (N ? k + 2P )/S+1
2D卷积中,卷积核的权重shape:(out_ch, in_ch , k, k)
def conv2d(inputs, kernels, bias, stride, padding):
""""
inputs: c, h, w
kernels: out_ch , in_ch, kh, kw; in_ch == c
bias: out_ch
"""
c, h, w =inputs.shape
out_ch, in_ch, kh, kw = kernels.shape
h_out = 1 + (h + 2*padding - kh) // stride
w_out = 1 + (h + 2*padding - kh) // stride
outputs = np.zeros((out_ch, h_out, w_out))
inputs_pad = np.pad(inputs, ((0, 0), (padding, padding), (padding, padding)))
for i in range(h_out):
for j in range(w_out):
area = inputs_pad[:, i*stride:i*stride+kh, j*stride:j*stride+kw] # in_ch, k, k
outputs[:, i, j] = np.sum(area[None,:] * kernels, axis=(1,2,3)) + bias
return outputs