Level 3 — ProductionNeural Network Fundamentals

Neural Network Fundamentals

45 minutes60 marksprintable — key stays hidden on paper

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 x=[1,2]T\mathbf{x}=[1, 2]^T, hidden weights W[1]=[0.50.50.30.8]W^{[1]}=\begin{bmatrix}0.5 & -0.5\\ 0.3 & 0.8\end{bmatrix}, hidden bias b[1]=[0,1]T\mathbf{b}^{[1]}=[0, 1]^T, output weights W[2]=[1,2]W^{[2]}=[1, -2], output bias b[2]=0.5b^{[2]}=0.5. Hidden activation is tanh\tanh; output is linear.

(a) Compute the pre-activations z[1]=W[1]x+b[1]\mathbf{z}^{[1]}=W^{[1]}\mathbf{x}+\mathbf{b}^{[1]}. (3) (b) Compute hidden activations a[1]=tanh(z[1])\mathbf{a}^{[1]}=\tanh(\mathbf{z}^{[1]}) (to 4 d.p.). (3) (c) Compute the network output y^\hat{y}. (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 σ(z)=11+ez\sigma(z)=\frac{1}{1+e^{-z}} and show it equals σ(z)(1σ(z))\sigma(z)(1-\sigma(z)). (3) (b) Give the definition and derivative of Leaky ReLU with slope α\alpha. (2) (c) Explain, from the derivative shapes, why tanh\tanh/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 z\mathbf{z}, softmax pi=ezijezjp_i=\frac{e^{z_i}}{\sum_j e^{z_j}}, and cross-entropy loss L=iyilogpiL=-\sum_i y_i \log p_i with one-hot label y\mathbf{y}.

(a) Derive pizk\frac{\partial p_i}{\partial z_k} for both cases i=ki=k and iki\neq k. (4) (b) Using (a), derive that Lzk=pkyk\frac{\partial L}{\partial z_k}=p_k-y_k. (5) (c) For logits z=[2,1,0]\mathbf{z}=[2, 1, 0] with true class 00, compute p\mathbf{p} and the gradient Lz\frac{\partial L}{\partial \mathbf{z}} (3 d.p.). (3)


Question 4 — Backpropagation from scratch (12 marks)

For a 2-layer MLP: z[1]=W[1]x+b[1]\mathbf{z}^{[1]}=W^{[1]}\mathbf{x}+\mathbf{b}^{[1]}, a[1]=g(z[1])\mathbf{a}^{[1]}=g(\mathbf{z}^{[1]}), z[2]=W[2]a[1]+b[2]\mathbf{z}^{[2]}=W^{[2]}\mathbf{a}^{[1]}+\mathbf{b}^{[2]}, y^=softmax(z[2])\hat{\mathbf{y}}=\text{softmax}(\mathbf{z}^{[2]}), loss = cross-entropy.

(a) Write the four gradient expressions LW[2],Lb[2],LW[1],Lb[1]\frac{\partial L}{\partial W^{[2]}}, \frac{\partial L}{\partial \mathbf{b}^{[2]}}, \frac{\partial L}{\partial W^{[1]}}, \frac{\partial L}{\partial \mathbf{b}^{[1]}} in terms of δ[2]=y^y\delta^{[2]}=\hat{\mathbf{y}}-\mathbf{y}. (6) (b) Write NumPy code (from memory) implementing this backward pass for a batch of NN examples (rows). Include the 1/N1/N averaging. (6)


Question 5 — Initialization & gradient scaling (10 marks)

(a) State the Xavier (Glorot) and He initialization variances in terms of ninn_{in} (and noutn_{out} where relevant), and say which activation each targets. (4) (b) Explain the variance-preservation argument: why we want Var(a[l])Var(a[l1])\text{Var}(a^{[l]})\approx\text{Var}(a^{[l-1]}) across layers. (3) (c) A deep net with sigmoid activations and weights initialized N(0,1)\mathcal{N}(0,1) 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 f(x)=σ(wx+b)f(x)=\sigma(wx+b) with x=1,w=2,b=1x=1, w=2, b=-1.

(a) Draw/describe the computational graph (nodes for wxwx, +b+b, σ\sigma). (2) (b) Using reverse-mode autograd, compute fw\frac{\partial f}{\partial w} numerically (4 d.p.). (4)

Answer keyMark scheme & solutions

Question 1 (10)

(a) z[1]=W[1]x+b[1]\mathbf{z}^{[1]}=W^{[1]}\mathbf{x}+\mathbf{b}^{[1]}. Row1: 0.5(1)+(0.5)(2)+0=0.51=0.50.5(1)+(-0.5)(2)+0 = 0.5-1 = -0.5. Row2: 0.3(1)+0.8(2)+1=0.3+1.6+1=2.90.3(1)+0.8(2)+1 = 0.3+1.6+1 = 2.9. z[1]=[0.5,2.9]T\mathbf{z}^{[1]}=[-0.5, 2.9]^T. (3: 1 setup, 2 for both values)

(b) tanh(0.5)=0.4621\tanh(-0.5)=-0.4621, tanh(2.9)=0.9940\tanh(2.9)=0.9940. a[1]=[0.4621,0.9940]T\mathbf{a}^{[1]}=[-0.4621, 0.9940]^T. (3)

(c) y^=W[2]a[1]+b[2]=1(0.4621)+(2)(0.9940)+0.5\hat{y}=W^{[2]}\mathbf{a}^{[1]}+b^{[2]} = 1(-0.4621)+(-2)(0.9940)+0.5 =0.46211.9880+0.5=1.9501= -0.4621 - 1.9880 + 0.5 = -1.9501. (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) σ(z)=(1+ez)1\sigma(z)=(1+e^{-z})^{-1}. σ(z)=(1+ez)2(ez)=ez(1+ez)2\sigma'(z)= -(1+e^{-z})^{-2}\cdot(-e^{-z}) = \frac{e^{-z}}{(1+e^{-z})^2}. Write ez(1+ez)2=11+ezez1+ez=σ(z)(1σ(z))\frac{e^{-z}}{(1+e^{-z})^2} = \frac{1}{1+e^{-z}}\cdot\frac{e^{-z}}{1+e^{-z}} = \sigma(z)(1-\sigma(z)), since ez1+ez=1σ(z)\frac{e^{-z}}{1+e^{-z}} = 1-\sigma(z). (3)

(b) LReLU(z)=z\text{LReLU}(z)=z if z>0z>0 else αz\alpha z. Derivative =1=1 if z>0z>0, =α=\alpha if z<0z<0. (2)

(c) Sigmoid/tanh derivatives are bounded (0.25\le 0.25 for sigmoid, 1\le 1 for tanh) and 0\to 0 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: GELU(z)=zΦ(z)\text{GELU}(z)=z\cdot\Phi(z) where Φ\Phi is the standard normal CDF, i.e. z12(1+erf(z/2))z\cdot\frac{1}{2}\left(1+\text{erf}(z/\sqrt2)\right). Advantage: smooth/non-monotonic, non-zero gradient for small negatives (no dead-ReLU units), often better performance. (2)

Question 3 (12)

(a) With pi=ezi/Sp_i=e^{z_i}/S, S=jezjS=\sum_j e^{z_j}. i=ki=k: pizk=pi(1pi)\frac{\partial p_i}{\partial z_k}=p_i(1-p_i). iki\neq k: pizk=pipk\frac{\partial p_i}{\partial z_k}=-p_i p_k. Compactly pizk=pi(δikpk)\frac{\partial p_i}{\partial z_k}=p_i(\delta_{ik}-p_k). (4)

(b) Lzk=iyi1pipizk=iyi1pipi(δikpk)=iyi(δikpk)\frac{\partial L}{\partial z_k}=-\sum_i y_i\frac{1}{p_i}\frac{\partial p_i}{\partial z_k} = -\sum_i y_i\frac{1}{p_i}p_i(\delta_{ik}-p_k) = -\sum_i y_i(\delta_{ik}-p_k) =yk+pkiyi=pkyk= -y_k + p_k\sum_i y_i = p_k - y_k (since iyi=1\sum_i y_i=1). (5)

(c) z=[2,1,0]\mathbf{z}=[2,1,0]: e2=7.389,e1=2.718,e0=1e^2=7.389, e^1=2.718, e^0=1, S=11.107S=11.107. p=[0.6652,0.2447,0.0900]\mathbf{p}=[0.6652, 0.2447, 0.0900]. True class 0 ⇒ y=[1,0,0]\mathbf{y}=[1,0,0]; gradient =py=[0.3348,0.2447,0.0900]=\mathbf{p}-\mathbf{y}=[-0.3348, 0.2447, 0.0900]. (3)

Question 4 (12)

(a) δ[2]=y^y\delta^{[2]}=\hat{\mathbf{y}}-\mathbf{y} LW[2]=δ[2](a[1])T\frac{\partial L}{\partial W^{[2]}}=\delta^{[2]}(\mathbf{a}^{[1]})^T Lb[2]=δ[2]\frac{\partial L}{\partial \mathbf{b}^{[2]}}=\delta^{[2]} δ[1]=(W[2]Tδ[2])g(z[1])\delta^{[1]}=(W^{[2]T}\delta^{[2]})\odot g'(\mathbf{z}^{[1]}) LW[1]=δ[1]xT\frac{\partial L}{\partial W^{[1]}}=\delta^{[1]}\mathbf{x}^T Lb[1]=δ[1]\frac{\partial L}{\partial \mathbf{b}^{[1]}}=\delta^{[1]} (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: Var(W)=2nin+nout\text{Var}(W)=\frac{2}{n_{in}+n_{out}} (or 1nin\frac1{n_{in}}), targets tanh/sigmoid. He: Var(W)=2nin\text{Var}(W)=\frac{2}{n_{in}}, 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 Var(a[l])Var(a[l1])\text{Var}(a^{[l]})\approx\text{Var}(a^{[l-1]}) keeps forward activations and backward gradients at stable scale so deep nets train. (3)

(c) With N(0,1)\mathcal{N}(0,1) and large ninn_{in}, pre-activation variance nin\approx n_{in} grows → large z|z| (exploding pre-activations); large z|z| pushes sigmoid into saturation where σ0\sigma'\to0, so backprop gradients vanish. (3)

Question 6 (6)

(a) Nodes: u=wxu=wx (inputs w,xw,x) → v=u+bv=u+b (input bb) → f=σ(v)f=\sigma(v). (2)

(b) Forward: u=2u=2, v=1v=1, f=σ(1)=0.7311f=\sigma(1)=0.7311. Backward: fv=f(1f)=0.73110.2689=0.1966\frac{\partial f}{\partial v}=f(1-f)=0.7311\cdot0.2689=0.1966; vu=1\frac{\partial v}{\partial u}=1; uw=x=1\frac{\partial u}{\partial w}=x=1. fw=0.196611=0.1966\frac{\partial f}{\partial w}=0.1966\cdot1\cdot1=0.1966. (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"}
]