首页
/ 使用joschu/cgt项目进行符号计算与自动微分教程

使用joschu/cgt项目进行符号计算与自动微分教程

2025-07-02 16:31:18作者:裴麒琰

什么是joschu/cgt项目

joschu/cgt是一个用于符号计算和自动微分的Python库,它允许用户构建数学表达式图,并自动计算这些表达式的梯度。该库特别适合机器学习中的优化问题,能够高效地处理向量、矩阵运算,并支持GPU加速。

基本工作流程

1. 定义符号变量

首先需要创建符号变量,这些变量代表计算图中的输入节点:

import cgt
a = cgt.scalar(name='a') # 浮点型标量,可选名称参数
b = cgt.scalar(name='b')
n = cgt.scalar(name='n', dtype='int64') # 整型标量

这里创建了三个符号变量:两个浮点型标量a和b,一个整型标量n。这些变量将成为我们计算图的输入节点。

2. 构建表达式

利用这些变量构建更复杂的数学表达式:

c = (a**n + b**n)**(1.0/n)

CGT会自动重载基本运算符(如+、<、等),使得我们可以像操作普通数值一样操作这些符号变量。在后台,CGT会构建一个表示这个计算过程的有向无环图(DAG)**。

3. 编译为可执行函数

将符号表达式编译为可执行函数:

f = cgt.function([a,b,n], c)
print f(8,15,2)  # 输出17.0

这个函数可以接受数值输入并返回计算结果。例如,当输入(8,15,2)时,计算的是(8² + 15²)的平方根,即17.0。

可视化计算图

CGT的一个强大功能是可以可视化计算图:

cgt.as_dot(c)

这将生成计算图的可视化表示,其中节点表示操作,边表示数据依赖关系。标签0和1表示函数参数的索引位置。

线性回归示例

让我们通过一个线性回归的例子展示更复杂的用法:

定义符号变量

X_nk = cgt.matrix("X")  # 输入特征矩阵
y_n = cgt.vector("y")    # 目标值向量
w_k = cgt.vector("w")    # 权重向量
b = cgt.scalar("b")      # 偏置项

构建预测和损失函数

ypred_n = X_nk.dot(w_k) + b  # 线性预测
L = cgt.sum(cgt.square(ypred_n - y_n))  # 平方损失
print "L = ", cgt.print_expr(L)

这里我们构建了一个标准的线性回归模型,使用平方误差作为损失函数。

计算梯度

grads = dLdw, dLdb = cgt.grad(L, [w_k, b])

CGT使用反向模式自动微分(即反向传播算法)自动计算损失函数对参数的梯度。这些梯度本身也是符号表达式。

编译为可执行函数

f_loss = cgt.function([X_nk, y_n, w_k, b], L)
f_grads = cgt.function([X_nk, y_n, w_k, b], grads)

使用数值数据进行测试

import numpy as np, numpy.random as nr
nr.seed(0)

# 生成随机数据
Xval = nr.randn(100,3)
yval = nr.randn(100)

# 初始化参数
wval = nr.randn(3)
bval = nr.randn()

# 计算损失和梯度
print "loss:", f_loss(Xval, yval, wval, bval)
print "grad:", f_grads(Xval, yval, wval, bval)

优化参数

方法1:使用SciPy优化器

def f(theta):
    return f_loss(Xval, yval, theta[0:3], theta[3])

def gradf(theta):
    gw,gb = f_grads(Xval, yval, theta[0:3], theta[3])
    return np.concatenate([gw,gb.reshape(1)])

import scipy.optimize as opt
theta_opt = opt.fmin_bfgs(f, np.zeros(4), gradf, disp=False)
print "Optimal theta:", theta_opt

方法2:使用CGT内置的优化

theta = cgt.vector('theta')
w_k_1 = theta[0:3]
b_1 = theta[3]
ypred_n_1 = X_nk.dot(w_k_1) + b_1
L_1 = cgt.sum(cgt.square(ypred_n_1 - y_n))
dLdtheta, = cgt.grad(L_1, [theta])

f = cgt.function([theta], L_1, givens=[(X_nk,Xval), (y_n,yval)])
gradf = cgt.function([theta], dLdtheta, givens=[(X_nk,Xval), (y_n,yval)])

theta_opt = opt.fmin_bfgs(f, np.zeros(4), gradf, disp=False)
print "Optimal theta:", theta_opt

方法3:使用共享变量和原地更新

这种方法特别适合大规模问题和GPU计算:

stepsize=0.001
w_k_2 = cgt.shared(wval.copy(), name='w')
b_2 = cgt.shared(bval, name='b')
ypred_n_2 = X_nk.dot(w_k_2) + b_2
L_2 = cgt.sum(cgt.square(ypred_n_2 - y_n))
dLdw_2,dLdb_2 = cgt.grad(L_2, [w_k_2, b_2])

updates = [(w_k_2, w_k_2 - stepsize*dLdw_2), (b_2, b_2 - stepsize*dLdb_2)]
givens = [(X_nk,Xval), (y_n,yval)]
f_update = cgt.function([], L_2, givens=givens, updates=updates)

for i in xrange(100):
    f_update()
print w_k_2.op.get_value(), b_2.op.get_value()

总结

joschu/cgt项目提供了一个强大的符号计算和自动微分框架,特别适合机器学习中的优化问题。通过本教程,我们学习了:

  1. 如何定义符号变量和构建表达式
  2. 如何可视化计算图
  3. 如何自动计算梯度
  4. 如何将符号表达式编译为可执行函数
  5. 三种不同的参数优化方法

CGT的设计使得从简单的数学表达式到复杂的机器学习模型都能高效地实现和优化。其支持GPU加速的特性使其特别适合大规模机器学习任务。

登录后查看全文

项目优选

收起
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Java
51
15
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
566
410
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
125
208
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
75
145
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
430
38
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
98
253
MateChatMateChat
前端智能化场景解决方案UI库,轻松构建你的AI应用,我们将持续完善更新,欢迎你的使用与建议。 官网地址:https://matechat.gitcode.com
693
91
folibfolib
FOLib 是一个为Ai研发而生的、全语言制品库和供应链服务平台
Java
42
2
CS-BooksCS-Books
🔥🔥超过1000本的计算机经典书籍、个人笔记资料以及本人在各平台发表文章中所涉及的资源等。书籍资源包括C/C++、Java、Python、Go语言、数据结构与算法、操作系统、后端架构、计算机系统知识、数据库、计算机网络、设计模式、前端、汇编以及校招社招各种面经~
97
13
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
298
1.03 K