为什么 DL 不用解析解而用梯度下降（提示：参数量太大了，billlion parameters）
### 1. 解析解本身要算 `(XᵀX)⁻¹Xᵀy`，代价极高

线性回归的解析解是：

θ=(X⊤X)−1 X⊤yθ=(X⊤X)−1 X⊤y

- `XᵀX` 是一个 `(n_features × n_features)` 的矩阵
    
- 求逆的计算复杂度约 **O(n³)**
    
- 当参数量到 **十亿级（billion）** 时，`n³ = 10²⁷`，任何机器都算不动
    

而深度学习模型的参数量经常是：

- GPT-3：**1750 亿**参数
    
- 更大的模型：**万亿级**
    

`n³` 直接天文数字，**连矩阵都存不下**，更别说求逆。

### 2. 内存根本放不下

`XᵀX` 是 `n × n` 的矩阵。假设 `n = 10⁹`（十亿参数）：

- 用 float 32 存，需要 `10⁹ × 10⁹ × 4 bytes = 4 × 10¹⁸ bytes ≈ 4 EB`
    
- 而全世界的数据总量估计也就几十 ZB 量级
    

**存都存不下**，解析解直接出局。

### 3. 深度模型根本不是线性的

解析解只对**线性模型 + 平方损失**这种有闭式解的问题成立。

深度学习里有：

- 多层非线性激活（ReLU、GELU…）
    
- 卷积、注意力、归一化层
    
- 非凸的损失曲面
    

这些**根本没有解析解**，只能靠迭代优化。

### 4. 梯度下降只需求梯度，不用求逆

梯度下降每次迭代：

θ←θ−η∇L(θ)θ←θ−η∇L(θ)

- 只需要计算梯度 `∇L`，复杂度大致是 **O(n)** 或 **O(n × batch)** 级别
    
- 不需要构造 `n × n` 矩阵，也不需要求逆
    
- 显存只需存参数、梯度、优化器状态（Adam 约 3 倍参数量）
    

这也是为什么：

- **参数量再大，只要显存够，就能一步步迭代**
    
- 而且可以用 **mini-batch SGD**，每次只用一个 batch 的数据估计梯度，进一步省内存
    

### 5. 顺便说：即使能求逆，也不一定值得

- 解析解对**病态矩阵**（特征高度相关）非常敏感，数值不稳定
    
- 梯度下降配合正则化、动量、自适应学习率（Adam），**鲁棒性更好**
    
- 还能随时**中断、继续训练**，适合大规模分布式场景
    

### 一句话总结

> 解析解要构造并求逆一个 `n × n` 的矩阵，参数量上十亿时**内存装不下、算力算不动**；而梯度下降只要算梯度，**每次迭代 O(n) 级别**，配合 mini-batch 还能更省——所以深度学习几乎都用梯度下降（及其变种）。



## . 问题设定

线性回归模型：

y^=Xθy^​=Xθ

- `X`：`m × n` 矩阵（m 个样本，n 个特征）
    
- `θ`：`n × 1` 参数向量
    
- `y`：`m × 1` 真实标签
    

目标：找 `θ` 让**预测值和真实值的平方误差最小**。

损失函数（MSE，忽略常数系数不影响最优解）：

L(θ)=∥Xθ−y∥2=(Xθ−y)⊤(Xθ−y)L(θ)=∥Xθ−y∥2=(Xθ−y)⊤(Xθ−y)

---

## 2. 展开损失函数

L(θ)=(Xθ−y)⊤(Xθ−y)L(θ)=(Xθ−y)⊤(Xθ−y)

利用转置分配律 `(A - B)ᵀ = Aᵀ - Bᵀ`：

=(Xθ)⊤(Xθ)−(Xθ)⊤y−y⊤(Xθ)+y⊤y=(Xθ)⊤(Xθ)−(Xθ)⊤y−y⊤(Xθ)+y⊤y

注意中间两项都是**标量**，而标量的转置等于自身：

(Xθ)⊤y=θ⊤X⊤y(Xθ)⊤y=θ⊤X⊤y  
y⊤(Xθ)=(θ⊤X⊤y)⊤=θ⊤X⊤yy⊤(Xθ)=(θ⊤X⊤y)⊤=θ⊤X⊤y

所以两项相等，合并：

L(θ)=θ⊤X⊤Xθ−2θ⊤X⊤y+y⊤yL(θ)=θ⊤X⊤Xθ−2θ⊤X⊤y+y⊤y

---

## 3. 对 θ 求梯度

用到两个矩阵求导公式：

∂∂θ(θ⊤Aθ)=2 Aθ(A 对称)∂θ∂​(θ⊤Aθ)=2 Aθ(A 对称)  
∂∂θ(b⊤θ)=b∂θ∂​(b⊤θ)=b

对 `L(θ)` 逐项求导：

- 第一项：`θᵀ XᵀX θ`，其中 `A = XᵀX` 是对称矩阵 → 导数 `2XᵀX θ`
    
- 第二项：`-2 θᵀ Xᵀy` → 导数 `-2Xᵀy`
    
- 第三项：`yᵀy` 与 θ 无关 → 导数 `0`
    

所以：

∇θL(θ)=2 X⊤Xθ−2 X⊤y∇θ​L(θ)=2 X⊤Xθ−2 X⊤y

---

## 4. 令梯度为 0

∇θL(θ)=0∇θ​L(θ)=0

2 X⊤Xθ−2 X⊤y=02 X⊤Xθ−2 X⊤y=0

X⊤Xθ=X⊤yX⊤Xθ=X⊤y

这个方程叫 **normal equation（正规方程）**。

---

## 5. 解出 θ

如果 `XᵀX` 可逆（满秩），两边左乘 `(XᵀX)⁻¹`：

θ=(X⊤X)−1 X⊤yθ=(X⊤X)−1 X⊤y​

这就是解析解的来源。

---

## 6. 每一步的几何/代价含义

|步骤|计算|复杂度|
|---|---|---|
| `XᵀX` |n×m 乘 m×n → n×n|O(mn²)|
| `(XᵀX)⁻¹` |n×n 求逆|**O(n³)**|
| `Xᵀy` |n×m 乘 m×1 → n×1|O(mn)|
|最后相乘|n×n 乘 n×1|O(n²)|

**瓶颈在求逆：O(n³)，而且需要 n×n 矩阵的内存。**

---

## 7. 什么时候会出问题

**（1）`XᵀX` 不可逆**

- 特征之间有**完全共线性**（某列是另一列的线性组合）
    
- 样本数 m < 特征数 n（比如 100 个样本 1000 个特征）
    

解决：用**伪逆** `(XᵀX)⁻¹ → (XᵀX)⁺`（如 SVD 求伪逆），或加正则项变成**岭回归**：

θ=(X⊤X+λI)−1 X⊤yθ=(X⊤X+λI)−1 X⊤y

**（2）参数量 n 巨大**

- `n³` 爆炸，内存也爆炸
    
- 这时才需要梯度下降
    

---

## 8. 直观理解：为什么这个解是最优的

`Xθ` 是 `X` 的列空间（column space）里的一个向量。  
`y` 一般不在这个列空间里，所以要让 `Xθ` 尽可能接近 `y`。

最小距离发生在：**残差 `y - Xθ` 垂直于 X 的列空间**，即：

X⊤(y−Xθ)=0 X⊤(y−Xθ)=0

X⊤y−X⊤Xθ=0 X⊤y−X⊤Xθ=0

X⊤Xθ=X⊤yX⊤Xθ=X⊤y

θ=(X⊤X)−1 X⊤yθ=(X⊤X)−1 X⊤y

这就是几何解释——**正交投影**。解析解的本质就是：把 `y` 正交投影到 `X` 的列空间上。

---

## 一句话总结

> 对平方损失 `‖Xθ - y‖²` 求导、令梯度为 0，得到正规方程 `XᵀXθ = Xᵀy`，解出 `θ = (XᵀX)⁻¹Xᵀy`。代价是 O(n³) 求逆 + n×n 内存，所以参数量一大就必须换成梯度下降。



## 1. 先回忆单变量：为什么求导等于 0

你在高中学过：函数 `f(x)` 在极值点处，导数 `f'(x) = 0`。

比如 `f(x) = (x - 3)²`，最小值在 `x = 3`，而 `f'(3) = 2(3-3) = 0`。

直觉：**在最低点，切线是水平的，斜率 = 0。**

所以"令导数为 0"是**找极值点的通用方法**。

---

## 2. 多变量情况：梯度 = 0

多变量函数 `L(θ₁, θ₂, ..., θₙ)` 的"斜率"由**梯度** `∇L` 描述。

梯度是一个向量，指向**函数上升最快的方向**。

- 如果 `∇L ≠ 0`：说明沿着梯度方向走，函数还能变大；沿着反方向走，函数还能变小 → **当前点不是最低点**
    
- 如果 `∇L = 0`：所有方向的斜率都是 0，**没有下降方向了** → 是驻点（可能是极小、极大、鞍点）
    

所以要找最小值，候选点就是 **∇L = 0 的点**。

---

## 3. 关键：不是所有 ∇L=0 都是最小值！

这是最容易误解的地方。

`∇L = 0` 只说明是**驻点（stationary point）**，可能是：

|类型|例子|∇L=0 处|
|---|---|---|
|极小值| `x²` 在 x=0|✅ 最小值|
|极大值| `-x²` 在 x=0|❌ 最大值|
|鞍点| `x² - y²` 在 (0,0)|❌ 不是极值|

**那为什么这里可以直接说 θ 就是最优解？**

因为**平方损失函数是凸函数（convex）**。

---

## 4. 凸函数：∇L = 0 一定是全局最小

凸函数的形状像一个**碗**：

text

        \        /
         \      /
          \    /
           \__/     ← 唯一的底部

凸函数的性质：

1. **只有一个"底部"**（可能是平的，但不会有两个分离的谷）
    
2. **任何局部最小值 = 全局最小值**
    
3. **∇L = 0 的点，一定是全局最小值点**
    

所以对凸函数来说，"令梯度为 0"是**充分且必要**的求全局最优的方法。

---

## 5. 为什么平方损失是凸的？

损失：

L(θ)=∥Xθ−y∥2=θ⊤X⊤Xθ−2θ⊤X⊤y+y⊤yL(θ)=∥Xθ−y∥2=θ⊤X⊤Xθ−2θ⊤X⊤y+y⊤y

看二次项 `θᵀ (XᵀX) θ`：

- `XᵀX` 是**半正定矩阵**（因为对任意 `v`，`vᵀXᵀXv = ‖Xv‖² ≥ 0`）
    
- 二次型 `θᵀ(XᵀX)θ` 的 Hessian 是 `2XᵀX`，半正定
    
- **Hessian 半正定 ⟺ 函数是凸的**
    

所以 `L(θ)` 是一个**凸二次函数**，形状就是一个碗（或碗底是平的），∇L = 0 处必然是全局最小。

---

## 6. 串起来看逻辑链

text

平方损失 L(θ) 是凸函数
        ↓
凸函数只有一个"谷底"
        ↓
谷底处 ∇L = 0
        ↓
所以：求 L 最小值 ⟺ 解 ∇L = 0
        ↓
∇L = 2 XᵀXθ - 2 Xᵀy = 0
        ↓
XᵀXθ = Xᵀy
        ↓
θ = (XᵀX)⁻¹Xᵀy

---

## 7. 对比：如果损失不是凸的呢？

深度学习里的损失**通常是非凸的**（神经网络有多层非线性激活）。

这时 `∇L = 0` 的点可能是：

- 局部最小（不是全局）
    
- 鞍点
    
- 平台
    

所以深度学习**不能**用"令梯度=0 解方程"的方法，只能靠梯度下降一步步走到某个还不错的局部解。

**这也正好呼应了你前面的问题**：深度学习既没有解析解（非凸 + 参数多），又只能靠梯度下降迭代。

---

## 8. 一句话总结

> 令梯度为 0 是因为：**极值点处斜率必为 0**。而平方损失是**凸函数**（Hessian `2XᵀX` 半正定），凸函数的 `∇L = 0` 点**一定是全局最小值**，所以可以直接令 `∇L = 0` 解出解析解。深度学习损失非凸，`∇L = 0` 不保证最优，所以只能梯度下降。

补一个直观类比：

- **凸函数** = 一个碗，碗底就是最低点，找碗底 = 找斜率为 0 处
    
- **非凸函数** = 连绵起伏的山地，有很多小坑和鞍部，斜率 0 的地方未必是最低点，只能一步步摸索着往下走

|参数|一元线性回归（单特征）|多元线性回归（多特征）|原因|
|---|---|---|---|
|**dw (权重)**| `2 * np.mean(xs * err)` | `2/n * (X.T @ err)` |一维向量可以用 mean；二维矩阵必须用矩阵乘法（每列单独求梯度）。|
|**db (偏置)**| `2 * np.mean(err)` | `2 * np.mean(err)` |偏置永远只是一个标量，与特征数量无关。|

