Implement the backward pass of 2D convolution, computing gradients w.r.t. both the kernel (dkernel) and the input (dx), given the upstream gradient dout.
For each output position (i, j, c_out):
Kernel gradient (accumulate patch contribution):
dkernel[kh, kw, cin, cout] += dout[i, j, cout] * x[i*stride+kh, j*stride+kw, cin]
Input gradient (distribute gradient back through kernel):
dx[i*stride+kh, j*stride+kw, cin] += dout[i, j, cout] * kernel[kh, kw, cin, cout]
Signature: def conv2d_backward(dout, x, kernel, stride=1, padding=0)
dout: (H_out, W_out, C_out) — upstream gradientx: (H, W, C_in) — original input (before padding)kernel: (kH, kW, C_in, C_out) — filter weightsstride: int (default 1)padding: int (default 0)[dx, dkernel] — list of gradients w.r.t. input and kernelThe test harness compares the concatenated flattened output: np.concatenate([dx.flatten(), dkernel.flatten()]). Your function must return [dx, dkernel] as numpy arrays or lists.
Math
Asked at
Test Results