Qu

conv2d

Builtin index · Statistics & ML

result = conv2d(x, kernel, [stride], [padding])

Input: x, kernel, stride, padding · Output: result

What it is

Slides a (Kh, Kw) learnable kernel matrix over an (H, W) image matrix x, moving stride positions at a time (integer, default 1) with padding — "valid" (no padding) or "same" (output keeps x's (H, W) shape); default "valid".

Overloads

One call shape — this function is not overloaded.

CodeInputOutputDescription
result = conv2d(x, kernel, [stride], [padding])
x matrixnot documented yet
kernel matrixnot documented yet
stride matrix, optionalnot documented yet
padding matrix, optionalnot documented yet
result matrix
Returns an (H', W') convolved output matrix.

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

x1d = [1.0, 2.0, 3.0, 4.0, 5.0]
edge_kernel = [1.0, 0.0, -1.0]
y1d = conv1d(x1d, edge_kernel)
print("conv1d edge response: {y1d}")

img = [1, 5, 2, 8; 4, 3, 9, 1; 7, 2, 6, 0; 1, 1, 1, 1]
k2d = [1, 0; 0, -1]
y2d = conv2d(img, k2d, 1, "valid")
print("conv2d output:\n{y2d}")

print("maxpool2d: {maxpool2d(img, 2)}")
print("avgpool2d: {avgpool2d(img, 2)}")
output
conv1d edge response: [-2, -2, -2]
conv2d output:
[-2, -4, 1; 2, -3, 9; 6, 1, 5]
maxpool2d: [5, 9; 7, 6]
avgpool2d: [3.25, 5; 2.75, 2]

from statistics-ml

How it works

conv2d(x, kernel, [stride], [padding]) — the 2-D sibling of conv1d above, picking up exactly the follow-ups that arm's own doc comment named as out of scope: real stride and "valid"/"same" padding. Still deliberately single input channel & single output channel (multi-channel is its own, larger follow-up — same "correct over broad" call). x is either a lone image (Value::Mat, H x W) or a batch of them (Value::List of Value::Mat, one image per element — List, not a stacked Mat, since a whole 2-D image can't be one row of another matrix the way a 1-D sequence could for conv1d's own batching). kernel is always a plain Mat (kH x kW). stride (positional 3rd arg or stride=, default 1) and padding (positional 4th arg or padding=, default "valid") are both optional, mirroring conv1d's own default-everything-else shape. The sliding-window sum itself runs on rayon (conv2d_single's into_par_iter over output rows) — real CPU-parallel acceleration, not "runs on one core under a fancier name." Gradient-checked against central finite differences for both x and kernel (lone image and batched-List, "valid" and "same") before this shipped, matching every other autodiff addition in this file.

From the note above this builtin in the interpreter, where the reasoning was written down as it was built.