Have a go at it. The editor and the docs panel are open, and your code is saved as you type. Running it needs a free account — you’ll come back to exactly what you wrote.
Gradient Checking
You wrote a gradient by hand. Is it right? A wrong gradient does not crash — it trains slowly, or plateaus, or quietly optimises the wrong thing. This is the single hardest bug in the curriculum to find by reading.
The check: compare your analytic gradient against a numerical one, component by component.
where is all zeros except a 1 in position i — nudge one weight, hold the rest still, see how the loss responds. Do that for every i and you have rebuilt the whole gradient from function evaluations alone.
Then compare with the relative error, not the absolute one:
Relative, because an absolute difference of 0.01 is catastrophic on gradients of size 0.001 and irrelevant on gradients of size 10,000. Below about 10−7 your gradient is right; above 10−4 it is wrong; in between, look harder.
This problem uses , whose gradient is 2w — small enough to check by hand, which is the point of practising on it.
w = [1, 2] analytic 2w = [2, 4] numerical, eps=1e-5: [2.0000, 4.0000] relative error ~ 1e-11 -> correct
Your task:
Implement numerical_gradient(w, eps) returning the numerical gradient of as an array the same shape as w.
Nudge one component at a time. Copy w before modifying it, or you will be differentiating a moving target.
Example Tests
The gradient of sum of squares is twice the weights
Input: {"w":[1,2],"eps":0.00001}
Expected: [2,4]
At the origin every partial derivative is zero
Input: {"w":[0,0,0],"eps":0.00001}
Expected: [0,0,0]
Negative weights give negative partials
Input: {"w":[-3,0.5],"eps":0.00001}
Expected: [-6,1]
import numpy as np
def numerical_gradient(w, eps):
"""
Central-difference gradient of L(w) = sum(w**2).
Args:
w: parameter vector, shape (n,)
eps: nudge size
Returns:
array of shape (n,), the numerical gradient
"""
# YOUR CODE HERE
pass