Convolutional Neural Networks
Time limit: 2 hours 30 minutes Total marks: 60 Instructions: Answer ALL three questions. Show full derivations; state assumptions. Partial credit for correct reasoning.
Question 1 — Spatial Arithmetic, Receptive Fields & Compute Budget (20 marks)
A feed-forward CNN backbone processes RGB inputs of size . The stack is:
| Layer | Type | Kernel | Stride | Padding | Dilation | Out channels |
|---|---|---|---|---|---|---|
| L1 | Conv | 2 | 3 | 1 | 64 | |
| L2 | MaxPool | 2 | 1 | 1 | 64 | |
| L3 | Conv | 1 | 2 | 2 | 128 | |
| L4 | Conv | 1 | 1 | 1 | 128 |
(a) Using the general spatial-output formula, derive the height/width of the feature map after each layer L1–L4. State the formula you use, including the dilation term. (6)
(b) For a convolution the effective kernel size under dilation is . Prove, by unrolling the recurrence for the receptive-field size and jump , that then compute the receptive field (in input pixels) of a single unit at the output of L4. (7)
(c) Count the number of multiply–accumulate operations (MACs) for layer L3 only, treating the dilated conv as a standard conv over its output spatial grid. Show your working: MACs (output positions) (output channels) (kernel elements) (input channels). (4)
(d) Explain in 2–3 sentences why replacing L3's single dilated by two stacked non-dilated convs changes both parameter count and receptive-field growth. (3)
Question 2 — Residual Learning: Gradient Flow Proof + Code (22 marks)
Consider a residual block and a plain block .
(a) For a stack of residual blocks , prove that and hence derive the gradient of a loss w.r.t. : Explain precisely why the additive "" term mitigates vanishing gradients. (8)
(b) A "bottleneck" residual block for ResNet-50 uses, on a -channel input at spatial size : a conv reducing to , a conv keeping , and a conv expanding back to . Derive the total parameter count (weights only, ignore bias/BN) as a function of , and compare it to a "basic" block of two convs each keeping channels. For , give both numbers. (6)
(c) Write a PyTorch nn.Module implementing the bottleneck block with a projection shortcut used when input/output channels differ or stride . Include BatchNorm and ReLU in the standard ResNet ordering, and ensure the addition is followed by the final activation. (8)
Question 3 — Detection/Segmentation Design + IoU Physics-of-Sampling (18 marks)
(a) Two axis-aligned bounding boxes are given in corner format: Compute the Intersection-over-Union (IoU). Show intersection area, union area, and the final value as a fraction and a decimal to 3 d.p. (5)
(b) Contrast YOLO (single-shot, grid regression) with a two-stage R-CNN family detector along THREE axes: (i) how region proposals arise, (ii) speed/accuracy trade-off, (iii) how each handles multiple objects per spatial location. Then state, with justification, which you would choose for a 30 FPS embedded drone. (6)
(c) In U-Net, downsampling loses spatial resolution. Explain the mechanism of skip connections between the contracting and expanding paths, and why concatenation (as in U-Net) differs functionally from addition (as in ResNet). Give one reason data augmentation (e.g. elastic deformation) is especially important for biomedical segmentation. (4)
(d) A segmentation network outputs logits; you use a combined loss . State the Dice coefficient formula for predicted mask and ground truth , and explain in one sentence why Dice is preferred over pixel accuracy for class-imbalanced masks. (3)
Answer keyMark scheme & solutions
Question 1
(a) Formula (per spatial dim), effective kernel : (1 mark for correct formula incl. dilation.)
- L1: : . → 112×112×64. (1.5)
- L2: : . → 56×56×64. (1.5)
- L3: ; : . → 56×56×128. (1)
- L4: : . → 56×56×128. (1)
(b) Derivation (recurrence unrolling, 4 marks). Initialize , . A layer with effective kernel and stride : each output unit sees consecutive units of the previous map, and adjacent previous units are spaced by the previous jump in input pixels. Extra span added , giving
Computation (3 marks). Jumps: ; ; ; ; . RF (: L1=7, L2=3, L3=5, L4=3):
- input pixels. (final 1 mark)
(c) L3 output grid positions; out ch ; kernel elems ; in ch . (2 setup, 2 result)
(d) Two stacked non-dilated convs have each → RF grows (contiguously sampled), vs one dilated conv → RF grows but with gaps (sparse/gridding sampling). Parameters: two layers cost ≈ double one dilated layer, but give denser coverage and extra nonlinearity. (3: RF density + param comment)
Question 2
(a) (5 marks derivation, 3 explanation.) By induction on the recurrence : summing telescopically from to , Differentiate via chain rule: Why: the constant "1" provides an identity (shortcut) path so propagates undiminished to any earlier layer even if the -Jacobian product is near zero; the gradient cannot fully vanish because the bracket is , never a product of many small factors.
(b) (6 marks.) Bottleneck weights (kernel²·Cin·Cout):
- :
- :
- :
Total .
Basic block (two , C→C): . For : bottleneck ; basic . Bottleneck ≈ 17× cheaper. (3 derivation, 3 numbers)
(c) (8 marks: correct convs 3, BN/ReLU order 2, shortcut logic 2, final add+ReLU 1.)
import torch.nn as nn
class Bottleneck(nn.Module):
expansion = 4
def __init__(self, in_ch, mid_ch, stride=1):
super().__init__()
out_ch = mid_ch * self.expansion
self.conv1 = nn.Conv2d(in_ch, mid_ch, 1, bias=False)
self.bn1 = nn.BatchNorm2d(mid_ch)
self.conv2 = nn.Conv2d(mid_ch, mid_ch, 3, stride=stride,
padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(mid_ch)
self.conv3 = nn.Conv2d(mid_ch, out_ch, 1, bias=False)
self.bn3 = nn.BatchNorm2d(out_ch)
self.relu = nn.ReLU(inplace=True)
self.shortcut = nn.Sequential()
if stride != 1 or in_ch != out_ch:
self.shortcut = nn.Sequential(
nn.Conv2d(in_ch, out_ch, 1, stride=stride, bias=False),
nn.BatchNorm2d(out_ch))
def forward(self, x):
out = self.relu(self.bn1(self.conv1(x)))
out = self.relu(self.bn2(self.conv2(out)))
out = self.bn3(self.conv3(out))
out += self.shortcut(x) # add BEFORE final activation
return self.relu(out)Question 3
(a) (5 marks.) Intersection corners: , width ; , height . Intersection . Areas: ; . Union .
(b) (6 marks, 2 per axis + choice.) (i) YOLO: no separate proposal stage—dense grid cells directly regress boxes+class. R-CNN: a Region Proposal Network / selective search generates candidate ROIs, then a classifier refines them. (ii) YOLO is faster (single forward pass, real-time) but historically lower localization accuracy on small/overlapping objects; two-stage R-CNN is slower but more accurate. (iii) YOLO uses multiple anchors/bounding-box predictors per cell; R-CNN handles many objects via many proposals + per-ROI classification (NMS to dedup). Choice: YOLO (or SSD) for the 30 FPS drone — single-shot meets the real-time/compute budget of embedded hardware.
(c) (4 marks.) Skip connections copy high-resolution feature maps from the contracting path and concatenate them onto the upsampled decoder features, restoring fine spatial detail lost during pooling and giving the decoder both semantic (deep) and localization (shallow) information. Concatenation preserves both feature sets as separate channels for the next conv to combine, whereas ResNet addition fuses them into one tensor (requires matching channel count, learns a residual). Elastic deformation matters because biomedical datasets are small and cells/tissue vary in shape; realistic deformations teach invariance and expand effective training data.
(d) (3 marks.) (soft: ). Preferred because it directly measures foreground overlap and is insensitive to the vast correct-background majority, so it does not get inflated by class imbalance the way pixel accuracy does.
[
{"claim":"L4 output spatial size is 56","code":"def O(I,P,k,s,d):\n keff=d*(k-1)+1\n return (I+2*P-keff)//s+1\nL1=O(224,3,7,2,1); L2=O(L1,1,3,2,1); L3=O(L2,2,3,1,2); L4=O(L3,1,3,1,1)\nresult = (L1==112 and L