Theano - A Trivial Theano Expression
Theano - A Basic Symbolic Expression
Section titled “Theano - A Basic Symbolic Expression”Let’s start with the most fundamental task in Theano: defining and evaluating a simple mathematical expression. We’ll add two scalar numbers, c = a + b.
In standard Python, c = a + b would immediately compute the sum if a and b have values. In Theano, the process is different because we first define the computation symbolically and then compile it for execution.
Steps to Evaluate c = a + b in Theano
Section titled “Steps to Evaluate c = a + b in Theano”1. Import Theano
Section titled “1. Import Theano”First, import the necessary Theano modules. It’s conventional to import theano.tensor with an alias like tt.
import theanoimport theano.tensor as ttimport numpy as np # We'll need numpy for input data later2. Declare Symbolic Variables
Section titled “2. Declare Symbolic Variables”Declare symbolic variables a and b. These are placeholders that represent the type of data (e.g., scalar, vector, matrix) and its data type (e.g., float64, int32) but don’t hold actual values yet. We use tt.dscalar() for double-precision floating-point scalars.
# Declare 'a' as a symbolic scalar (double precision float)a = tt.dscalar('a') # 'a' is an optional name for debugging
# Declare 'b' as another symbolic scalarb = tt.dscalar('b')
# Check their typesprint(f"Type of 'a': {type(a)}")print(f"Theano type of 'a': {a.type}")# Output will show they are Theano TensorVariables of type float64 scalarAt this stage, a and b are just nodes in a future computational graph.
3. Define the Symbolic Expression
Section titled “3. Define the Symbolic Expression”Now, define the expression using the symbolic variables. This builds the computational graph.
# Define 'c' as the symbolic sum of 'a' and 'b'c = a + b
# 'c' is now also a symbolic variable representing the addition operationprint(f"\nType of 'c': {type(c)}")print(f"Theano type of 'c': {c.type}")# Output will show 'c' is also a TensorVariable resulting from the additionCrucially, no addition is performed yet. We have only defined the relationship c = a + b symbolically.
4. Compile the Theano Function
Section titled “4. Compile the Theano Function”To actually compute the sum, we need to compile this symbolic graph into an executable function using theano.function. This function takes symbolic inputs and returns symbolic outputs.
# Compile the function# inputs: A list of symbolic variables that are inputs to the expression ([a, b])# outputs: A list of symbolic variables that are the results ([c])add_scalars = theano.function(inputs=[a, b], outputs=c)
print(f"\nCompiled function type: {type(add_scalars)}")# Output: <class 'theano.compile.function_module.Function'>Theano performs optimizations during this compilation step.
5. Invoke the Function with Concrete Values
Section titled “5. Invoke the Function with Concrete Values”Now we can call the compiled function add_scalars with actual numerical values for a and b. Theano functions typically accept standard Python numbers or NumPy arrays.
# Call the function with concrete values for 'a' and 'b'result = add_scalars(3.5, 5.5)
# The function executes the compiled graph and returns the numerical resultprint(f"\nResult of 3.5 + 5.5: {result}")print(f"Type of result: {type(result)}")
# You can call it again with different valuesresult2 = add_scalars(10.0, -2.0)print(f"Result of 10.0 + (-2.0): {result2}")The output result will be 9.0. Note that Theano functions often return NumPy types (like numpy.ndarray even for scalars) by default.
Full Program Listing
Section titled “Full Program Listing”import theanoimport theano.tensor as ttimport numpy as np
# 1. Declare symbolic variables (placeholders)a = tt.dscalar('a') # double precision scalarb = tt.dscalar('b') # double precision scalar
# 2. Define the symbolic expression (build the graph)c = a + b
# 3. Compile the expression into an executable function# Specify inputs [a, b] and output [c]add_scalars = theano.function(inputs=[a, b], outputs=c)
# 4. Invoke the compiled function with concrete numerical datavalue1 = 3.5value2 = 5.5result = add_scalars(value1, value2)
# 5. Print the resultprint(f"Symbolic expression defined: c = a + b")print(f"Compiled function: {add_scalars}")print(f"Executing with a={value1}, b={value2}")print(f"Result (c): {result}")print(f"Result type: {type(result)}")
# Example with different valuesresult2 = add_scalars(100, 200)print(f"\nExecuting with a=100, b=200")print(f"Result (c): {result2}")This simple example illustrates the core workflow of Theano: define symbolically -> compile -> execute with data. This separation allows Theano to perform significant optimizations before running any calculations.