Neural Network Fundamentals
Chapter: 3.1 Neural Network Fundamentals Level: 3 — Production (from-scratch derivations, code-from-memory, explain-out-loud) Time limit: 45 minutes Total marks: 60
Instructions: Show all derivations. Where code is asked, write clean NumPy-only pseudocode/code from memory. Use for math.
Question 1 — Forward pass + activations (10 marks)
A single hidden-layer MLP has input , hidden weights , hidden bias , output weights , output bias . Hidden activation is ; output is linear.
(a) Compute the pre-activations . (3) (b) Compute hidden activations (to 4 d.p.). (3) (c) Compute the network output . (2) (d) State one reason a bias term changes the representable function that scaling weights alone cannot. (2)
Question 2 — Activation function derivations (10 marks)
(a) Derive the derivative of the sigmoid and show it equals . (3) (b) Give the definition and derivative of Leaky ReLU with slope . (2) (c) Explain, from the derivative shapes, why /sigmoid contribute to vanishing gradients while ReLU mitigates it. (3) (d) State the GELU function (exact form) and one advantage over ReLU. (2)
Question 3 — Softmax + cross-entropy backprop (12 marks)
Consider a softmax output layer with logits , softmax , and cross-entropy loss with one-hot label .
(a) Derive for both cases and . (4) (b) Using (a), derive that . (5) (c) For logits with true class , compute and the gradient (3 d.p.). (3)
Question 4 — Backpropagation from scratch (12 marks)
For a 2-layer MLP: , , , , loss = cross-entropy.
(a) Write the four gradient expressions in terms of . (6) (b) Write NumPy code (from memory) implementing this backward pass for a batch of examples (rows). Include the averaging. (6)
Question 5 — Initialization & gradient scaling (10 marks)
(a) State the Xavier (Glorot) and He initialization variances in terms of (and where relevant), and say which activation each targets. (4) (b) Explain the variance-preservation argument: why we want across layers. (3) (c) A deep net with sigmoid activations and weights initialized suffers exploding pre-activations then saturating gradients. In one/two sentences link this to both the exploding and vanishing gradient phenomena. (3)
Question 6 — Computational graph / autograd (6 marks)
Let with .
(a) Draw/describe the computational graph (nodes for , , ). (2) (b) Using reverse-mode autograd, compute numerically (4 d.p.). (4)
Answer keyMark scheme & solutions
Question 1 (10)
(a) . Row1: . Row2: . . (3: 1 setup, 2 for both values)
(b) , . . (3)
(c) . (2)
(d) Bias shifts the activation threshold/decision boundary away from the origin; without it every hyperplane must pass through the origin, so no amount of weight scaling can translate the function. (2)
Question 2 (10)
(a) . . Write , since . (3)
(b) if else . Derivative if , if . (2)
(c) Sigmoid/tanh derivatives are bounded ( for sigmoid, for tanh) and in saturation; multiplying many such factors during backprop shrinks gradients toward zero (vanishing). ReLU derivative is exactly 1 on the active region, so gradient magnitude is preserved through many layers. (3)
(d) Exact GELU: where is the standard normal CDF, i.e. . Advantage: smooth/non-monotonic, non-zero gradient for small negatives (no dead-ReLU units), often better performance. (2)
Question 3 (12)
(a) With , . : . : . Compactly . (4)
(b) (since ). (5)
(c) : , . . True class 0 ⇒ ; gradient . (3)
Question 4 (12)
(a) (6)
(b) (row = example; caches A0=X, Z1, A1, Yhat)
def backward(X, Y, W1, b1, W2, A0, Z1, A1, Yhat, g_prime):
N = X.shape[0]
dZ2 = (Yhat - Y) / N # (N, C)
dW2 = A1.T @ dZ2 # (H, C)
db2 = dZ2.sum(axis=0) # (C,)
dA1 = dZ2 @ W2.T # (N, H)
dZ1 = dA1 * g_prime(Z1) # (N, H)
dW1 = X.T @ dZ1 # (D, H)
db1 = dZ1.sum(axis=0) # (H,)
return dW1, db1, dW2, db2(6: correct dZ2 w/ 1/N, matmul orders, summed biases)
Question 5 (10)
(a) Xavier/Glorot: (or ), targets tanh/sigmoid. He: , targets ReLU (accounts for half the units being zeroed). (4)
(b) If per-layer variance grows, signals/gradients explode; if it shrinks, they vanish. Keeping keeps forward activations and backward gradients at stable scale so deep nets train. (3)
(c) With and large , pre-activation variance grows → large (exploding pre-activations); large pushes sigmoid into saturation where , so backprop gradients vanish. (3)
Question 6 (6)
(a) Nodes: (inputs ) → (input ) → . (2)
(b) Forward: , , . Backward: ; ; . . (4)
[
{"claim":"Q1 output yhat = -1.9501","code":"import math\nz1=[-0.5,2.9]\na=[math.tanh(z1[0]),math.tanh(z1[1])]\nyhat=1*a[0]+(-2)*a[1]+0.5\nresult=abs(yhat-(-1.9501))<1e-3"},
{"claim":"Q3 softmax gradient = [-0.3348,0.2447,0.0900]","code":"import math\nz=[2,1,0]\ne=[math.exp(v) for v in z]\nS=sum(e)\np=[v/S for v in e]\ny=[1,0,0]\ng=[p[i]-y[i] for i in range(3)]\nres=[round(v,4) for v in g]\nresult=res==[-0.3348,0.2447,0.09]"},
{"claim":"Softmax-CE gradient identity dL/dz = p - y (symbolic 2-class check)","code":"z0,z1,y0,y1=symbols('z0 z1 y0 y1')\nS=exp(z0)+exp(z1)\np0=exp(z0)/S\np1=exp(z1)/S\nL=-(y0*log(p0)+y1*log(p1))\ncheck=simplify(diff(L,z0)-(p0-y0))\nresult=check==0 or simplify(check.subs({y1:1-y0}))==0"},
{"claim":"Q6 df/dw = 0.1966","code":"import math\nf=1/(1+math.exp(-1))\ndfdw=f*(1-f)*1*1\nresult=abs(dfdw-0.1966)<1e-3"}
]