Ch 8 ▸ Upsampling and transposed convolution ▸ Module 2/4
Transposed convolution.
🔒 This module is locked
It builds on Making maps bigger. Pass that module’s knowledge check to unlock it, or skip ahead if you already know the material.
Chapter 7 ended with an operation that turned a small map into a bigger one. Going backward through a convolution, each output’s gradient was multiplied by the whole kernel, and that 3×3 stamp was added onto the window the output had read. Four gradients became sixteen values.
Use that operation as a layer and you get a transposed convolution: each input value is multiplied by the whole kernel, and the resulting k×k stamp is added onto the output. Input puts its stamp with its top-left corner at , where is the stride. Where stamps overlap, they add. Like a convolution’s, its kernel weights are learned in training, so unlike nearest neighbor and bilinear it can learn how each value should be spread out.
By hand
Take a 2×2 input and a 3×3 kernel of ones, at stride 2:
The top-left value, 1, stamps 1 × the kernel, a 3×3 block of 1s, at corner (0, 0). The top-right value, 2, stamps a block of 2s at corner (0, 2), two columns over. The bottom row’s stamps land two rows down, at (2, 0) and (2, 2). The stamps are 3 wide but only 2 apart, so neighbors overlap by one row or column, and there the values add:
Column 2 is covered by both a left and a right stamp, and row 2 by both a top and a bottom stamp. The middle, (2, 2), is covered by all four: 1 + 2 + 3 + 4 = 10.
INPUT · 2×2
KERNEL · 3×3
CLICK A WEIGHT TO CHANGE IT
OUTPUT · 5×5 = (2 − 1) × 2 + 3
▸ PRESS STEP OR PLAY. EACH INPUT VALUE STAMPS ITSELF × THE KERNEL ONTO THE OUTPUT, 2 CELLS FURTHER ALONG THAN THE LAST.
Step through figure 8.2 to watch the four stamps land. Click a weight to change it, and every stamp changes the same way, because every input value uses the same kernel. That’s weight sharing again, as in a convolution. Then try other settings:
- At stride 1, the stamps overlap heavily, and the output grows by only .
- With a 2×2 kernel at stride 2, the stamps tile the output exactly. Each output is one input value times one weight.
- With a 2×2 kernel at stride 3, the stride is bigger than the kernel. The stamps leave gaps, and the outputs in the gaps get nothing at all.
Output size
The last stamp’s corner lands at , and the stamp reaches further. So without padding, the output size is
In the example, .
Padding in a transposed convolution works in reverse too. Instead of adding rings of zeros around the input, it crops rows and columns off every side of the output. With padding:
Stride works in reverse as well. In a convolution, stride 2 roughly halves the size; here it roughly doubles it. A common choice for exact doubling is a 4×4 kernel at stride 2 with padding 1: a 16×16 map becomes , so 32×32. Another is a 2×2 kernel at stride 2 with no padding: .
Not every setting doubles exactly. A 3×3 kernel at stride 2 with padding 1 turns 16 into , one short. Libraries have an extra setting, called output padding, that adds the missing row and column on one side. The next module shows why the size can come out one short.
Knowledge check ▸ 5 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.
1In the module’s worked example (input [[1, 2], [3, 4]], 3×3 kernel of ones, stride 2), what is output (2, 0): row 2, column 0?
2A transposed convolution with a 4×4 kernel, stride 2 and padding 1 runs on an 8×8 map. What size is the output?
3A transposed convolution with a 3×3 kernel at stride 1 and no padding runs on an 8×8 map. What size is the output?
4In figure 8.2, set the kernel to 2×2 and the stride to 3. After all four stamps, how many of the output cells got no stamp at all?
5How is a transposed convolution different from nearest neighbor or bilinear upsampling?