CGO 05-1: Automatic Differentiation
Download the Jupyter Notebook file from here.
CGO 05-1: Automatic Differentiation
This notebook uses pytorch. Instructions for installing can be found at https://pytorch.org/
import torch
from torch import nn
import math
Function
We wish to model the following function:
\[f(x) = \frac{ x_1 x_2 \sin(x_3) + e^{x_1 x_2} }{ x_3 }\]We will compute the gradient at the point $x = [x_1,\,x_2,\,x_3]^\intercal = [1,\,2,\,\pi/2]^\intercal$
# Create the input values
x = torch.Tensor( (1, 2, math.pi/2) )
# We have to use requires_grad=True for the visualization
x.requires_grad=True
# Call the function
def f( x ):
return (x[0]*x[1]*torch.sin(x[2])+torch.exp(x[0]*x[1])) / x[2]
y = f(x)
# Calculate the gradient in reverse mode
y.backward()
print( x.grad )
Visualization of the Computational Graph
We can visualize the computational graph using torchviz.
pip install torchviz
from torchviz import make_dot, make_dot_from_trace
make_dot( y )
Computing the Hessian
We can easily compute gradients of gradients using the automatic differentiation system. This will allow us to approximate arbitrary order derivatives of arbitrary functions.
As a simple example we compute the Hessian of $f(x) = x_1^2 + 4 x_2^2$ with $x=[1,1]^\intercal$.
# Trivial function
x = torch.Tensor( (1,1) )
def f(x):
return x[0]**2 + 4*x[1]**2
# We have to use requires_grad=True for the visualization
x.requires_grad=True
# Jacobian
[g] = torch.autograd.grad( f(x), (x,), create_graph=True )
print( 'g:', g )
# Hessian
h = torch.zeros( (g.numel(),g.numel()) )
for i in range(g.numel()):
[h[i,:]] = torch.autograd.grad( g[i], (x,), create_graph=True )
print( 'h:', h )