Skip to content

Theano - 一个简单的 Theano 表达式

让我们从 Theano 中最基础的任务开始:定义和评估一个简单的数学表达式。我们将加两个标量数,即 c = a + b。

在标准的 Python 中,如果 a 和 b 具有值,c = a + b 将立即计算总和。在 Theano 中,过程不同,因为我们首先符号化地定义计算,然后再将其编译以供执行。

首先,导入必要的 Theano 模块。通常会将 theano.tensor 导入并使用别名 tt。

import theano
import theano.tensor as tt
import numpy as np # 稍后需要 numpy 来处理输入数据

声明符号变量 a 和 b。这些是占位符,代表数据的类型(例如,标量、向量、矩阵)及其数据类型(例如,float64、int32),但它们尚不持有实际值。我们使用 tt.dscalar() 表示双精度浮点标量。

# 声明 'a' 为一个符号标量 (双精度浮点数)
a = tt.dscalar('a') # 'a' 是一个可选的名称,用于调试
# 声明 'b' 为另一个符号标量
b = tt.dscalar('b')
# 检查它们的类型
print(f"Type of 'a': {type(a)}")
print(f"Theano type of 'a': {a.type}")
# 输出将显示它们是类型为 float64 scalar 的 Theano TensorVariables

在此阶段,a 和 b 只是未来计算图中的节点。

现在,使用符号变量定义表达式。这将构建计算图。

# 定义 'c' 为 'a' 和 'b' 的符号和
c = a + b
# 'c' 现在也是一个表示加法操作的符号变量
print(f"\nType of 'c': {type(c)}")
print(f"Theano type of 'c': {c.type}")
# 输出将显示 'c' 也是一个加法运算结果的 TensorVariable

至关重要的是,此时尚未执行任何加法运算。我们只符号化地定义了关系 c = a + b。

要实际计算总和,我们需要使用 theano.function 将此符号图编译成一个可执行函数。此函数接受符号输入并返回符号输出。

# 编译函数
# inputs: 作为表达式输入的符号变量列表 ([a, b])
# outputs: 作为结果的符号变量列表 ([c])
add_scalars = theano.function(inputs=[a, b], outputs=c)
print(f"\nCompiled function type: {type(add_scalars)}")
# 输出: <class 'theano.compile.function_module.Function'>

Theano 在此编译步骤中执行优化(optimizations)。

现在我们可以使用 a 和 b 的实际数值调用编译好的函数 add_scalars。Theano 函数通常接受标准的 Python 数字或 NumPy 数组。

# 使用 'a' 和 'b' 的具体数值调用函数
result = add_scalars(3.5, 5.5)
# 函数执行编译好的图并返回数值结果
print(f"\nResult of 3.5 + 5.5: {result}")
print(f"Type of result: {type(result)}")
# 您可以使用不同的数值再次调用它
result2 = add_scalars(10.0, -2.0)
print(f"Result of 10.0 + (-2.0): {result2}")

输出 result 将是 9.0。请注意,Theano 函数通常默认返回 NumPy 类型(即使对于标量,也可能是 numpy.ndarray)。

import theano
import theano.tensor as tt
import numpy as np
# 1. 声明符号变量 (占位符)
a = tt.dscalar('a') # 双精度标量
b = tt.dscalar('b') # 双精度标量
# 2. 定义符号表达式 (构建图)
c = a + b
# 3. 将表达式编译成可执行函数
# 指定输入 [a, b] 和输出 [c]
add_scalars = theano.function(inputs=[a, b], outputs=c)
# 4. 使用具体的数值数据调用编译好的函数
value1 = 3.5
value2 = 5.5
result = add_scalars(value1, value2)
# 5. 打印结果
print(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)}")
# 使用不同数值的示例
result2 = add_scalars(100, 200)
print(f"\nExecuting with a=100, b=200")
print(f"Result (c): {result2}")

这个简单的例子阐述了 Theano 的核心工作流程:符号化定义 -> 编译 -> 使用数据执行。这种分离使得 Theano 可以在运行任何计算之前执行重要的优化。