.. _crash_course_autograd: Step 3: Automatic differentiation with autograd =============================================== In this step, you learn how to use the MXNet ``autograd`` package to perform gradient calculations by automatically calculating derivatives. This is helpful because it will help you save time and effort. You train models to get better as a function of experience. Usually, getting better means minimizing a loss function. To achieve this goal, you often iteratively compute the gradient of the loss with respect to weights and then update the weights accordingly. Gradient calculations are straightforward through a chain rule. However, for complex models, working this out manually is challenging. The ``autograd`` package helps you by automatically calculating derivatives. Basic use --------- To get started, import the ``autograd`` package as in the following code. .. code:: python from mxnet import np, npx from mxnet import autograd npx.set_np() As an example, you could differentiate a function :math:`f(x) = 2 x^2` with respect to parameter :math:`x`. You can start by assigning an initial value of :math:`x`, as follows: .. code:: python x = np.array([[1, 2], [3, 4]]) x .. parsed-literal:: :class: output array([[1., 2.], [3., 4.]]) After you compute the gradient of :math:`f(x)` with respect to :math:`x`, you need a place to store it. In MXNet, you can tell an ndarray that you plan to store a gradient by invoking its ``attach_grad`` method, shown in the following example. .. code:: python x.attach_grad() Next, define the function :math:`y=f(x)`. To let MXNet store :math:`y`, so that you can compute gradients later, use the following code to put the definition inside an ``autograd.record()`` scope. .. code:: python with autograd.record(): y = 2 * x * x You can invoke back propagation (backprop) by calling ``y.backward()``. When :math:`y` has more than one entry, ``y.backward()`` is equivalent to ``y.sum().backward()``. .. code:: python y.backward() Next, verify whether this is the expected output. Note that :math:`y=2x^2` and :math:`\frac{dy}{dx} = 4x`, which should be ``[[4, 8],[12, 16]]``. Check the automatically computed results. .. code:: python x.grad .. parsed-literal:: :class: output array([[ 4., 8.], [12., 16.]]) Using Python control flows -------------------------- Sometimes you want to write dynamic programs where the execution depends on real-time values. MXNet records the execution trace and computes the gradient as well. Consider the following function ``f`` in the following example code. The function doubles the inputs until its ``norm`` reaches 1000. Then it selects one element depending on the sum of its elements. .. code:: python def f(a): b = a * 2 while np.abs(b).sum() < 1000: b = b * 2 if b.sum() >= 0: c = b[0] else: c = b[1] return c In this example, you record the trace and feed in a random value. .. code:: python a = np.random.uniform(size=2) a.attach_grad() with autograd.record(): c = f(a) c.backward() You can see that ``b`` is a linear function of ``a``, and ``c`` is chosen from ``b``. The gradient with respect to ``a`` be will be either ``[c/a[0], 0]`` or ``[0, c/a[1]]``, depending on which element from ``b`` is picked. You see the results of this example with this code: .. code:: python a.grad == c/a .. parsed-literal:: :class: output array([ True, False]) Next Steps ---------- After you have used ``autograd``, learn about training a neural network. See :ref:`crash_course_train`.