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.
from mxnet import np, npx
from mxnet import autograd
npx.set_np()
As an example, you could differentiate a function \(f(x) = 2 x^2\) with respect to parameter \(x\). You can start by assigning an initial value of \(x\), as follows:
x = np.array([[1, 2], [3, 4]])
x
array([[1., 2.],
[3., 4.]])
After you compute the gradient of \(f(x)\) with respect to
\(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.
x.attach_grad()
Next, define the function \(y=f(x)\). To let MXNet store \(y\),
so that you can compute gradients later, use the following code to put
the definition inside an autograd.record() scope.
with autograd.record():
y = 2 * x * x
You can invoke back propagation (backprop) by calling y.backward().
When \(y\) has more than one entry, y.backward() is equivalent
to y.sum().backward().
y.backward()
Next, verify whether this is the expected output. Note that
\(y=2x^2\) and \(\frac{dy}{dx} = 4x\), which should be
[[4, 8],[12, 16]]. Check the automatically computed results.
x.grad
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.
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.
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:
a.grad == c/a
array([ True, False])
Next Steps¶
After you have used autograd, learn about training a neural network.
See Step 4: Train the neural network.