The Theano Library in Python

Theano is an open-source library used for numerical computations in Python. It was mainly defined for optimizing and evaluating the matrices operation efficiently. In Theano, we can express mathematical equations in symbolic form, just like in SymPy. Theano then diligently compiles it into remarkably efficient, low-level code. This efficient code can be executed on powerful GPUs, leading to remarkable speed enhancements in complex numerical computations.

Deep learning enthusiasts and researchers found this library very helpful because it provides efficient and robust computation with the help of GPU.

Functions in Theano

In Theano, several functions help in the statistical analysis of the data. In this Answer, we will cover the essential functions of the Theano Library so that you have a firm grasp of this library. Please have a look at the below-mentioned applications of Theano.

  • Symbolic and elementwise function

  • Reduction Operations

  • Gradient computation

  • Matrix operations

  • Activation function

  • Loss Functions

  • Shared Variables

  • Random Number Generation

  • Logical and Comparison Operations

  • Shape Manipulation

  • Broadcasting

  • Indexing and Slicing

  • Conditional Expressions

  • Set Subtensor

  • Stack and Concatenate

  • L1 and L2 Regularization

Let us discuss all these applications and functionalities individually.

Symbolic and elementwise function

In Theano, instead of creating another numerical variable for the computations, we create a symbolic variable for solving the mathematical equations. Also, we can create an elementwise function that applies a specific operation to each element in an array independently.

The below code explains how to make a symbolic and element-wise function in Theano.

import theano.tensor as T
# Define symbolic variables
x = T.scalar('x')
y = T.scalar('y')
# Symbolic expression for addition
addition_expr = x + y
# Symbolic expression for elementwise sine function
a = T.vector('a')
sine_expr = T.sin(a)

Reduction operations

As the name represents, a reduction operation in Theano reduces the dimensions after applying a specific operation. The most common reduction operations are sum, mean, average, min, and max. Through this, we can quickly analyze the behavior of the data.

Reduction operations in Theano are defined below.

import theano.tensor as T
# Define a symbolic variable
x = T.matrix('x')
# Symbolic expression for computing the sum of all elements in x
sum_expr = T.sum(x)
# Symbolic expression for computing the mean of all elements in x
mean_expr = T.mean(x)
# Symbolic expression for computing the maximum value in x
max_expr = T.max(x)

Gradient computation

The gradient is finding the rate of change of one variable concerning another variable. Theano provides a function to compute derivatives. It can be helpful in deep learning, where we are required to compute the gradients in the backpropagation of a neural network. Please look at the code below and appreciate Theano and how it makes our work easy.

import theano.tensor as T
from theano import function
# Define a symbolic variable
x = T.scalar('x')
# Symbolic expression for a function: f(x) = x^2
expr = x**2
# Compute the gradient of the expression with respect to x
grad_expr = T.grad(expr, x)
# Create a function to compute the gradient
compute_gradient = function([x], grad_expr)
# Test the function
input_value = 2.0
gradient_result = compute_gradient(input_value)
print(gradient_result)

Matrix operations

Matrix operations in Theano make our work easy in preparing and computing a dataset. It enables us to define the weights of the network in the matrix. The simple operations of matrices in Theano are provided below.

import theano.tensor as T
from theano import function
# Define symbolic variables for matrices
X = T.matrix('X')
Y = T.matrix('Y')
# Symbolic expression for matrix multiplication: Z = X * Y
matrix_mult_expr = T.dot(X, Y)
# Create a function to compute matrix multiplication
compute_matrix_mult = function([X, Y], matrix_mult_expr)
# Test the function
import numpy as np
x_value = np.array([[1, 2], [3, 4]])
y_value = np.array([[5, 6], [7, 8]])
result = compute_matrix_mult(x_value, y_value)
print(result)

Activation function

We required activations function in the neural network for training the model for the best accuracy. The activation function is chosen based on the provided problem. If the problem is to classify, then sigmoid or softmax is the best option. If it is a regression task, relu provides the best results. The code below shows the syntax of how we can use these activation functions in Theano.

import theano.tensor as T
x = T.matrix('x')
# Symbolic expression for sigmoid activation function
sigmoid_expr = T.nnet.sigmoid(x)
# Symbolic expression for rectified linear unit (ReLU) activation function
relu_expr = T.nnet.relu(x)
# Symbolic expression for hyperbolic tangent (tanh) activation function
tanh_expr = T.tanh(x)
# Define a symbolic variable
# Symbolic expression for softmax function along axis 1
softmax_expr = T.nnet.softmax(x)

Loss functions

In the context of neural network models, the loss function is the uncertainty in the model while predicting. The loss function is essential for training the models. Likewise, for the activation functions choosing a loss function also requires some considerations. There are various loss functions, such as mean absolute error, mean squared error, and categorical cross-entropy loss. The below code provides the format for using the mean squared error and categorical cross-entropy loss.

import theano.tensor as T
# Define symbolic variables for predicted and target values
y_pred = T.vector('y_pred')
y_true = T.vector('y_true')
# Symbolic expression for mean squared error (MSE) loss function
mse_loss_expr = T.mean((y_pred - y_true)**2)
# Symbolic expression for categorical cross-entropy loss function
cross_entropy_loss_expr = T.nnet.categorical_crossentropy(y_pred, y_true).mean()

Shared variables

Shared variables store model parameters that need to be updated during training, such as weights and biases in neural networks. By using shared variables, you can separate the model definition from the optimization process, making it easier to apply various optimization algorithms.

import theano.tensor as T
import theano
# Define shared variable
shared_var = theano.shared(value=1.0, name='shared_var')
# Symbolic expression using the shared variable
x = T.scalar('x')
shared_expr = x * shared_var
# Update the shared variable's value
new_value = 2.0
shared_var.set_value(new_value)

Random number generation

Random number generation allows you to introduce randomness into your computations, which is particularly useful for tasks such as initializing model parameters, adding noise to data, or performing stochastic operations in some machine learning algorithms. We can specify the range in which it should generate the numbers.

import theano.tensor as T
from theano.sandbox.rng_mrg import MRG_RandomStreams
# Define a random number generator
rng = MRG_RandomStreams(seed=42)
# Symbolic expression for generating random uniform numbers between [0, 1)
random_uniform_expr = rng.uniform(size=(5, 5))
# Symbolic expression for generating random normal (Gaussian) numbers
random_normal_expr = rng.normal(size=(5, 5))

Logical and comparison operations

In Theano, logical and comparison operations are performed using the standard Python logical and comparison operators, which are overloaded for Theano symbolic variables. These operations allow you to build complex logical expressions and conditions when defining symbolic functions.

import theano.tensor as T
# Define symbolic variables
x = T.scalar('x')
y = T.scalar('y')
# Symbolic expression for logical AND operation
and_expr = T.and_(x > 0, y < 10)
# Symbolic expression for elementwise comparison
elementwise_comparison_expr = T.gt(x, y) # Greater than
elementwise_comparison_expr = T.le(x, y) # Less than or equal to
elementwise_comparison_expr = T.eq(x, y) # Equal to

Shape manipulation

We can manipulate the shape of a matrix in Theano. It is very helpful in convolutional neural networks because we need to resize and reshape the image for the model requirements.

import theano.tensor as T
# Define a symbolic variable for a matrix
X = T.matrix('X')
# Symbolic expression for transposing a matrix
transpose_expr = T.transpose(X)
# Symbolic expression for reshaping a matrix
reshape_expr = X.reshape((4, 3))

Broadcasting

Broadcasting is like an intelligent assistant that simplifies element-wise operations between arrays of different shapes. It saves you from the hassle of manually copying the smaller array to match the larger one. With broadcasting, you don't need to worry about aligning sizes; it takes care of that. It effortlessly stretches the smaller array to fit the larger array's shape, making element-wise calculations easy and efficient on your computer's memory.

import theano.tensor as T
# Define symbolic variables for a matrix and a scalar
X = T.matrix('X')
a = T.scalar('a')
# Symbolic expression for elementwise addition with broadcasting
broadcast_add_expr = X + a

Indexing and slicing

Indexing and slicing are fundamental operations in programming and data manipulation, allowing you to access specific elements or subsets of elements from data structures like arrays, lists, and strings.

import theano.tensor as T
# Define a symbolic variable for a matrix
X = T.matrix('X')
# Symbolic expression for getting a specific row of the matrix
row_expr = X[0]
# Symbolic expression for getting a specific column of the matrix
column_expr = X[:, 1]
# Symbolic expression for slicing a matrix
slice_expr = X[1:4, 2:5]

Conditional expressions

In Theano, conditional expressions allow you to perform different computations based on a condition. Conditional expressions are created using the theano.tensor.switch function, which takes a condition, an expression to evaluate if the condition is true, and another expression to evaluate if the condition is false.

import theano.tensor as T
# Define symbolic variables
x = T.scalar('x')
y = T.scalar('y')
# Symbolic expression for a conditional operation
condition_expr = T.switch(T.lt(x, y), x, y)

Set sub-tensor

In Theano, we can modify or update specific elements or sub-tensors of a tensor in place. It allows you to create a new tensor with some elements or sub-tensors replaced by new values without altering the original tensor.

import theano.tensor as T
import theano
import numpy as np
# Define a shared variable with initial value
shared_var = theano.shared(value=np.zeros((3, 3)), name='shared_var')
# Define a symbolic variable for an update value
update_value = T.scalar('update_value')
# Symbolic expression for setting a subtensor of the shared variable
set_subtensor_expr = T.set_subtensor(shared_var[0:2, 0:2], update_value)
# Create a function to set the subtensor and update the shared variable
set_subtensor_fn = theano.function([update_value], set_subtensor_expr)
# Test the function
set_subtensor_fn(5.0)
print(shared_var.get_value())

Stack and concatenate

In Theano, the functions theano.tensor.stack and theano.tensor.concatenate are used for stacking and concatenating tensors, respectively.

import theano.tensor as T
# Define symbolic variables for matrices
X = T.matrix('X')
Y = T.matrix('Y')
# Symbolic expression for stacking matrices vertically
stacked_expr = T.stack([X, Y])
# Symbolic expression for concatenating matrices horizontally
concatenated_expr = T.concatenate([X, Y], axis=1)

L1 and L2 regularization

We use L1 and L2 regularization to prevent overfitting and underfitting in the models. They add penalty terms to the loss function, encouraging the model to have smaller weights and reducing the complexity of the model.

import theano.tensor as T
# Define symbolic variables for model parameters
weights = T.matrix('weights')
bias = T.vector('bias')
# Symbolic expression for L1 regularization term
l1_regularization_expr = T.sum(T.abs_(weights))
# Symbolic expression for L2 regularization term
l2_regularization_expr = T.sum(weights**2)

Conclusion

Theano is a library that helps in machine learning for matrix computations, finding the gradients that help during the backpropagation of the neural network. Moreover, we can perform statistical analysis on the data by using this library. Theano library is best for shape manipulations of the matrices. Concludingly, we have covered several functions of the Theano library; it is impossible to cover all the functions in a single Answer. After understanding the code and syntax provided in this Answer, you will be able to start working with Theano.

Copyright ©2024 Educative, Inc. All rights reserved