☰
TensorFlow Cookbook 实战:用 Cholesky 分解实现线性回归(Decomposition Method)
2026/10/11 11:37:38 网站建设 项目流程
  • 示例工程

【免费下载链接】tensorflow_cookbook

Code for Tensorflow Machine Learning Cookbook

项目地址:https://gitcode.com/gh_mirrors/te/tensorflow_cookbook
点击查看免费下载

导读

本章节聚焦于《TensorFlow Machine Learning Cookbook》第 3 章(Linear Regression)中的第二种闭式求解方案——Cholesky 分解法:利用tf.cholesky()将对称正定的法方程矩阵AᵀA分解为下三角矩阵与其转置之积,再通过两次三角矩阵回代求出线性回归系数。读完本文,你将掌握 Cholesky 分解求解线性回归的完整数学推导、TensorFlow 1.x 图模式下的逐步实现代码、与矩阵求逆方法的数值对比,以及如何在 TensorFlow 2.x 中迁移对应 API。仓库中该配方的完整可运行代码位于 02_lin_reg_decomposition.py,对应的交互式讲解见 02_lin_reg_decomposition.ipynb。

一、为什么需要矩阵分解:从法方程谈起

对于 2D 线性回归A * x = b(A为设计矩阵,x为待求参数矩阵,b为目标值矩阵),第 3 章第 1 篇配方 01_lin_reg_inverse.py 给出了经典的最小二乘闭式解:

(t(A) * A) * x = t(A) * b x = (t(A) * A)^(-1) * t(A) * b

其中t(A)表示A的转置。这段闭式解的核心操作是显式计算矩阵(AᵀA)⁻¹的逆(代码中对应tf.matrix_inverse(tA_A))。从数值计算的角度看,显式求逆存在两个隐患:

  1. 计算量大:直接求逆需要完整的高斯消元过程,复杂度约为O(2n³/3);
  2. 数值稳定性差:当AᵀA接近奇异(条件数很大)时,求逆结果对舍入误差极其敏感,系数可能出现灾难性偏差。

Cholesky 分解正是规避上述问题的经典手段。本配方(第 3 章第 2 篇)的目标,就是用**分解(Decomposition)+ 回代(Back-substitution)**取代显式求逆,得到同样的最小二乘解,但更快、更稳。仓库第 3 章总览 03_Linear_Regression/readme.md 明确将前两篇归类为"标准矩阵线性回归求解",并指出它们与后续基于计算图的迭代式回归(第 3 至 8 篇)属于两类不同的实现思路。

二、数学原理:Cholesky 分解如何求出x

2.1 分解条件:对称正定矩阵

Cholesky 分解适用于对称正定矩阵:任一对称正定矩阵M都可以唯一分解为一个下三角矩阵L与其转置的乘积,即M = L * L'(L'为L的转置)。

对于超定线性回归系统,A本身是长方形矩阵(行数 = 样本数,列数 = 参数个数),并不满足分解条件。但注意:AᵀA天然是对称正定矩阵(只要A列满秩),因此配方分解的对象不是A,而是AᵀA:

t(A) * A = L * L'

2.2 两阶段求解

将分解结果代入法方程AᵀA·x = Aᵀb,得到:

L * L' * x = t(A) * b

由于L是下三角矩阵、L'是上三角矩阵,求解被拆成两次代价极低的三角矩阵回代:

  1. 前向代入(forward substitution):解L * y = t(A) * b,求出中间向量y;
  2. 回代求解(backward substitution):解L' * x = y,最终得到参数x。

完整求解步骤在配方说明文档中归纳为:

  1. 计算AᵀA的 Cholesky 分解,使AᵀA = L·L';
  2. 解L·y = Aᵀb得y;
  3. 解L'·x = y得x。

从代数上看,最终结果x = (L·L')⁻¹·Aᵀb = (AᵀA)⁻¹·Aᵀb,与矩阵求逆方法数学等价,但全程没有显式构造任何逆矩阵。

记法说明:配套 Notebook(02_lin_reg_decomposition.ipynb)的数学推导采用了另一种约定,将分解写作AᵀA = Lᵀ·L,并相应地先解Lᵀ·z = Aᵀy、再解L·x = z。两种记法只是把 "L" 的名字赋予了下三角或上三角因子,最终结果完全一致。以代码为准:TensorFlow 的tf.cholesky()返回的是下三角因子L,满足AᵀA = L·Lᵀ,因此代码中的求解顺序是先乘L、后乘Lᵀ。

2.3 复杂度优势

Cholesky 分解本身的复杂度约为O(n³/3),加上两次回代O(n²),相比直接高斯消元求逆(O(2n³/3))大约节省一半的计算量;更重要的是,分解过程避免了求逆放大的舍入误差,数值上更稳定。这正是本配方在工程实践中的核心价值。

三、数据准备:构造设计矩阵

与第 1 篇配方保持一致(Notebook 中注明"使用与先前配方相同的数据生成方法"),代码先用 NumPy 生成 100 个带噪声的线性样本:

x_vals = np.linspace(0, 10, 100) y_vals = x_vals + np.random.normal(0, 1, 100)

其中x在[0, 10]区间均匀取 100 个点,y = x + ε,ε ~ N(0, 1),即真实模型为斜率 1、截距 0 的直线,便于事后检验拟合结果。

接着构造 2D 回归的设计矩阵A(形状100 × 2):

x_vals_column = np.transpose(np.matrix(x_vals)) # 第一列:x 值 ones_column = np.transpose(np.matrix(np.repeat(1, 100))) # 第二列:全 1(截距项) A = np.column_stack((x_vals_column, ones_column)) b = np.transpose(np.matrix(y_vals)) # 目标列向量

设计矩阵第二列全 1 的作用是引入偏置项,使得求解得到的两个参数分别对应斜率(slope)和截距(y_intercept)。最后将 NumPy 数组包装为 TensorFlow 常量张量,纳入计算图:

A_tensor = tf.constant(A) b_tensor = tf.constant(b)

对应源码见 02_lin_reg_decomposition.py。

四、TensorFlow 实现:分解 + 两次回代

以下全部代码(02_lin_reg_decomposition.py)与前述数学步骤一一对应。

第 1 步:构造法方程矩阵并做 Cholesky 分解

tA_A = tf.matmul(tf.transpose(A_tensor), A_tensor) # Aᵀ·A,100x2 与 2x100 相乘得 2x2 L = tf.cholesky(tA_A) # 下三角因子 L,满足 AᵀA = L·Lᵀ

tf.cholesky()是 TensorFlow 对 LAPACKpotrf的封装,直接返回下三角因子。注意这里的AᵀA是2×2小矩阵,分解开销极小;即使扩展到更多特征维度,同一套 API 依然适用。

第 2 步:前向代入,解L * y = Aᵀ * b

tA_b = tf.matmul(tf.transpose(A_tensor), b) # Aᵀ·b,2x1 sol1 = tf.matrix_solve(L, tA_b) # 解 L·y = Aᵀ·b,得 y

tf.matrix_solve()求解线性方程组M·X = RHS。当M是三角矩阵时,TensorFlow 内部直接采用回代算法,复杂度为O(n²),无需任何求逆操作。

第 3 步:回代求解,解L' * x = y

sol2 = tf.matrix_solve(tf.transpose(L), sol1) # 解 Lᵀ·x = y,得最终参数 x

tf.transpose(L)将下三角因子转置为上三角矩阵,第二次tf.matrix_solve完成上三角回代。

第 4 步:会话求值

solution_eval = sess.run(sol2)

在 TensorFlow 1.x 图模式下,tf.Session()负责驱动整个计算图执行;由于所有节点都是常量与确定运算,sess.run(sol2)会一次性完成全部矩阵运算并返回2×1的参数向量。

完整的图构建过程与求值环节见 02_lin_reg_decomposition.py。整套实现只需四类算子:tf.matmul、tf.transpose、tf.cholesky、tf.matrix_solve,没有任何训练循环或超参数。

五、结果提取与可视化

solution_eval中第一个元素是斜率、第二个是截距,直接索引取值:

slope = solution_eval[0][0] y_intercept = solution_eval[1][0] print('slope: ' + str(slope)) print('y_intercept: ' + str(y_intercept))

Notebook 中的真实运行输出为:

slope: 0.944118894701 y_intercept: 0.227194921431

由于生成数据的真实关系是y = x + ε,拟合斜率接近 1、截距接近 0,验证了分解法求出的正是最小二乘解。随后代码按best_fit = slope * x + y_intercept逐点生成拟合直线,并用 Matplotlib 将原始散点与红色拟合线绘制在同一张图上(02_lin_reg_decomposition.py),结果即文首配图——数据点沿直线紧密分布,拟合线斜率与真实斜率基本一致。

六、与矩阵求逆方法的对比

第 1 篇配方的求逆版实现(01_lin_reg_inverse.py)核心代码如下:

tA_A = tf.matmul(tf.transpose(A_tensor), A_tensor) tA_A_inv = tf.matrix_inverse(tA_A) # 显式求逆 product = tf.matmul(tA_A_inv, tf.transpose(A_tensor)) solution = tf.matmul(product, b_tensor)

与本篇分解版对照,两者在数学结果上完全等价,差异全在数值策略:

维度矩阵求逆法(第 1 篇)Cholesky 分解法(本篇)
核心算子tf.matrix_inversetf.cholesky+ 两次tf.matrix_solve
显式构造逆矩阵是否
计算量约O(2n³/3)约O(n³/3),快约一倍
数值稳定性条件数大时误差被放大三角回代,误差累积更小
适用前提方阵可逆AᵀA对称正定(列满秩即可)

在特征维度n不大的情况下两者差别不明显;当n增长、或AᵀA病态时,分解法的优势会逐步显现。这也是线性代数求解库(LAPACK、NumPynumpy.linalg.solve等)默认不采用"先求逆再相乘"的根本原因。

七、与后续迭代式回归的关系

第 3 章从第 3 篇开始切换思路:以 03_lin_reg_tensorflow_way.py 为代表,改用计算图 + 梯度下降迭代逼近参数(在该配方中,模型为y = A·x + b,损失为批量 L2 损失loss = mean((y_target - model_output)²),通过GradientDescentOptimizer逐步优化)。与闭式解的两篇配方相比:

  • 本篇一次性算出全局最优参数,无学习率、迭代次数等超参数,也无需担心收敛问题;
  • 迭代式方法则具备可扩展性,能够处理大规模数据、引入正则化、切换到任意损失函数——第 3 章第 4 至 8 篇(L1/L2 损失、Deming 回归、Lasso/Ridge、ElasticNet、逻辑回归)正是沿着这条路线展开的。

因此,理解本篇的分解法,相当于掌握了线性回归"解析解"的数值最优实现,是理解后续所有"数值迭代解"的对比基准。

八、运行环境与 API 迁移注意事项

仓库根目录的 requirements.txt 将环境锁定为TensorFlow 1.15.0(配合numpy==1.14.5、matplotlib==2.2.2等)。本配方代码的图模式写法(tf.Session()+ops.reset_default_graph())依赖 1.x 默认关闭 Eager Execution 的语义,属于典型的 TF 1.x 风格。

在 TensorFlow 2.x 中,相关 API 已迁移至tf.linalg命名空间,功能完全对应:

TF 1.x(本配方)TF 2.x 等价 API
tf.cholesky(tA_A)tf.linalg.cholesky(tA_A)
tf.matrix_solve(L, b)tf.linalg.solve(L, b)
tf.matrix_inverse(M)tf.linalg.inv(M)(或直接tf.linalg.solve)

迁移时还需注意:TF 2.x 默认 Eager 模式,tf.constant张量可直接参与 NumPy 风格运算;若仍想以图方式执行,可使用tf.function包装上述矩阵运算。无论如何,分解法"先分解、后回代、不求逆"的核心思想不随 API 变化。

小结

本篇从仓库第 3 章第 2 篇配方出发,完整走通了 Cholesky 分解求解线性回归的链路:法方程AᵀA·x = Aᵀb→tf.cholesky分解为L·Lᵀ→ 两次tf.matrix_solve三角回代 → 提取斜率与截距并可视化。与同章矩阵求逆法相比,它在保持数学等价的前提下获得更优的复杂度与数值稳定性;与后续梯度下降法相比,它属于无需调参的闭式精确解。读者可基于 02_lin_reg_decomposition.py 直接运行复现,或对照 02_lin_reg_decomposition.ipynb 逐单元阅读推导细节,并尝试将特征列扩展到多维以检验方法的通用性。

  • 示例工程

【免费下载链接】tensorflow_cookbook

Code for Tensorflow Machine Learning Cookbook

项目地址:https://gitcode.com/gh_mirrors/te/tensorflow_cookbook
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询