如何通过SymPy获取梯度的未展开矩阵表达式?
解决SymPy中最小二乘梯度的紧凑矩阵形式问题
问题分析
你尝试通过手动求和定义最小二乘损失函数并求导,但无论是否使用.as_explicit(),得到的都是展开的元素求和式,无法得到预期的紧凑矩阵形式2Aᵀ(Ax - y)(注:你写的A.应为矩阵转置Aᵀ,否则维度不匹配)。这是因为手动遍历元素求和的方式,SymPy无法自动将零散的元素导数重新合并为矩阵运算形式。
解决方案
直接利用SymPy的矩阵内积定义损失函数,借助矩阵微积分规则让SymPy自动推导紧凑形式的梯度:
import sympy as sp # 定义矩阵与向量符号 A = sp.MatrixSymbol('A', 3, 2) x = sp.MatrixSymbol('x', 2, 1) y = sp.MatrixSymbol('y', 3, 1) # 最小二乘损失函数:||Ax - y||² = (Ax - y)ᵀ · (Ax - y) f = (A * x - y).T @ (A * x - y) # 对向量x求梯度,derive_by_array返回行向量,转置为列向量形式 gradient = sp.derive_by_array(f, x).T # 化简表达式 gradient_simplified = sp.simplify(gradient) print(gradient_simplified)
结果说明
运行上述代码后,会直接得到紧凑的矩阵形式结果:2*A.T*(A*x - y),完全符合你的预期。
为什么之前的方法无效?
- 使用
Sum手动遍历元素时,SymPy会将损失函数视为标量求和,对每个x元素的导数会单独展开为求和表达式,无法自动识别并合并为矩阵乘法的形式。 - 直接用矩阵内积定义损失,SymPy能利用内置的矩阵求导规则,直接推导出紧凑的矩阵梯度表达式,无需手动处理元素求和。
内容的提问来源于stack exchange,提问作者Olivier_s_j
相关产品推荐
相关产品推荐

