RECEPTIVE FIELD

Ch 7 ▸ Backprop through a convolution ▸ Module 2/4

  1. 1Loss and gradients
  2. 2Gradients for the weights
  3. 3Gradients for the input
  4. 4Learning a kernel

Gradients for the weights.

🔒 This module is locked

It builds on Loss and gradients. Pass that module’s knowledge check to unlock it, or skip ahead if you already know the material.

Go to Loss and gradients

Backpropagation reaches a convolution layer with one number for each of its outputs: the gradient of the loss with respect to that output. Call that map of gradients GG. The layer’s job is to turn GG into a gradient for each of its nine weights.

The example

Take chapter 2’s 4×4 example: the image, the edge kernel, and the 2×2 output map it made.

x=[1488259914881488]w=[−101−202−101]y=[28162816]x = \begin{bmatrix} 1 & 4 & 8 & 8 \\ 2 & 5 & 9 & 9 \\ 1 & 4 & 8 & 8 \\ 1 & 4 & 8 & 8 \end{bmatrix} \qquad w = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix} \qquad y = \begin{bmatrix} 28 & 16 \\ 28 & 16 \end{bmatrix}

Suppose the targets are 27, 16, 28 and 17. Two outputs are right, one is 1 too high, and one is 1 too low. The squared error is 1+0+0+1=21 + 0 + 0 + 1 = 2, and each output’s gradient is 2×(y−t)2 \times (y - t):

G=[2×(28−27)2×(16−16)2×(28−28)2×(16−17)]=[200−2]G = \begin{bmatrix} 2 \times (28 - 27) & 2 \times (16 - 16) \\ 2 \times (28 - 28) & 2 \times (16 - 17) \end{bmatrix} = \begin{bmatrix} 2 & 0 \\ 0 & -2 \end{bmatrix}

In a real network, GG would arrive from the layers above. Here it comes straight from the loss.

One weight, every position

Take the kernel’s middle weight. Because of weight sharing, it was used at all four positions, and each time it sat on a different pixel: 5 for the top-left output, 9 for the top-right, 4 for the bottom-left and 8 for the bottom-right.

Nudge that weight up by a small amount hh. Each output changes by hh times the pixel the weight sat on, because that’s what the weight multiplied. And by the chain rule, each output’s change moves the loss by its gradient times that change. So each output contributes (pixel × GG) to the weight’s gradient, and the four contributions add up:

(5×2)+(9×0)+(4×0)+(8×(−2))=10+0+0−16=−6(5 \times 2) + (9 \times 0) + (4 \times 0) + (8 \times (-2)) = 10 + 0 + 0 - 16 = -6

The gradient is −6, so increasing the middle weight would lower the loss. That makes sense: the bottom-right output is too low, and raising this weight raises it by 8 for every unit, more than it raises the too-high top-left output, by 5.

All nine

Every weight works the same way: add up (pixel × GG) over all positions, using the pixel that weight sat on at each one.

FIG 7.2 ▸ GRADIENTS FOR THE WEIGHTS LOSS = 2

THE KERNEL · 3×3, 9 WEIGHTS

PICK A WEIGHT

GRADIENT FOR EACH WEIGHT · 3×3

The kernel fits on the 4×4 input in four positions, so the input is drawn four times below, once per position. The same nine weights are used at every position. Pick a weight, and each position shows the pixel it sat on and what that adds to its gradient.

TOP-LEFT POSITION

y = 28 · TARGET 27 · G = 2

ADDS 5 × 2 = 10

TOP-RIGHT POSITION

y = 16 · TARGET 16 · G = 0

ADDS 9 × 0 = 0

BOTTOM-LEFT POSITION

y = 28 · TARGET 28 · G = 0

ADDS 4 × 0 = 0

BOTTOM-RIGHT POSITION

y = 16 · TARGET 17 · G = −2

ADDS 8 × (−2) = −16

▸ GRADIENT FOR THE PICKED WEIGHT = (5 × 2) + (9 × 0) + (4 × 0) + (8 × (−2)) = −6

Each copy of the input shows the 3×3 kernel at one position: the outlined squares are the nine pixels it covers, with the weight on each written small underneath. The solid square is the pixel the picked weight sat on. Red cells are above zero, blue below.

A 3×3 kernel fits on the 4×4 image in four positions, so figure 7.2 draws the image four times, once per position, with the kernel outlined on it and each weight written under the pixel it sits on. Pick any weight. In each copy, the pixel that weight sat on is filled in, and underneath is what that position adds to the weight’s gradient. The line at the bottom adds up the four. The full gradient, one number per weight, is

[−8−10−2−4−62−6−80]\begin{bmatrix} -8 & -10 & -2 \\ -4 & -6 & 2 \\ -6 & -8 & 0 \end{bmatrix}

It has the same shape as the kernel, 3×3, because there’s one gradient for each weight.

Why sharing matters

Every weight of a convolution is used at every position, so its gradient collects a contribution from every position. On the 32×32 duck that’s 900 contributions per weight. Each position says how the weight should change to fix that position’s output, and the gradient adds up all those votes. That’s why a learned kernel ends up finding a pattern that’s useful everywhere in the image, not at one place: it was trained by all of them at once.

Knowledge check ▸ 4 questions

Before you move on.

Answer every question correctly to unlock the next module. A wrong answer gets a hint, and you can try again as many times as you like.

  1. 1A weight was used at four positions. It sat on pixels 3, 1, 2 and 4, and those outputs’ gradients G were 1, 0, −1 and 2. What is the weight’s gradient?

  2. 2In the module’s 4×4 example, what is the gradient for the kernel’s top-right weight?

  3. 3A 3×3 kernel runs over a 32×32 image with no padding. How many contributions does each weight’s gradient add up?

  4. 4Why does a convolution weight’s gradient add up contributions from every position?

0 of 4 answered correctly.

🔒 Next module: Gradients for the input