ContentsFoundations to FrontierBezhig

ai-lab/m01_autograd/gradcheck.py

All lab code. Download this file.

"""AI01 lab, step 6: check backprop against finite differences. You write both functions.

A gradient check is an autograd engineer's unit test: nudge one input a tiny
amount, see how much the output moves, and compare that slope with the grad
that backward() computed.
"""
from engine import Value


def numerical_grad(f, xs, h=1e-6):
    """Estimate every partial derivative of f at the point xs.

    f   a function that takes a list of floats and returns a float.
    xs  the point, a list of floats. Must be left unchanged when you return.
    h   the nudge size.

    Return a list of floats [df/dx0, df/dx1, ...]. Estimate each entry with the
    central difference
        (f(x with x_i + h) - f(x with x_i - h)) / (2h),
    holding every other coordinate fixed. Holding the rest fixed is exactly
    what "partial derivative" means.
    """
    raise NotImplementedError("Step 6: numerical_grad")


def max_grad_error(f, xs, h=1e-6):
    """Largest gap between backprop and numerical_grad for one function.

    f   a function that takes a list of Values and returns one Value, built
        with your engine.
    xs  the point, a list of floats.

    1. Make fresh Values from xs, call f on them, call backward() on the
       result, and read each input Value's grad.
    2. Call numerical_grad on the float version of f, passing h through. The
       float version is a function that takes a list of floats, wraps each
       float in a Value, calls f, and returns the output's .data.
    3. Return the largest absolute difference between the two lists.
    """
    raise NotImplementedError("Step 6: max_grad_error")