1. 从机器学习实战说起:为什么我们需要矩阵求导?
大家好,我是老张,在AI和算法领域摸爬滚打了十几年。今天想和大家聊聊一个让很多初学者头疼,但又绕不开的话题——矩阵求导。我知道,一看到“求导”两个字,可能有人就想起了大学时被高数支配的恐惧。别慌,咱们今天不搞那些纯理论的推导,就从你手头正在做的项目说起。
想象一下这个场景:你正在训练一个线性回归模型。你的目标是找到一组参数 w,让预测值 y_pred = Xw 和真实值 y 之间的差距(比如均方误差)最小。这个“找最优参数”的过程,在数学上就叫优化。而优化的核心步骤之一,就是计算损失函数关于参数 w 的梯度,然后沿着梯度下降的方向更新 w。当你的参数 w 是一个向量,甚至你的输入数据 X 是一个矩阵时,这个“梯度”怎么算?难道要像一元函数求导那样,一个一个元素地求偏导吗?那效率太低了,代码写起来也又臭又长。
这时候,矩阵求导 就闪亮登场了。它允许我们把对向量或矩阵中每一个元素的求导操作,打包成一个简洁、统一的矩阵或向量表达式。这样一来,你写出来的梯度公式不仅干净利落,而且可以直接利用像NumPy、PyTorch这些库的高效矩阵运算,计算速度能提升好几个数量级。可以说,不理解矩阵求导,你就很难真正看懂现代机器学习算法(从线性回归、逻辑回归到神经网络的反向传播)的核心推导,更谈不上进行高效的模型调试和改进了。
所以,这篇文章的目的很明确:帮你从“会用”到“懂原理”。我会先带大家系统梳理机器学习里最常用、最核心的几个矩阵求导公式,并用实际的代码例子展示它们怎么用。然后,我们会深入一个稍微进阶但极其重要的主题:逆矩阵的求导。我会用两种不同的方法来推导它,并告诉你它们分别适合什么场景。相信我,跟着思路走下来,你会有一种“原来如此”的通透感。
2. 机器学习中的矩阵求导核心公式手册
在深入细节之前,我们得先统一一下“语言”。矩阵求导有不同的布局约定(Layout Convention),主要是分子布局和分母布局,这会导致结果的形式(是行向量还是列向量,是否转置)有所不同。为了不让大家混淆,也为了和主流深度学习框架(如PyTorch,它默认遵循分母布局)以及大多数教材保持一致,我们这里全程采用分母布局。简单说,就是求导结果的行列数,与分母(自变量)的行列数保持一致。你只要记住这一点,看下面的公式就不会晕。
2.1 基石:向量对向量的求导
这是最基本,也是构建其他公式的基石。假设 x 是一个 n 维列向量,y 是一个 m 维列向量,那么 y 对 x 的导数(雅可比矩阵)是一个 m×n 的矩阵,其中第 (i, j) 个元素是 ∂y_i / ∂x_j。
公式一:∂(aᵀx) / ∂x = a 这个公式看似简单,却非常强大。这里 a 是一个与 x 同维的常数向量,aᵀx 是一个标量(内积)。它的导数结果是 a。
- 生活类比:想象 x 是你购物车里各种商品的数量,a 是每种商品的单价。总价 aᵀx 关于数量 x 的变化率,自然就是每种商品的单价 a。
- 代码验证:
输出会显示import numpy as np # 定义向量 x = np.array([1.0, 2.0, 3.0]) a = np.array([0.5, 1.5, 2.5]) # 计算标量内积 scalar = np.dot(a, x) # aᵀx # 手动求导(根据公式) grad_manual = a # 根据公式,导数就是 a # 用NumPy的梯度近似验证(对于向量输入,需用自动微分或逐元素求偏导来验证概念) # 这里我们用一个小扰动来近似验证对x[0]的偏导 epsilon = 1e-7 x_perturbed = x.copy() x_perturbed[0] += epsilon scalar_perturbed = np.dot(a, x_perturbed) grad_approx_0 = (scalar_perturbed - scalar) / epsilon print(f"手动计算的梯度(整个向量): {grad_manual}") print(f"对x0的数值近似偏导: {grad_approx_0:.6f}, 公式给出的a[0]: {a[0]}")grad_approx_0非常接近a[0],验证了公式。
公式二:∂(xᵀx) / ∂x = 2x 这个公式求的是向量 x 自身内积(即其L2范数的平方)的导数。结果是 2x。
- 为什么是2x? 你可以把它类比为一元函数 f(x) = x² 的导数 f'(x) = 2x。在多元情况下,每个元素 x_i 对自己的平方求导是 2x_i,而对其他元素的平方求导为0,所以合起来就是


3716

被折叠的 条评论
为什么被折叠?



