Derivatives & Graphs
title: Differentiation in PyTorch author: Juma Shafara date: "2023-09" date-modified: "2024-07-30" description: In this lab, you will learn the basics of tensor operations on 2D tensors. keywords: []

Objective
- How to perform differentiation in pytorch.
Table of Contents
In this lab, you will learn the basics of differentiation.
Estimated Time Needed: 25 min
Preparation
The following are the libraries we are going to use for this lab.
Derivatives
Let us create the tensor x and set the parameter requires_grad to true because you are going to take the derivative of the tensor.
Then let us create a tensor according to the equation \(y=x^2\).
Then let us take the derivative with respect x at x = 2
The preceding lines perform the following operation:
\(\frac{\mathrm{dy(x)}}{\mathrm{dx}}=2x\)
\(\frac{\mathrm{dy(x=2)}}{\mathrm{dx}}=2(2)=4\)
Let us try to calculate the derivative for a more complicated function.
The function is in the following form: \(y=x^{2}+2x+1\)
The derivative is given by:
\(\frac{\mathrm{dy(x)}}{\mathrm{dx}}=2x+2\)
\(\frac{\mathrm{dy(x=2)}}{\mathrm{dx}}=2(2)+2=6\)
Practice
Determine the derivative of \(y = 2x^3+x\) at \(x=1\)
Double-click here for the solution.
We can implement our own custom autograd Functions by subclassing torch.autograd.Function and implementing the forward and backward passes which operate on Tensors
class SQ(torch.autograd.Function):
@staticmethod
def forward(ctx,i):
"""
In the forward pass we receive a Tensor containing the input and return
a Tensor containing the output. ctx is a context object that can be used
to stash information for backward computation. You can cache arbitrary
objects for use in the backward pass using the ctx.save_for_backward method.
"""
result=i**2
ctx.save_for_backward(i)
return result
@staticmethod
def backward(ctx, grad_output):
"""
In the backward pass we receive a Tensor containing the gradient of the loss
with respect to the output, and we need to compute the gradient of the loss
with respect to the input.
"""
i, = ctx.saved_tensors
grad_output = 2*i
return grad_output
We can apply it the function
Partial Derivatives
We can also calculate Partial Derivatives. Consider the function: \(f(u,v)=vu+u^{2}\)
Let us create u tensor, v tensor and f tensor
This is equivalent to the following:
\(f(u=1,v=2)=(2)(1)+1^{2}=3\)
Now let us take the derivative with respect to u:
the expression is given by:
\(\frac{\mathrm{\partial f(u,v)}}{\partial {u}}=v+2u\)
\(\frac{\mathrm{\partial f(u=1,v=2)}}{\partial {u}}=2+2(1)=4\)
Now, take the derivative with respect to v:
The equation is given by:
\(\frac{\mathrm{\partial f(u,v)}}{\partial {v}}=u\)
\(\frac{\mathrm{\partial f(u=1,v=2)}}{\partial {v}}=1\)
Calculate the derivative with respect to a function with multiple values as follows. You use the sum trick to produce a scalar valued function and then take the gradient:
We can plot the function and its derivative
The orange line is the slope of the blue line at the intersection point, which is the derivative of the blue line.
The method detach() excludes further tracking of operations in the graph, and therefore the subgraph will not record operations. This allows us to then convert the tensor to a numpy array. To understand the sum operation Click Here
The relu activation function is an essential function in neural networks. We can take the derivative as follows:
# Take the derivative of Relu with respect to multiple value. Plot out the function and its derivative
x = torch.linspace(-10, 10, 1000, requires_grad = True)
Y = torch.relu(x)
y = Y.sum()
y.backward()
plt.plot(x.detach().numpy(), Y.detach().numpy(), label = 'function')
plt.plot(x.detach().numpy(), x.grad.detach().numpy(), label = 'derivative')
plt.xlabel('x')
plt.legend()
plt.show()
Practice
Try to determine partial derivative \(u\) of the following function where \(u=2\) and \(v=1\): $ f=uv+(uv)^2$