Add presentation slides for OU process and Mehler formula
Sync to site1 / sync (push) Has been cancelled
@@ -0,0 +1,612 @@
|
|||||||
|
---
|
||||||
|
title: "Hermite 插值详解"
|
||||||
|
date: 2026-06-02
|
||||||
|
draft: false
|
||||||
|
tags: ["数值分析", "插值", "Hermite插值", "多项式逼近"]
|
||||||
|
categories: ["research", "math"]
|
||||||
|
description: "从切触条件、构造方法到误差分析,系统讲解 Hermite 插值的理论与应用。"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hermite 插值详解
|
||||||
|
|
||||||
|
> 本文系统讲解数值分析中的 **Hermite 插值(Hermite Interpolation,埃尔米特插值)**。它是 Lagrange 插值的自然推广:不仅要求插值多项式在节点处与被插函数取相同的**函数值**,还要求取相同的**导数值(一阶乃至更高阶)**。这使得插值曲线在节点处不仅"经过"数据点,还与原曲线"相切",从而得到更光滑、更逼真的逼近。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、引入与动机
|
||||||
|
|
||||||
|
### 1.1 从 Lagrange 插值说起
|
||||||
|
|
||||||
|
给定 $n+1$ 个互异节点 $x_0, x_1, \dots, x_n$ 及对应函数值 $f(x_i)$,Lagrange 插值给出唯一的次数 $\le n$ 多项式 $L_n(x)$,使得
|
||||||
|
|
||||||
|
$$
|
||||||
|
L_n(x_i) = f(x_i), \qquad i = 0, 1, \dots, n.
|
||||||
|
$$
|
||||||
|
|
||||||
|
它只匹配**函数值**。然而在很多实际问题中,我们对曲线"形状"的要求更高,**仅匹配函数值是不够的**:
|
||||||
|
|
||||||
|
- **光滑性不足**:Lagrange 插值在节点处的切线方向完全由全局多项式自动决定,可能与真实曲线的斜率相去甚远,导致曲线在节点附近"扭动"。
|
||||||
|
- **物理意义缺失**:若数据点代表某质点的位置,那么我们往往同时知道该点的**速度**(即一阶导数)。只匹配位置而丢弃速度信息,是对已知信息的浪费。
|
||||||
|
- **拼接不连续**:在分段插值中,若相邻段只匹配端点函数值而不匹配导数,则拼接处会出现折角(导数不连续)。
|
||||||
|
|
||||||
|
### 1.2 Hermite 插值的核心思想
|
||||||
|
|
||||||
|
**Hermite 插值**的思想是:在节点处同时匹配函数值与若干阶导数值。最常见的是同时匹配函数值与一阶导数值:
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(x_i) = f(x_i), \qquad H'(x_i) = f'(x_i), \qquad i = 0, 1, \dots, n.
|
||||||
|
$$
|
||||||
|
|
||||||
|
### 1.3 几何直观:节点处"相切"
|
||||||
|
|
||||||
|
考虑两条曲线 $y = f(x)$ 与 $y = H(x)$。如果它们在某点 $x_i$ 满足
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(x_i) = f(x_i) \quad (\text{过同一点}), \qquad H'(x_i) = f'(x_i) \quad (\text{斜率相同}),
|
||||||
|
$$
|
||||||
|
|
||||||
|
那么这两条曲线在 $x_i$ 处**相切**(一阶切触,order-1 contact)。如果进一步匹配到二阶导数 $H''(x_i)=f''(x_i)$,则它们在该点的**曲率**也一致(更高阶的切触)。
|
||||||
|
|
||||||
|
> 一句话概括:**Lagrange 插值让曲线"穿过"数据点;Hermite 插值让曲线"贴着"数据点走。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、问题定义
|
||||||
|
|
||||||
|
### 2.1 一般 Hermite 插值问题
|
||||||
|
|
||||||
|
给定 $n+1$ 个互异节点 $x_0, x_1, \dots, x_n$。在每个节点 $x_i$ 处,给定函数值及从一阶到 $m_i$ 阶的导数值:
|
||||||
|
|
||||||
|
$$
|
||||||
|
f(x_i),\ f'(x_i),\ f''(x_i),\ \dots,\ f^{(m_i)}(x_i).
|
||||||
|
$$
|
||||||
|
|
||||||
|
也就是说,节点 $x_i$ 处提供了 $m_i + 1$ 个约束条件(称该节点的**重数(multiplicity)**为 $m_i + 1$)。我们称整数 $m_i$ 为节点 $x_i$ 的**切触阶(order of contact)**。
|
||||||
|
|
||||||
|
记总约束数(总自由度)为
|
||||||
|
|
||||||
|
$$
|
||||||
|
N = \sum_{i=0}^{n} (m_i + 1).
|
||||||
|
$$
|
||||||
|
|
||||||
|
**目标**:求一个次数 $\le N-1$ 的多项式 $H(x)$,满足全部切触条件
|
||||||
|
|
||||||
|
$$
|
||||||
|
H^{(k)}(x_i) = f^{(k)}(x_i), \qquad k = 0, 1, \dots, m_i, \quad i = 0, 1, \dots, n.
|
||||||
|
$$
|
||||||
|
|
||||||
|
### 2.2 存在唯一性定理
|
||||||
|
|
||||||
|
> **定理(Hermite 插值的存在唯一性)**
|
||||||
|
> 设节点 $x_0, \dots, x_n$ 互异,切触阶分别为 $m_0, \dots, m_n$,记 $N = \sum_{i=0}^{n}(m_i+1)$。则在给定上述 $N$ 个切触条件下,**存在且唯一**一个次数 $\le N-1$ 的多项式 $H(x)$ 满足所有条件。
|
||||||
|
|
||||||
|
**证明(唯一性,反证法)**:
|
||||||
|
次数 $\le N-1$ 的多项式构成一个 $N$ 维线性空间(基为 $1, x, \dots, x^{N-1}$),共有 $N$ 个待定系数。切触条件给出 $N$ 个线性方程,于是问题等价于一个 $N \times N$ 的线性方程组。要证明解存在且唯一,只需证明对应齐次问题只有零解。
|
||||||
|
|
||||||
|
设 $P(x)$ 是次数 $\le N-1$ 的多项式,且满足全部**齐次**条件
|
||||||
|
|
||||||
|
$$
|
||||||
|
P^{(k)}(x_i) = 0, \qquad k = 0, 1, \dots, m_i, \quad i = 0, 1, \dots, n.
|
||||||
|
$$
|
||||||
|
|
||||||
|
则在每个节点 $x_i$ 处,$P$ 及其直到 $m_i$ 阶导数都为零,意味着 $x_i$ 是 $P$ 的至少 $m_i + 1$ 重根。因此 $P$ 的根(计重数)总数至少为
|
||||||
|
|
||||||
|
$$
|
||||||
|
\sum_{i=0}^{n}(m_i + 1) = N.
|
||||||
|
$$
|
||||||
|
|
||||||
|
但 $P$ 的次数 $\le N-1$,一个非零的 $N-1$ 次多项式至多有 $N-1$ 个根(计重数)。矛盾。故 $P \equiv 0$。这证明齐次问题只有零解,从而线性方程组的系数矩阵非奇异,原问题存在唯一解。$\blacksquare$
|
||||||
|
|
||||||
|
**特例**:当所有 $m_i = 0$ 时,$N = n+1$,Hermite 插值退化为 **Lagrange 插值**;当 $n+1$ 个节点每个都匹配函数值与一阶导数($m_i = 1$)时,$N = 2(n+1) = 2n+2$,称为**标准 Hermite 插值**,其多项式次数 $\le 2n+1$。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、两点三次 Hermite 插值(重点)
|
||||||
|
|
||||||
|
这是工程与图形学中**最常用**的 Hermite 插值形式,必须重点掌握。
|
||||||
|
|
||||||
|
### 3.1 问题设定
|
||||||
|
|
||||||
|
取两个节点 $x_0, x_1$,每个节点匹配函数值与一阶导数:
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(x_0) = f(x_0),\quad H'(x_0) = f'(x_0),\quad H(x_1) = f(x_1),\quad H'(x_1) = f'(x_1).
|
||||||
|
$$
|
||||||
|
|
||||||
|
共 $N = 4$ 个条件,故 $H(x)$ 是唯一的次数 $\le 3$ 的多项式(**三次多项式**)。
|
||||||
|
|
||||||
|
### 3.2 标准区间 $[0,1]$ 上的四个基函数
|
||||||
|
|
||||||
|
为简化推导,先把区间映射到 $[0,1]$。令
|
||||||
|
|
||||||
|
$$
|
||||||
|
t = \frac{x - x_0}{x_1 - x_0} \in [0, 1], \qquad h = x_1 - x_0.
|
||||||
|
$$
|
||||||
|
|
||||||
|
我们寻找一组三次基函数 $H_{00}(t), H_{10}(t), H_{01}(t), H_{11}(t)$,使得
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(t) = H_{00}(t)\, p_0 + H_{10}(t)\, m_0 + H_{01}(t)\, p_1 + H_{11}(t)\, m_1,
|
||||||
|
$$
|
||||||
|
|
||||||
|
其中 $p_0 = f(x_0)$,$p_1 = f(x_1)$ 是端点值,$m_0 = h f'(x_0)$,$m_1 = h f'(x_1)$ 是按区间长度缩放后的端点导数(因为对 $t$ 求导带来因子 $h$,详见 3.4 节)。
|
||||||
|
|
||||||
|
每个基函数在 $t=0,1$ 两端的"值/导数"特征如下表(这正是它们的**定义性质**):
|
||||||
|
|
||||||
|
| 基函数 | $值(0)$ | $导数(0)$ | $值(1)$ | $导数(1)$ | 作用 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| $H_{00}$ | $1$ | $0$ | $0$ | $0$ | 携带左端点值 $p_0$ |
|
||||||
|
| $H_{10}$ | $0$ | $1$ | $0$ | $0$ | 携带左端点切线 $m_0$ |
|
||||||
|
| $H_{01}$ | $0$ | $0$ | $1$ | $0$ | 携带右端点值 $p_1$ |
|
||||||
|
| $H_{11}$ | $0$ | $0$ | $0$ | $1$ | 携带右端点切线 $m_1$ |
|
||||||
|
|
||||||
|
### 3.3 基函数的推导
|
||||||
|
|
||||||
|
每个基函数是 $t$ 的三次多项式,写作 $H(t) = a t^3 + b t^2 + c t + d$,由上表的 4 个条件唯一确定。注意 $H'(t) = 3a t^2 + 2b t + c$。
|
||||||
|
|
||||||
|
**推导 $H_{00}$**:要求 $H_{00}(0)=1, H_{00}'(0)=0, H_{00}(1)=0, H_{00}'(1)=0$。
|
||||||
|
- $H_{00}(0)=d=1$。
|
||||||
|
- $H_{00}'(0)=c=0$。
|
||||||
|
- $H_{00}(1)=a+b+c+d=a+b+1=0 \Rightarrow a+b=-1$。
|
||||||
|
- $H_{00}'(1)=3a+2b+c=3a+2b=0 \Rightarrow b=-\tfrac{3}{2}a$。
|
||||||
|
- 代入 $a+b=-1$:$a-\tfrac{3}{2}a=-1 \Rightarrow -\tfrac{1}{2}a=-1 \Rightarrow a=2$,于是 $b=-3$。
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{H_{00}(t) = 2t^3 - 3t^2 + 1.}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**推导 $H_{10}$**:要求 $H_{10}(0)=0, H_{10}'(0)=1, H_{10}(1)=0, H_{10}'(1)=0$。
|
||||||
|
- $d=0$;$c=1$。
|
||||||
|
- $a+b+c+d=a+b+1=0 \Rightarrow a+b=-1$。
|
||||||
|
- $3a+2b+c=3a+2b+1=0 \Rightarrow 3a+2b=-1$。
|
||||||
|
- 由 $a+b=-1$ 得 $b=-1-a$,代入:$3a+2(-1-a)=-1 \Rightarrow a-2=-1 \Rightarrow a=1$,$b=-2$。
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{H_{10}(t) = t^3 - 2t^2 + t.}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**推导 $H_{01}$**:要求 $H_{01}(0)=0, H_{01}'(0)=0, H_{01}(1)=1, H_{01}'(1)=0$。
|
||||||
|
- $d=0$;$c=0$。
|
||||||
|
- $a+b=1$;$3a+2b=0 \Rightarrow b=-\tfrac{3}{2}a$。
|
||||||
|
- $a-\tfrac{3}{2}a=1 \Rightarrow -\tfrac12 a=1 \Rightarrow a=-2$,$b=3$。
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{H_{01}(t) = -2t^3 + 3t^2.}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**推导 $H_{11}$**:要求 $H_{11}(0)=0, H_{11}'(0)=0, H_{11}(1)=0, H_{11}'(1)=1$。
|
||||||
|
- $d=0$;$c=0$。
|
||||||
|
- $a+b=0$;$3a+2b=1$。
|
||||||
|
- 由 $b=-a$:$3a-2a=1 \Rightarrow a=1$,$b=-1$。
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{H_{11}(t) = t^3 - t^2.}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**验证(单位分解性质)**:注意 $H_{00}(t) + H_{01}(t) = (2t^3-3t^2+1) + (-2t^3+3t^2) = 1$。这保证了对常值函数 $f\equiv c$(其导数为 $0$)的插值结果恒为 $c$,符合预期。
|
||||||
|
|
||||||
|
### 3.4 完整公式(一般区间 $[x_0, x_1]$)
|
||||||
|
|
||||||
|
把 $t = (x-x_0)/h$ 代回,并注意链式法则 $\frac{\mathrm d}{\mathrm dx} = \frac{1}{h}\frac{\mathrm d}{\mathrm dt}$,对 $x$ 的导数与对 $t$ 的导数相差因子 $1/h$。因此端点导数 $f'(x_i)$ 与对 $t$ 的导数关系为 $\frac{\mathrm dH}{\mathrm dt}\big|_{t=0} = h f'(x_0)$,这解释了 3.2 节中为何令 $m_0 = h f'(x_0)$、$m_1 = h f'(x_1)$。最终插值多项式为
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{
|
||||||
|
H(x) = H_{00}(t)\,f(x_0) + H_{10}(t)\,h\,f'(x_0) + H_{01}(t)\,f(x_1) + H_{11}(t)\,h\,f'(x_1),
|
||||||
|
\qquad t=\frac{x-x_0}{h},\ h=x_1-x_0.
|
||||||
|
}
|
||||||
|
$$
|
||||||
|
|
||||||
|
展开为
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{aligned}
|
||||||
|
H(x) ={}& (2t^3-3t^2+1)\,f(x_0) + (t^3-2t^2+t)\,h\,f'(x_0) \\
|
||||||
|
&+ (-2t^3+3t^2)\,f(x_1) + (t^3-t^2)\,h\,f'(x_1).
|
||||||
|
\end{aligned}
|
||||||
|
$$
|
||||||
|
|
||||||
|
### 3.5 数值算例
|
||||||
|
|
||||||
|
设 $f(x) = \sin x$,节点 $x_0 = 0$,$x_1 = \tfrac{\pi}{2}$。则
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{aligned}
|
||||||
|
&f(x_0) = \sin 0 = 0, & &f'(x_0) = \cos 0 = 1, \\
|
||||||
|
&f(x_1) = \sin\tfrac{\pi}{2} = 1, & &f'(x_1) = \cos\tfrac{\pi}{2} = 0,
|
||||||
|
\end{aligned}
|
||||||
|
$$
|
||||||
|
|
||||||
|
且 $h = \tfrac{\pi}{2} \approx 1.5708$。代入完整公式(仅 $f(x_0)=0$、$f'(x_1)=0$ 两项消失):
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(x) = H_{10}(t)\,h\cdot 1 + H_{01}(t)\cdot 1
|
||||||
|
= h(t^3 - 2t^2 + t) + (-2t^3 + 3t^2),
|
||||||
|
$$
|
||||||
|
|
||||||
|
其中 $t = x / h = \dfrac{2x}{\pi}$。
|
||||||
|
|
||||||
|
**在区间中点 $x = \tfrac{\pi}{4}$ 处检验**(此时 $t = 0.5$):
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{aligned}
|
||||||
|
H_{10}(0.5) &= 0.125 - 0.5 + 0.5 = 0.125, \\
|
||||||
|
H_{01}(0.5) &= -0.25 + 0.75 = 0.5, \\
|
||||||
|
H(\tfrac{\pi}{4}) &= 1.5708 \times 0.125 + 1 \times 0.5 = 0.19635 + 0.5 = 0.69635.
|
||||||
|
\end{aligned}
|
||||||
|
$$
|
||||||
|
|
||||||
|
真实值 $\sin\tfrac{\pi}{4} = \tfrac{\sqrt2}{2} \approx 0.70711$。误差约为 $0.0108$,对仅用两个节点的三次插值而言已相当精确。作为对比,仅用相同两节点的线性 Lagrange 插值在中点给出 $0.5$,误差高达 $0.207$,可见匹配导数信息带来的显著改进。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、一般 Hermite 插值的构造方法
|
||||||
|
|
||||||
|
### 4.1 方法一:基函数法(广义 Lagrange 基)
|
||||||
|
|
||||||
|
对**标准 Hermite 插值**(每个节点匹配 $f(x_i)$ 与 $f'(x_i)$,$i=0,\dots,n$),插值多项式次数 $\le 2n+1$,可写成
|
||||||
|
|
||||||
|
$$
|
||||||
|
H_{2n+1}(x) = \sum_{i=0}^{n} f(x_i)\, h_i(x) + \sum_{i=0}^{n} f'(x_i)\, \hat h_i(x),
|
||||||
|
$$
|
||||||
|
|
||||||
|
其中 $h_i(x)$ 与 $\hat h_i(x)$ 是满足下列"选择性"条件的基函数($\delta_{ij}$ 为 Kronecker 符号):
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{aligned}
|
||||||
|
h_i(x_j) = \delta_{ij}, &\qquad h_i'(x_j) = 0, \\
|
||||||
|
\hat h_i(x_j) = 0, &\qquad \hat h_i'(x_j) = \delta_{ij}.
|
||||||
|
\end{aligned}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**构造公式**:借助 Lagrange 基函数
|
||||||
|
|
||||||
|
$$
|
||||||
|
\ell_i(x) = \prod_{\substack{j=0 \\ j\ne i}}^{n} \frac{x - x_j}{x_i - x_j},
|
||||||
|
$$
|
||||||
|
|
||||||
|
可以证明
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{
|
||||||
|
\begin{aligned}
|
||||||
|
h_i(x) &= \big[\,1 - 2(x - x_i)\,\ell_i'(x_i)\,\big]\,\ell_i^2(x), \\
|
||||||
|
\hat h_i(x) &= (x - x_i)\,\ell_i^2(x).
|
||||||
|
\end{aligned}
|
||||||
|
}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**验证思路**:因 $\ell_i(x_j) = \delta_{ij}$,故 $\ell_i^2(x_j) = \delta_{ij}$,于是 $\hat h_i(x_j) = (x_j-x_i)\delta_{ij} = 0$ 对一切 $j$ 成立;又 $\hat h_i'(x) = \ell_i^2(x) + (x-x_i)\cdot 2\ell_i\ell_i'$,在 $x=x_j$ 处当 $j\ne i$ 时 $\ell_i(x_j)=0$ 使两项皆为 $0$,当 $j=i$ 时第一项 $\ell_i^2(x_i)=1$、第二项含因子 $(x_i-x_i)=0$,故 $\hat h_i'(x_j)=\delta_{ij}$。$h_i$ 中的线性因子 $[1 - 2(x-x_i)\ell_i'(x_i)]$ 正是为抵消 $\ell_i^2$ 在 $x_i$ 处的导数而精心设计的。
|
||||||
|
|
||||||
|
基函数法概念清晰、利于理论分析,但当节点数较多或含高阶切触时,公式变得繁琐,**实际计算更推荐下面的差商法**。
|
||||||
|
|
||||||
|
### 4.2 方法二:重节点的差商法(Newton 形式,推荐)
|
||||||
|
|
||||||
|
Newton 均差(divided differences,差商)插值可以**自然地推广**到 Hermite 情形:把每个节点按其重数 $m_i+1$ **重复列出**,对于重复的节点,差商表中无法用普通差商公式(会出现 $0/0$)的位置,**用导数值填充**。
|
||||||
|
|
||||||
|
#### 4.2.1 重节点差商的定义
|
||||||
|
|
||||||
|
普通差商递归定义为
|
||||||
|
|
||||||
|
$$
|
||||||
|
f[x_i] = f(x_i), \qquad
|
||||||
|
f[x_i, \dots, x_{i+k}] = \frac{f[x_{i+1},\dots,x_{i+k}] - f[x_i,\dots,x_{i+k-1}]}{x_{i+k} - x_i}.
|
||||||
|
$$
|
||||||
|
|
||||||
|
当节点重合($x_{i+k} \to x_i$)时,分母为零。此时由微分中值定理的极限给出**重节点差商**:
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{\,\underbrace{f[x_i, x_i, \dots, x_i]}_{k+1 \text{ 个}} = \frac{f^{(k)}(x_i)}{k!}.\,}
|
||||||
|
$$
|
||||||
|
|
||||||
|
特别地:
|
||||||
|
|
||||||
|
$$
|
||||||
|
f[x_i, x_i] = f'(x_i), \qquad f[x_i, x_i, x_i] = \frac{f''(x_i)}{2}.
|
||||||
|
$$
|
||||||
|
|
||||||
|
#### 4.2.2 构造步骤
|
||||||
|
|
||||||
|
1. 建立**重复节点序列** $z_0, z_1, \dots, z_{N-1}$:把 $x_i$ 重复 $m_i+1$ 次依次排列。
|
||||||
|
2. 建立差商表。**对角线(最高阶差商)**逐列计算:
|
||||||
|
- 若相邻两个 $z$ 不相等,用普通差商公式;
|
||||||
|
- 若相邻两个 $z$ 相等(对应同一节点),用上面的导数公式填充。
|
||||||
|
3. 取**表的顶部对角线元素**作为 Newton 系数,写出多项式:
|
||||||
|
|
||||||
|
$$
|
||||||
|
\boxed{
|
||||||
|
H(x) = \sum_{k=0}^{N-1} f[z_0, z_1, \dots, z_k] \prod_{j=0}^{k-1}(x - z_j).
|
||||||
|
}
|
||||||
|
$$
|
||||||
|
|
||||||
|
#### 4.2.3 算例:带重节点的差商表
|
||||||
|
|
||||||
|
求满足下列条件的多项式(即两点三次 Hermite,与第三节呼应,便于互相验证):
|
||||||
|
|
||||||
|
$$
|
||||||
|
f(0) = 1,\quad f'(0) = 0,\quad f(1) = 0,\quad f'(1) = -1.
|
||||||
|
$$
|
||||||
|
|
||||||
|
重复节点序列:$z_0 = z_1 = 0$,$z_2 = z_3 = 1$。差商表如下(左列为 $z$ 与 $f$,向右逐阶):
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{array}{c|cccc}
|
||||||
|
z & f[\cdot] & f[\cdot,\cdot] & f[\cdot,\cdot,\cdot] & f[\cdot,\cdot,\cdot,\cdot] \\ \hline
|
||||||
|
0 & 1 & & & \\
|
||||||
|
& & \mathbf{0} & & \\
|
||||||
|
0 & 1 & & -1 & \\
|
||||||
|
& & -1 & & \mathbf{1} \\
|
||||||
|
1 & 0 & & 0 & \\
|
||||||
|
& & -1 & & \\
|
||||||
|
1 & 0 & & & \\
|
||||||
|
\end{array}
|
||||||
|
$$
|
||||||
|
|
||||||
|
逐项说明:
|
||||||
|
|
||||||
|
- 一阶差商列:
|
||||||
|
- $f[z_0,z_1] = f[0,0] = f'(0) = 0$(重节点,用导数)。
|
||||||
|
- $f[z_1,z_2] = f[0,1] = \dfrac{0 - 1}{1 - 0} = -1$(普通差商)。
|
||||||
|
- $f[z_2,z_3] = f[1,1] = f'(1) = -1$(重节点,用导数)。
|
||||||
|
- 二阶差商列:
|
||||||
|
- $f[z_0,z_1,z_2] = \dfrac{f[z_1,z_2] - f[z_0,z_1]}{z_2 - z_0} = \dfrac{-1 - 0}{1 - 0} = -1$。
|
||||||
|
- $f[z_1,z_2,z_3] = \dfrac{f[z_2,z_3] - f[z_1,z_2]}{z_3 - z_1} = \dfrac{-1 - (-1)}{1 - 0} = 0$。
|
||||||
|
- 三阶差商(顶部):
|
||||||
|
- $f[z_0,z_1,z_2,z_3] = \dfrac{f[z_1,z_2,z_3] - f[z_0,z_1,z_2]}{z_3 - z_0} = \dfrac{0 - (-1)}{1 - 0} = 1$。
|
||||||
|
|
||||||
|
于是顶部对角线系数依次为 $1,\ 0,\ -1,\ 1$,Newton 形式为
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{aligned}
|
||||||
|
H(x) &= 1 + 0\cdot(x-0) + (-1)(x-0)(x-0) + 1\cdot(x-0)(x-0)(x-1) \\
|
||||||
|
&= 1 - x^2 + x^2(x-1) \\
|
||||||
|
&= 1 - x^2 + x^3 - x^2 \\
|
||||||
|
&= x^3 - 2x^2 + 1.
|
||||||
|
\end{aligned}
|
||||||
|
$$
|
||||||
|
|
||||||
|
**验证**:$H(0)=1$ ✓;$H'(x)=3x^2-4x$,$H'(0)=0$ ✓;$H(1)=1-2+1=0$ ✓;$H'(1)=3-4=-1$ ✓。四个切触条件全部满足,构造正确。
|
||||||
|
|
||||||
|
> **说明**:差商法的最大优点是**统一处理任意阶切触**。无论某节点要匹配到几阶导数,只需把它重复相应次数、在重节点位置填入 $f^{(k)}(x_i)/k!$ 即可,无需为每种情形单独设计基函数。这也是教科书和数值库内部最常采用的实现思路。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、误差分析
|
||||||
|
|
||||||
|
### 5.1 误差余项公式
|
||||||
|
|
||||||
|
> **定理(Hermite 插值余项)**
|
||||||
|
> 设 $f \in C^{N}[a,b]$,节点 $x_0,\dots,x_n \in [a,b]$ 互异,切触阶为 $m_0,\dots,m_n$,$N=\sum(m_i+1)$,$H(x)$ 为满足全部切触条件、次数 $\le N-1$ 的 Hermite 插值多项式。则对任意 $x\in[a,b]$,存在依赖于 $x$ 的 $\xi=\xi(x)\in(a,b)$,使得
|
||||||
|
> $$
|
||||||
|
> \boxed{\,f(x) - H(x) = \frac{f^{(N)}(\xi)}{N!}\,\prod_{i=0}^{n}(x - x_i)^{m_i+1}.\,}
|
||||||
|
> $$
|
||||||
|
|
||||||
|
**证明要点(Rolle 定理法)**:固定 $x\ne x_i$。令节点因子 $W(t)=\prod_i (t-x_i)^{m_i+1}$(次数为 $N$),并构造辅助函数
|
||||||
|
|
||||||
|
$$
|
||||||
|
g(t) = f(t) - H(t) - \frac{f(x)-H(x)}{W(x)}\,W(t).
|
||||||
|
$$
|
||||||
|
|
||||||
|
则 $g$ 在 $t=x$ 处为零,且在每个 $x_i$ 处有 $m_i+1$ 重零点(因 $f-H$ 与 $W$ 在 $x_i$ 处都有相应阶的零)。于是 $g$(计重数)至少有 $N+1$ 个零点。反复使用 Rolle 定理,$g^{(N)}$ 至少有一个零点 $\xi$。由于 $H$ 次数 $\le N-1$ 故 $H^{(N)}\equiv 0$,而 $W^{(N)}=N!$,代入 $g^{(N)}(\xi)=0$ 解得
|
||||||
|
|
||||||
|
$$
|
||||||
|
f^{(N)}(\xi) - \frac{f(x)-H(x)}{W(x)}\,N! = 0
|
||||||
|
\;\Longrightarrow\;
|
||||||
|
f(x)-H(x) = \frac{f^{(N)}(\xi)}{N!}W(x). \qquad\blacksquare
|
||||||
|
$$
|
||||||
|
|
||||||
|
### 5.2 标准 Hermite(每点匹配值与一阶导)的余项
|
||||||
|
|
||||||
|
此时每个 $m_i=1$,$N=2n+2$,余项为
|
||||||
|
|
||||||
|
$$
|
||||||
|
f(x) - H(x) = \frac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod_{i=0}^{n}(x-x_i)^2.
|
||||||
|
$$
|
||||||
|
|
||||||
|
**两点三次情形**($n=1$,$N=4$):
|
||||||
|
|
||||||
|
$$
|
||||||
|
f(x) - H_3(x) = \frac{f^{(4)}(\xi)}{4!}(x-x_0)^2(x-x_1)^2 = \frac{f^{(4)}(\xi)}{24}(x-x_0)^2(x-x_1)^2.
|
||||||
|
$$
|
||||||
|
|
||||||
|
注意节点因子 $(x-x_i)^2 \ge 0$ 恒非负,这与 Lagrange 情形(节点因子可正可负)不同,反映了"相切"带来的更强约束。
|
||||||
|
|
||||||
|
### 5.3 与 Lagrange 插值误差的对比
|
||||||
|
|
||||||
|
| 对比项 | Lagrange 插值($n+1$ 点) | Hermite 插值(标准,$n+1$ 点) |
|
||||||
|
|---|---|---|
|
||||||
|
| 多项式次数 | $\le n$ | $\le 2n+1$ |
|
||||||
|
| 余项导数阶 | $f^{(n+1)}$ | $f^{(2n+2)}$ |
|
||||||
|
| 余项公式 | $\dfrac{f^{(n+1)}(\xi)}{(n+1)!}\prod (x-x_i)$ | $\dfrac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod (x-x_i)^2$ |
|
||||||
|
| 节点因子符号 | 可正可负 | 恒 $\ge 0$ |
|
||||||
|
| 收敛阶(等距 $h$) | $O(h^{n+1})$ | $O(h^{2n+2})$ |
|
||||||
|
|
||||||
|
**关键结论**:在使用相同节点数的前提下,Hermite 插值由于额外利用了导数信息,余项中出现**更高阶的导数**与**更高次的节点因子幂**,因而通常具有**更高的逼近精度(更高的收敛阶)**。代价是需要已知导数值,且多项式次数翻倍——次数过高时同样可能出现 Runge 现象,故实际更常用**分段**形式(见第六节)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、与样条的联系
|
||||||
|
|
||||||
|
### 6.1 分段三次 Hermite 插值
|
||||||
|
|
||||||
|
当节点很多时,直接构造高次 Hermite 多项式会引发振荡(Runge 现象)。实用做法是**分段**:在每个相邻区间 $[x_i, x_{i+1}]$ 上用第三节的两点三次 Hermite 公式构造一段三次多项式,再拼接起来。
|
||||||
|
|
||||||
|
由于每段都在端点匹配函数值与一阶导数,拼接处天然满足
|
||||||
|
|
||||||
|
$$
|
||||||
|
H(x_i^-) = H(x_i^+) = f(x_i), \qquad H'(x_i^-) = H'(x_i^+) = f'(x_i),
|
||||||
|
$$
|
||||||
|
|
||||||
|
即整条曲线达到 **$C^1$ 连续**(函数与一阶导都连续)。这正是分段三次 Hermite 插值(Piecewise Cubic Hermite Interpolation)。其前提是**每个节点的导数 $f'(x_i)$ 已知或被估计出来**。
|
||||||
|
|
||||||
|
### 6.2 三次样条与 Hermite 形式的关系
|
||||||
|
|
||||||
|
**三次样条(cubic spline)**同样是分段三次、$C^1$ 连续,但它额外要求
|
||||||
|
|
||||||
|
$$
|
||||||
|
H''(x_i^-) = H''(x_i^+), \qquad i=1,\dots,n-1,
|
||||||
|
$$
|
||||||
|
|
||||||
|
即**二阶导数也连续**,从而整体达到 **$C^2$ 连续**,曲线更光滑(曲率不突变)。
|
||||||
|
|
||||||
|
两者的本质区别在于"导数从何而来":
|
||||||
|
|
||||||
|
- **分段 Hermite**:各节点的斜率 $f'(x_i)$ 是**给定或局部估计**的(局部方法,每段相互独立),只保证 $C^1$。
|
||||||
|
- **三次样条**:斜率(或二阶导)是通过求解一个**全局三对角线性方程组**确定的,目的是让二阶导连续,因此是**全局方法**,达到 $C^2$,但任一数据点的改动会影响整条曲线。
|
||||||
|
|
||||||
|
事实上,任何三次样条都可以**改写成分段 Hermite 形式**:只要先解出样条在各节点的导数值 $s'(x_i)$,再把这些导数当作 Hermite 的输入即可。所以"三次样条"可视为"用全局光滑性条件自动确定斜率的分段三次 Hermite 插值"。
|
||||||
|
|
||||||
|
### 6.3 单调性保持(PCHIP)
|
||||||
|
|
||||||
|
分段三次 Hermite 的一个重要变体是 **PCHIP(Piecewise Cubic Hermite Interpolating Polynomial)**。它不直接使用真实导数,而是用一套特殊规则**估计每个节点的斜率 $d_i$**,使得:
|
||||||
|
|
||||||
|
- 在数据单调的区间内,插值曲线**保持单调**,不产生过冲(overshoot)/ 振荡;
|
||||||
|
- 在局部极值点处令斜率为 $0$,避免越过数据点。
|
||||||
|
|
||||||
|
具体地,PCHIP 在内部节点用相邻区间斜率的**加权调和平均**来估计 $d_i$:若相邻两段割线斜率 $\delta_{i-1}, \delta_i$ 同号,则
|
||||||
|
|
||||||
|
$$
|
||||||
|
\frac{w_1+w_2}{d_i} = \frac{w_1}{\delta_{i-1}} + \frac{w_2}{\delta_i},
|
||||||
|
\qquad w_1 = 2h_i + h_{i-1},\ w_2 = h_i + 2h_{i-1},
|
||||||
|
$$
|
||||||
|
|
||||||
|
否则(异号或某段为零,即遇到局部极值)令 $d_i = 0$。这保证了形状保持性。与三次样条相比,PCHIP 牺牲了 $C^2$ 光滑(只保 $C^1$),换来**无过冲**的视觉与物理可靠性,非常适合插值带有尖锐变化或单调段的数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、应用场景
|
||||||
|
|
||||||
|
### 7.1 计算机图形学:三次 Hermite 曲线
|
||||||
|
|
||||||
|
第三节的四基函数 $H_{00},H_{10},H_{01},H_{11}$ 正是图形学中**三次 Hermite 曲线(Cubic Hermite Spline)**的数学基础。给定两端点 $\mathbf P_0,\mathbf P_1$ 与两端切向量 $\mathbf T_0,\mathbf T_1$(这里把标量推广为向量,对每个坐标分量分别插值):
|
||||||
|
|
||||||
|
$$
|
||||||
|
\mathbf P(t) = H_{00}(t)\mathbf P_0 + H_{10}(t)\mathbf T_0 + H_{01}(t)\mathbf P_1 + H_{11}(t)\mathbf T_1,\quad t\in[0,1].
|
||||||
|
$$
|
||||||
|
|
||||||
|
设计师通过拖动切向量即可直观地控制曲线的"出入方向"。
|
||||||
|
|
||||||
|
**Catmull-Rom 样条**是其著名特例:它自动地把每个控制点的切向量取为相邻两点连线方向
|
||||||
|
|
||||||
|
$$
|
||||||
|
\mathbf T_i = \frac{1}{2}(\mathbf P_{i+1} - \mathbf P_{i-1}),
|
||||||
|
$$
|
||||||
|
|
||||||
|
从而只需给一串点就能生成一条**经过所有控制点、$C^1$ 连续**的光滑曲线,广泛用于路径与曲线设计。
|
||||||
|
|
||||||
|
### 7.2 动画关键帧插值与相机路径
|
||||||
|
|
||||||
|
在动画中,美术师设置若干**关键帧(keyframe)**:在某些时刻指定物体的位置、旋转、缩放等属性。系统需要在关键帧之间"补间(in-between)"。使用 Hermite 插值(指定每个关键帧的属性值**及其变化速率/切线**)可以让运动平滑、避免在关键帧处出现速度突变(折角)。相机沿预定轨迹平移、推拉时同样依赖 Hermite/样条曲线得到流畅运镜。
|
||||||
|
|
||||||
|
### 7.3 数值微分方程与轨迹规划
|
||||||
|
|
||||||
|
- **常微分方程数值解**:一些方法(如 Hermite–Obreschkoff、含导数信息的密集输出/dense output)利用解在网格点的函数值与导数值(导数恰由 ODE 右端 $f(t,y)$ 直接给出)做 Hermite 插值,得到任意时刻的高精度连续解。
|
||||||
|
- **机器人/无人机轨迹规划**:要求轨迹在路点(waypoint)处同时满足位置与速度(甚至加速度)约束,正是高阶 Hermite 插值的典型用武之地——它能保证速度连续,使运动平稳、可执行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、Python 代码示例
|
||||||
|
|
||||||
|
下面用 `numpy` 从零实现两点三次 Hermite 插值,并用 SciPy 的 `CubicHermiteSpline` 与 `BPoly.from_derivatives` 进行对照验证。代码可直接运行。
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# 1) 基函数法:标准区间 [0,1] 上的四个三次 Hermite 基函数
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def hermite_basis(t):
|
||||||
|
"""返回 (H00, H10, H01, H11) 在参数 t 处的值。t 可为标量或 numpy 数组。"""
|
||||||
|
H00 = 2 * t**3 - 3 * t**2 + 1 # 携带左端点值
|
||||||
|
H10 = t**3 - 2 * t**2 + t # 携带左端点切线
|
||||||
|
H01 = -2 * t**3 + 3 * t**2 # 携带右端点值
|
||||||
|
H11 = t**3 - t**2 # 携带右端点切线
|
||||||
|
return H00, H10, H01, H11
|
||||||
|
|
||||||
|
|
||||||
|
def cubic_hermite(x, x0, x1, p0, p1, m0, m1):
|
||||||
|
"""
|
||||||
|
两点三次 Hermite 插值。
|
||||||
|
x0, x1 : 两个节点
|
||||||
|
p0, p1 : 端点函数值 f(x0), f(x1)
|
||||||
|
m0, m1 : 端点一阶导数 f'(x0), f'(x1)
|
||||||
|
返回 H(x)。
|
||||||
|
"""
|
||||||
|
h = x1 - x0
|
||||||
|
t = (x - x0) / h
|
||||||
|
H00, H10, H01, H11 = hermite_basis(t)
|
||||||
|
# 注意导数项需乘以区间长度 h(链式法则)
|
||||||
|
return H00 * p0 + H10 * (h * m0) + H01 * p1 + H11 * (h * m1)
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# 2) 算例:用 f(x)=sin(x) 在 [0, pi/2] 上做两点三次 Hermite 插值
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
x0, x1 = 0.0, np.pi / 2
|
||||||
|
p0, p1 = np.sin(x0), np.sin(x1) # 函数值: 0, 1
|
||||||
|
m0, m1 = np.cos(x0), np.cos(x1) # 导数值: 1, 0
|
||||||
|
|
||||||
|
xs = np.linspace(x0, x1, 9)
|
||||||
|
H_vals = cubic_hermite(xs, x0, x1, p0, p1, m0, m1)
|
||||||
|
true_vals = np.sin(xs)
|
||||||
|
|
||||||
|
print("x Hermite sin(x) 误差")
|
||||||
|
for x, h, s in zip(xs, H_vals, true_vals):
|
||||||
|
print(f"{x:.4f} {h:.6f} {s:.6f} {abs(h - s):.2e}")
|
||||||
|
|
||||||
|
# 在中点 pi/4 处单独检验(对应正文 3.5 节)
|
||||||
|
xm = np.pi / 4
|
||||||
|
print(f"\n中点 H(pi/4) = {cubic_hermite(xm, x0, x1, p0, p1, m0, m1):.5f}, "
|
||||||
|
f"真值 = {np.sin(xm):.5f}")
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# 3) 与 SciPy 对照(若已安装 scipy)
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
try:
|
||||||
|
from scipy.interpolate import CubicHermiteSpline, BPoly
|
||||||
|
|
||||||
|
# CubicHermiteSpline 直接接受节点、函数值、导数值
|
||||||
|
nodes = np.array([x0, x1])
|
||||||
|
vals = np.array([p0, p1])
|
||||||
|
ders = np.array([m0, m1])
|
||||||
|
chs = CubicHermiteSpline(nodes, vals, ders)
|
||||||
|
|
||||||
|
# BPoly.from_derivatives: 每个节点给 [值, 一阶导]
|
||||||
|
bp = BPoly.from_derivatives(nodes, [[p0, m0], [p1, m1]])
|
||||||
|
|
||||||
|
max_err_chs = np.max(np.abs(chs(xs) - H_vals))
|
||||||
|
max_err_bp = np.max(np.abs(bp(xs) - H_vals))
|
||||||
|
print(f"\n与 CubicHermiteSpline 的最大偏差: {max_err_chs:.2e}")
|
||||||
|
print(f"与 BPoly.from_derivatives 的最大偏差: {max_err_bp:.2e}")
|
||||||
|
# 两者应与自实现完全一致(偏差约为机器精度 ~1e-16)
|
||||||
|
except ImportError:
|
||||||
|
print("\n未安装 scipy,跳过对照验证。")
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期输出**(节选):自实现结果与 SciPy 两种方法的偏差均在机器精度量级(约 $10^{-16}$),中点处 $H(\pi/4)\approx 0.69635$,与正文 3.5 节手算一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、小结表格
|
||||||
|
|
||||||
|
下表对比三种最常用的插值方案,帮助快速选型:
|
||||||
|
|
||||||
|
| 对比维度 | Lagrange 插值 | Hermite 插值(标准) | 三次样条(cubic spline) |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **匹配条件** | 仅节点函数值 $f(x_i)$ | 节点函数值 $f(x_i)$ **与导数值** $f'(x_i)$(可含更高阶) | 节点函数值;导数由全局光滑条件自动确定 |
|
||||||
|
| **多项式形态** | 单个次数 $\le n$ 的多项式 | 单个次数 $\le 2n+1$ 的多项式(或分段三次) | 分段三次多项式 |
|
||||||
|
| **连续性** | 自身光滑(单个多项式),分段拼接仅 $C^0$ | 节点处达 $C^1$(分段时);插值更"贴合" | $C^2$(二阶导连续,最光滑) |
|
||||||
|
| **是否需导数** | 否 | **是**(须已知或估计 $f'$) | 否(自动求解) |
|
||||||
|
| **误差余项** | $\dfrac{f^{(n+1)}(\xi)}{(n+1)!}\prod(x-x_i)$ | $\dfrac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod(x-x_i)^2$ | 分段,$O(h^4)$ 量级 |
|
||||||
|
| **局部/全局** | 全局(改一点影响整体) | 局部(分段 Hermite 每段独立) | 全局(解三对角方程组) |
|
||||||
|
| **典型用途** | 理论分析、低阶插值、推导数值公式 | 图形学曲线、动画关键帧、轨迹规划、ODE 密集输出 | 数据光滑拟合、CAD 曲线、平滑插值 |
|
||||||
|
| **代表实现** | — | `CubicHermiteSpline`、`BPoly.from_derivatives`、PCHIP | `CubicSpline` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考与延伸
|
||||||
|
|
||||||
|
- 经典数值分析教材(如 Burden & Faires《Numerical Analysis》、李庆扬《数值分析》)中关于 Hermite 插值与差商的章节。
|
||||||
|
- SciPy 文档:[`CubicHermiteSpline`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.CubicHermiteSpline.html)、[`PchipInterpolator`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.PchipInterpolator.html)、`BPoly.from_derivatives`。
|
||||||
|
- 计算机图形学中关于 Hermite 曲线、Bézier 曲线与 Catmull-Rom 样条相互转化的资料。
|
||||||
|
|
||||||
|
> **一句话总结**:Hermite 插值通过同时匹配函数值与导数值,让插值曲线在节点处"相切",以更高的收敛阶和更好的光滑性逼近原函数;其两点三次形式与分段推广(含 PCHIP、Catmull-Rom)是图形学、动画与轨迹规划的基石,实际构造首选**重节点差商法**。
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""把 Hermite 幻灯片 + 已有播客音频合成为 MP4 视频(无需重新调 TTS)。
|
||||||
|
|
||||||
|
流程:
|
||||||
|
1) 读已有完整音频时长;按每句文本字符数占比,把总时长分配到 11 页
|
||||||
|
(字符数是中文 TTS 时长的良好代理;总时长严格等于真实音频)。
|
||||||
|
2) 用 Chrome headless 把 11 页各截一张 1920x1080 PNG(?page=N&clean=1)。
|
||||||
|
3) ffmpeg:每页图片按对应时长生成视频轨,叠加音频,输出 MP4。
|
||||||
|
|
||||||
|
用法:python3 build_video.py
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
SCRIPT_JSON = os.path.join(HERE, "hermite_polynomials-script.json")
|
||||||
|
SLIDE_HTML = os.path.join(HERE, "slides", "Hermite 多项式.html")
|
||||||
|
OUT_DIR = os.path.join(HERE, "output")
|
||||||
|
SHOT_DIR = os.path.join(OUT_DIR, "shots")
|
||||||
|
AUDIO_IN = os.path.join(OUT_DIR, "hermite_polynomials-podcast.mp3")
|
||||||
|
VIDEO_OUT = os.path.join(OUT_DIR, "hermite_polynomials-video.mp4")
|
||||||
|
|
||||||
|
CHROME = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||||
|
|
||||||
|
# 句(1-based) -> 页(1-based) 映射。共 43 句、11 页。
|
||||||
|
LINE_TO_PAGE = {
|
||||||
|
1: 1, 2: 1,
|
||||||
|
3: 2, 4: 2, 5: 2, 6: 2,
|
||||||
|
7: 3, 8: 3,
|
||||||
|
9: 4, 10: 4, 11: 4, 12: 4,
|
||||||
|
13: 5, 14: 5, 15: 5, 16: 5, 17: 5,
|
||||||
|
18: 6, 19: 6, 20: 6,
|
||||||
|
21: 7, 22: 7, 23: 7, 24: 7, 25: 7, 26: 7,
|
||||||
|
27: 8, 28: 8, 29: 8,
|
||||||
|
30: 9, 31: 9, 32: 9, 33: 9,
|
||||||
|
34: 10, 35: 10, 36: 10, 37: 10, 38: 10, 39: 10,
|
||||||
|
40: 11, 41: 11, 42: 11, 43: 11,
|
||||||
|
}
|
||||||
|
NUM_PAGES = 11
|
||||||
|
|
||||||
|
|
||||||
|
def run(cmd):
|
||||||
|
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
|
||||||
|
def ffprobe_dur(path):
|
||||||
|
out = subprocess.check_output(
|
||||||
|
["ffprobe", "-v", "error", "-show_entries", "format=duration",
|
||||||
|
"-of", "default=noprint_wrappers=1:nokey=1", path])
|
||||||
|
return float(out.strip())
|
||||||
|
|
||||||
|
|
||||||
|
def step1_page_durations():
|
||||||
|
total = ffprobe_dur(AUDIO_IN)
|
||||||
|
with open(SCRIPT_JSON, encoding="utf-8") as f:
|
||||||
|
lines = json.load(f)["lines"]
|
||||||
|
# 每句字符数(去空白)作为时长权重
|
||||||
|
page_chars = {p: 0 for p in range(1, NUM_PAGES + 1)}
|
||||||
|
for i, line in enumerate(lines, 1):
|
||||||
|
n = len(line["paragraph"].strip())
|
||||||
|
page_chars[LINE_TO_PAGE.get(i, NUM_PAGES)] += n
|
||||||
|
grand = sum(page_chars.values())
|
||||||
|
page_dur = {p: total * page_chars[p] / grand for p in page_chars}
|
||||||
|
# 修正累计误差,使最后一页吸收余量
|
||||||
|
assigned = sum(page_dur.values())
|
||||||
|
page_dur[NUM_PAGES] += (total - assigned)
|
||||||
|
print(f"音频总时长 {total:.2f}s,按字符占比分配到 {NUM_PAGES} 页:")
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
print(f" page {p:>2}: {page_dur[p]:6.2f}s ({page_chars[p]} 字)")
|
||||||
|
return page_dur, total
|
||||||
|
|
||||||
|
|
||||||
|
def step2_screenshots():
|
||||||
|
os.makedirs(SHOT_DIR, exist_ok=True)
|
||||||
|
file_url = "file://" + SLIDE_HTML.replace(" ", "%20")
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
out = os.path.join(SHOT_DIR, f"page_{p:02d}.png")
|
||||||
|
url = f"{file_url}?page={p}&clean=1"
|
||||||
|
run([CHROME, "--headless=new", "--disable-gpu", "--hide-scrollbars",
|
||||||
|
"--force-device-scale-factor=1", "--window-size=1920,1080",
|
||||||
|
f"--screenshot={out}", "--virtual-time-budget=2800", url])
|
||||||
|
if not os.path.exists(out):
|
||||||
|
raise RuntimeError(f"截图失败 page {p}")
|
||||||
|
print(f"截图 page {p:02d} ✓")
|
||||||
|
|
||||||
|
|
||||||
|
def step3_video(page_dur):
|
||||||
|
tmp_list = os.path.join(SHOT_DIR, "vlist.txt")
|
||||||
|
with open(tmp_list, "w") as lf:
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
img = os.path.join(SHOT_DIR, f"page_{p:02d}.png")
|
||||||
|
dur = max(page_dur[p], 0.8)
|
||||||
|
vid = os.path.join(SHOT_DIR, f"v_{p:02d}.mp4")
|
||||||
|
run(["ffmpeg", "-y", "-loop", "1", "-i", img, "-t", f"{dur:.3f}",
|
||||||
|
"-r", "30", "-pix_fmt", "yuv420p",
|
||||||
|
"-vf", "scale=1920:1080:force_original_aspect_ratio=decrease,"
|
||||||
|
"pad=1920:1080:(ow-iw)/2:(oh-ih)/2",
|
||||||
|
"-c:v", "libx264", "-preset", "medium", "-crf", "20", vid])
|
||||||
|
lf.write(f"file '{vid}'\n")
|
||||||
|
print(f"页视频 {p:02d} {dur:.2f}s ✓")
|
||||||
|
silent = os.path.join(SHOT_DIR, "silent.mp4")
|
||||||
|
run(["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", tmp_list, "-c", "copy", silent])
|
||||||
|
run(["ffmpeg", "-y", "-i", silent, "-i", AUDIO_IN,
|
||||||
|
"-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-shortest", VIDEO_OUT])
|
||||||
|
print(f"\n✅ 视频已输出:{VIDEO_OUT} ({ffprobe_dur(VIDEO_OUT):.1f}s)")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not os.path.exists(AUDIO_IN):
|
||||||
|
print(f"ERROR: 找不到音频 {AUDIO_IN}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
os.makedirs(OUT_DIR, exist_ok=True)
|
||||||
|
print("=== 步骤 1/3:按字符占比分配每页时长 ===")
|
||||||
|
page_dur, _ = step1_page_durations()
|
||||||
|
print("\n=== 步骤 2/3:截取 11 页幻灯片 ===")
|
||||||
|
step2_screenshots()
|
||||||
|
print("\n=== 步骤 3/3:ffmpeg 合成视频 ===")
|
||||||
|
step3_video(page_dur)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"title": "Hermite 多项式:高斯世界里的频率分解工具",
|
||||||
|
"locale": "zh",
|
||||||
|
"lines": [
|
||||||
|
{"speaker": "male", "paragraph": "Hello Deer!欢迎回到我们的节目。今天我们要聊一个听起来很硬核、但其实特别优雅的数学工具——Hermite 多项式。"},
|
||||||
|
{"speaker": "female", "paragraph": "对,很多人一听多项式就想躲。但今天我保证,我们用大白话把它讲明白。先说说,我们为什么要管它?"},
|
||||||
|
{"speaker": "male", "paragraph": "好问题。这要从一个叫 LeJEPA 的自监督学习方法说起。它的核心证明里要回答一件事:编码器把数据映射成一个表示之后,这个表示里到底哪一部分,对所谓的正样本对的相关性贡献最大。"},
|
||||||
|
{"speaker": "female", "paragraph": "正样本对,简单说就是同一个东西的两个不同视角,对吧?模型希望它们的表示尽量像。"},
|
||||||
|
{"speaker": "male", "paragraph": "没错。而要回答哪部分贡献最大,你得先有一把刀,能把任意一个函数拆成一块一块。这就像傅里叶分析,把一段声音拆成不同频率的正弦波。"},
|
||||||
|
{"speaker": "female", "paragraph": "啊,这个类比我喜欢。傅里叶是把周期信号拆成高音、低音。那 Hermite 是拆什么?"},
|
||||||
|
{"speaker": "male", "paragraph": "Hermite 是专门为高斯分布、也就是我们常说的正态分布、钟形曲线,量身定做的拆分工具。当你的数据服从钟形曲线时,Hermite 多项式就是那套最自然的基本积木。"},
|
||||||
|
{"speaker": "female", "paragraph": "所以可以理解成:傅里叶是周期世界的积木,Hermite 是高斯世界的积木。那这些积木长什么样?"},
|
||||||
|
{"speaker": "male", "paragraph": "最前面几块特别简单。第零块就是常数一。第一块就是它本身,z。第二块是 z 的平方再减去一。第三块是 z 的三次方减去三倍的 z。越往后次数越高,但都有规律。"},
|
||||||
|
{"speaker": "female", "paragraph": "有规律就好记。是不是有个递推的套路,能从前面两块推出下一块?"},
|
||||||
|
{"speaker": "male", "paragraph": "正是。下一块等于 z 乘以当前这一块,再减去它的阶数乘以前一块。比如想要第二块,就拿 z 乘第一块的 z,得到 z 平方,再减去一倍的常数一,正好是 z 平方减一。"},
|
||||||
|
{"speaker": "female", "paragraph": "漂亮,自己就能一层层搭上去。那这套积木最关键的本事是什么?"},
|
||||||
|
{"speaker": "male", "paragraph": "最关键的叫正交性。意思是说,任意两块不同阶数的积木,在高斯分布下做平均,它们的乘积平均下来等于零。互不干扰。"},
|
||||||
|
{"speaker": "female", "paragraph": "等一下,这个互不干扰,是不是又跟正弦波很像?不同频率的正弦波相乘积分也是零。"},
|
||||||
|
{"speaker": "male", "paragraph": "完全一样的精神。不同频率的波互不打架;不同阶数的 Hermite 积木也互不打架。只有自己跟自己相乘,平均才不为零,而且那个值正好等于它的阶数的阶乘。"},
|
||||||
|
{"speaker": "female", "paragraph": "能举个最小的例子验证一下吗?让我有点踏实感。"},
|
||||||
|
{"speaker": "male", "paragraph": "当然。拿第一块 z 和第二块 z 平方减一相乘,展开就是 z 的三次方减去 z。在钟形曲线下,所有奇数次方的平均值都是零,所以整体就是零减零,等于零。它俩果然互不干扰。"},
|
||||||
|
{"speaker": "female", "paragraph": "服气。那有了这套互不干扰的积木,是不是任何函数都能用它们拼出来?"},
|
||||||
|
{"speaker": "male", "paragraph": "只要这个函数不太离谱,具体说是它的平方的平均值是有限的,那它就能写成这些积木的加权叠加。每一块前面配一个系数,系数大代表这个函数里那个阶数的成分多。"},
|
||||||
|
{"speaker": "female", "paragraph": "就像把一个向量沿着一组坐标轴分解,每个轴上投影多少。这里的轴就是不同阶数的 Hermite 积木。"},
|
||||||
|
{"speaker": "male", "paragraph": "比喻得非常准。好,现在重头戏来了:为什么这套工具对 LeJEPA 这么要命。"},
|
||||||
|
{"speaker": "female", "paragraph": "我正想问。前面铺垫这么多,关键的转折在哪?"},
|
||||||
|
{"speaker": "male", "paragraph": "关键在于那个生成正样本对的过程,数学上叫 OU 过程。你可以把它想象成:拿原始的表示,乘上一个介于零和一之间的系数,再掺进一点点随机噪声,得到第二个视角。"},
|
||||||
|
{"speaker": "female", "paragraph": "那个介于零和一的系数,我们就叫它相关强度吧。它怎么影响不同阶数的积木?"},
|
||||||
|
{"speaker": "male", "paragraph": "这就是最神奇的地方。线性成分,也就是第一阶,经过这个过程之后,两边的相关性正好等于那个系数本身。但二阶成分的相关性,是这个系数的平方。三阶是三次方。"},
|
||||||
|
{"speaker": "female", "paragraph": "等等,因为这个系数小于一,所以平方会更小,三次方更更小。也就是阶数越高,相关性掉得越快?"},
|
||||||
|
{"speaker": "male", "paragraph": "对,是指数级地掉。高阶的非线性成分,经过这个过程之后几乎就被冲淡没了。只有线性成分保留得最结实。"},
|
||||||
|
{"speaker": "female", "paragraph": "我好像猜到结论了。如果模型的目标是让正样本对的相关性尽可能大……"},
|
||||||
|
{"speaker": "male", "paragraph": "聪明。既然线性成分留下的相关性最高,非线性成分都被打了折扣,那最优策略自然就是:只保留线性成分,把所有非线性成分统统丢掉。"},
|
||||||
|
{"speaker": "female", "paragraph": "所以模型被这个机制温柔地逼着,学成了一个本质上线性的表示。这就是他们那个核心定理的直觉来源。"},
|
||||||
|
{"speaker": "male", "paragraph": "正是。研究者还给了一个很贴心的量,叫谱权重,专门衡量一个表示里每个阶数的成分占了多大比例。"},
|
||||||
|
{"speaker": "female", "paragraph": "谱权重怎么理解?给我个画面感。"},
|
||||||
|
{"speaker": "male", "paragraph": "你就想象一个饼图。整张饼是这个表示的总能量。线性成分切走一块,二阶切走一块,三阶再一块。每一块的占比就是那个阶数的谱权重,所有块加起来正好是百分之百。"},
|
||||||
|
{"speaker": "female", "paragraph": "那如果一个表示是纯线性的,饼图就是线性那一块占满整张,对吧?"},
|
||||||
|
{"speaker": "male", "paragraph": "完全正确。纯线性,线性那块就是百分之百。纯二次,二阶那块占满。混合的,就是好几块都有。而 LeJEPA 想要的理想状态,就是把整张饼都给线性那一块。"},
|
||||||
|
{"speaker": "female", "paragraph": "我帮大家把今天的几个要点串一下。第一,Hermite 多项式是高斯世界里的频率分解工具,类比傅里叶。"},
|
||||||
|
{"speaker": "male", "paragraph": "第二,它最核心的性质是正交性,不同阶数互不干扰,所以任意合理的函数都能干净地拆成这些积木的叠加。"},
|
||||||
|
{"speaker": "female", "paragraph": "第三,那个生成正样本对的 OU 过程,对越高阶的成分削减得越狠,相关性按阶数指数衰减。"},
|
||||||
|
{"speaker": "male", "paragraph": "第四,因此最大化相关性的最优解,就是只留线性成分,这就推出了所谓的线性可识别性,也是整套理论的基石。"},
|
||||||
|
{"speaker": "female", "paragraph": "讲得太顺了。如果听众还想往下走,下一站是什么?"},
|
||||||
|
{"speaker": "male", "paragraph": "下一站就是去看那个相关性按阶数衰减的公式到底从哪来,背后有个叫 Mehler 公式的东西,会把今天这个直觉彻底坐实。"},
|
||||||
|
{"speaker": "female", "paragraph": "好,那我们下期接着聊。谢谢大家收听,记得,数学不可怕,可怕的是没人陪你拆积木。我们下次见!"},
|
||||||
|
{"speaker": "male", "paragraph": "下次见,拜拜!"}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# Hermite 多项式:高斯世界里的频率分解工具(播客文字稿)
|
||||||
|
|
||||||
|
> 来源文档:[`JEPA/math/01_hermite_polynomials.md`](../../../JEPA/math/01_hermite_polynomials.md)
|
||||||
|
> 形式:双主播(男 / 女)对话讲解,约 10 分钟
|
||||||
|
> 配套脚本:[`hermite_polynomials-script.json`](hermite_polynomials-script.json)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**男主播:** Hello Deer!欢迎回到我们的节目。今天我们要聊一个听起来很硬核、但其实特别优雅的数学工具——Hermite 多项式。
|
||||||
|
|
||||||
|
**女主播:** 对,很多人一听多项式就想躲。但今天我保证,我们用大白话把它讲明白。先说说,我们为什么要管它?
|
||||||
|
|
||||||
|
**男主播:** 好问题。这要从一个叫 LeJEPA 的自监督学习方法说起。它的核心证明里要回答一件事:编码器把数据映射成一个表示之后,这个表示里到底哪一部分,对所谓的正样本对的相关性贡献最大。
|
||||||
|
|
||||||
|
**女主播:** 正样本对,简单说就是同一个东西的两个不同视角,对吧?模型希望它们的表示尽量像。
|
||||||
|
|
||||||
|
**男主播:** 没错。而要回答哪部分贡献最大,你得先有一把刀,能把任意一个函数拆成一块一块。这就像傅里叶分析,把一段声音拆成不同频率的正弦波。
|
||||||
|
|
||||||
|
**女主播:** 啊,这个类比我喜欢。傅里叶是把周期信号拆成高音、低音。那 Hermite 是拆什么?
|
||||||
|
|
||||||
|
**男主播:** Hermite 是专门为高斯分布、也就是我们常说的正态分布、钟形曲线,量身定做的拆分工具。当你的数据服从钟形曲线时,Hermite 多项式就是那套最自然的基本积木。
|
||||||
|
|
||||||
|
**女主播:** 所以可以理解成:傅里叶是周期世界的积木,Hermite 是高斯世界的积木。那这些积木长什么样?
|
||||||
|
|
||||||
|
**男主播:** 最前面几块特别简单。第零块就是常数一。第一块就是它本身,z。第二块是 z 的平方再减去一。第三块是 z 的三次方减去三倍的 z。越往后次数越高,但都有规律。
|
||||||
|
|
||||||
|
**女主播:** 有规律就好记。是不是有个递推的套路,能从前面两块推出下一块?
|
||||||
|
|
||||||
|
**男主播:** 正是。下一块等于 z 乘以当前这一块,再减去它的阶数乘以前一块。比如想要第二块,就拿 z 乘第一块的 z,得到 z 平方,再减去一倍的常数一,正好是 z 平方减一。
|
||||||
|
|
||||||
|
**女主播:** 漂亮,自己就能一层层搭上去。那这套积木最关键的本事是什么?
|
||||||
|
|
||||||
|
**男主播:** 最关键的叫正交性。意思是说,任意两块不同阶数的积木,在高斯分布下做平均,它们的乘积平均下来等于零。互不干扰。
|
||||||
|
|
||||||
|
**女主播:** 等一下,这个互不干扰,是不是又跟正弦波很像?不同频率的正弦波相乘积分也是零。
|
||||||
|
|
||||||
|
**男主播:** 完全一样的精神。不同频率的波互不打架;不同阶数的 Hermite 积木也互不打架。只有自己跟自己相乘,平均才不为零,而且那个值正好等于它的阶数的阶乘。
|
||||||
|
|
||||||
|
**女主播:** 能举个最小的例子验证一下吗?让我有点踏实感。
|
||||||
|
|
||||||
|
**男主播:** 当然。拿第一块 z 和第二块 z 平方减一相乘,展开就是 z 的三次方减去 z。在钟形曲线下,所有奇数次方的平均值都是零,所以整体就是零减零,等于零。它俩果然互不干扰。
|
||||||
|
|
||||||
|
**女主播:** 服气。那有了这套互不干扰的积木,是不是任何函数都能用它们拼出来?
|
||||||
|
|
||||||
|
**男主播:** 只要这个函数不太离谱,具体说是它的平方的平均值是有限的,那它就能写成这些积木的加权叠加。每一块前面配一个系数,系数大代表这个函数里那个阶数的成分多。
|
||||||
|
|
||||||
|
**女主播:** 就像把一个向量沿着一组坐标轴分解,每个轴上投影多少。这里的轴就是不同阶数的 Hermite 积木。
|
||||||
|
|
||||||
|
**男主播:** 比喻得非常准。好,现在重头戏来了:为什么这套工具对 LeJEPA 这么要命。
|
||||||
|
|
||||||
|
**女主播:** 我正想问。前面铺垫这么多,关键的转折在哪?
|
||||||
|
|
||||||
|
**男主播:** 关键在于那个生成正样本对的过程,数学上叫 OU 过程。你可以把它想象成:拿原始的表示,乘上一个介于零和一之间的系数,再掺进一点点随机噪声,得到第二个视角。
|
||||||
|
|
||||||
|
**女主播:** 那个介于零和一的系数,我们就叫它相关强度吧。它怎么影响不同阶数的积木?
|
||||||
|
|
||||||
|
**男主播:** 这就是最神奇的地方。线性成分,也就是第一阶,经过这个过程之后,两边的相关性正好等于那个系数本身。但二阶成分的相关性,是这个系数的平方。三阶是三次方。
|
||||||
|
|
||||||
|
**女主播:** 等等,因为这个系数小于一,所以平方会更小,三次方更更小。也就是阶数越高,相关性掉得越快?
|
||||||
|
|
||||||
|
**男主播:** 对,是指数级地掉。高阶的非线性成分,经过这个过程之后几乎就被冲淡没了。只有线性成分保留得最结实。
|
||||||
|
|
||||||
|
**女主播:** 我好像猜到结论了。如果模型的目标是让正样本对的相关性尽可能大……
|
||||||
|
|
||||||
|
**男主播:** 聪明。既然线性成分留下的相关性最高,非线性成分都被打了折扣,那最优策略自然就是:只保留线性成分,把所有非线性成分统统丢掉。
|
||||||
|
|
||||||
|
**女主播:** 所以模型被这个机制温柔地逼着,学成了一个本质上线性的表示。这就是他们那个核心定理的直觉来源。
|
||||||
|
|
||||||
|
**男主播:** 正是。研究者还给了一个很贴心的量,叫谱权重,专门衡量一个表示里每个阶数的成分占了多大比例。
|
||||||
|
|
||||||
|
**女主播:** 谱权重怎么理解?给我个画面感。
|
||||||
|
|
||||||
|
**男主播:** 你就想象一个饼图。整张饼是这个表示的总能量。线性成分切走一块,二阶切走一块,三阶再一块。每一块的占比就是那个阶数的谱权重,所有块加起来正好是百分之百。
|
||||||
|
|
||||||
|
**女主播:** 那如果一个表示是纯线性的,饼图就是线性那一块占满整张,对吧?
|
||||||
|
|
||||||
|
**男主播:** 完全正确。纯线性,线性那块就是百分之百。纯二次,二阶那块占满。混合的,就是好几块都有。而 LeJEPA 想要的理想状态,就是把整张饼都给线性那一块。
|
||||||
|
|
||||||
|
**女主播:** 我帮大家把今天的几个要点串一下。第一,Hermite 多项式是高斯世界里的频率分解工具,类比傅里叶。
|
||||||
|
|
||||||
|
**男主播:** 第二,它最核心的性质是正交性,不同阶数互不干扰,所以任意合理的函数都能干净地拆成这些积木的叠加。
|
||||||
|
|
||||||
|
**女主播:** 第三,那个生成正样本对的 OU 过程,对越高阶的成分削减得越狠,相关性按阶数指数衰减。
|
||||||
|
|
||||||
|
**男主播:** 第四,因此最大化相关性的最优解,就是只留线性成分,这就推出了所谓的线性可识别性,也是整套理论的基石。
|
||||||
|
|
||||||
|
**女主播:** 讲得太顺了。如果听众还想往下走,下一站是什么?
|
||||||
|
|
||||||
|
**男主播:** 下一站就是去看那个相关性按阶数衰减的公式到底从哪来,背后有个叫 Mehler 公式的东西,会把今天这个直觉彻底坐实。
|
||||||
|
|
||||||
|
**女主播:** 好,那我们下期接着聊。谢谢大家收听,记得,数学不可怕,可怕的是没人陪你拆积木。我们下次见!
|
||||||
|
|
||||||
|
**男主播:** 下次见,拜拜!
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Hermite 多项式:高斯世界里的频率分解工具
|
||||||
|
|
||||||
|
**Host (Male)**: Hello Deer!欢迎回到我们的节目。今天我们要聊一个听起来很硬核、但其实特别优雅的数学工具——Hermite 多项式。
|
||||||
|
|
||||||
|
**Host (Female)**: 对,很多人一听多项式就想躲。但今天我保证,我们用大白话把它讲明白。先说说,我们为什么要管它?
|
||||||
|
|
||||||
|
**Host (Male)**: 好问题。这要从一个叫 LeJEPA 的自监督学习方法说起。它的核心证明里要回答一件事:编码器把数据映射成一个表示之后,这个表示里到底哪一部分,对所谓的正样本对的相关性贡献最大。
|
||||||
|
|
||||||
|
**Host (Female)**: 正样本对,简单说就是同一个东西的两个不同视角,对吧?模型希望它们的表示尽量像。
|
||||||
|
|
||||||
|
**Host (Male)**: 没错。而要回答哪部分贡献最大,你得先有一把刀,能把任意一个函数拆成一块一块。这就像傅里叶分析,把一段声音拆成不同频率的正弦波。
|
||||||
|
|
||||||
|
**Host (Female)**: 啊,这个类比我喜欢。傅里叶是把周期信号拆成高音、低音。那 Hermite 是拆什么?
|
||||||
|
|
||||||
|
**Host (Male)**: Hermite 是专门为高斯分布、也就是我们常说的正态分布、钟形曲线,量身定做的拆分工具。当你的数据服从钟形曲线时,Hermite 多项式就是那套最自然的基本积木。
|
||||||
|
|
||||||
|
**Host (Female)**: 所以可以理解成:傅里叶是周期世界的积木,Hermite 是高斯世界的积木。那这些积木长什么样?
|
||||||
|
|
||||||
|
**Host (Male)**: 最前面几块特别简单。第零块就是常数一。第一块就是它本身,z。第二块是 z 的平方再减去一。第三块是 z 的三次方减去三倍的 z。越往后次数越高,但都有规律。
|
||||||
|
|
||||||
|
**Host (Female)**: 有规律就好记。是不是有个递推的套路,能从前面两块推出下一块?
|
||||||
|
|
||||||
|
**Host (Male)**: 正是。下一块等于 z 乘以当前这一块,再减去它的阶数乘以前一块。比如想要第二块,就拿 z 乘第一块的 z,得到 z 平方,再减去一倍的常数一,正好是 z 平方减一。
|
||||||
|
|
||||||
|
**Host (Female)**: 漂亮,自己就能一层层搭上去。那这套积木最关键的本事是什么?
|
||||||
|
|
||||||
|
**Host (Male)**: 最关键的叫正交性。意思是说,任意两块不同阶数的积木,在高斯分布下做平均,它们的乘积平均下来等于零。互不干扰。
|
||||||
|
|
||||||
|
**Host (Female)**: 等一下,这个互不干扰,是不是又跟正弦波很像?不同频率的正弦波相乘积分也是零。
|
||||||
|
|
||||||
|
**Host (Male)**: 完全一样的精神。不同频率的波互不打架;不同阶数的 Hermite 积木也互不打架。只有自己跟自己相乘,平均才不为零,而且那个值正好等于它的阶数的阶乘。
|
||||||
|
|
||||||
|
**Host (Female)**: 能举个最小的例子验证一下吗?让我有点踏实感。
|
||||||
|
|
||||||
|
**Host (Male)**: 当然。拿第一块 z 和第二块 z 平方减一相乘,展开就是 z 的三次方减去 z。在钟形曲线下,所有奇数次方的平均值都是零,所以整体就是零减零,等于零。它俩果然互不干扰。
|
||||||
|
|
||||||
|
**Host (Female)**: 服气。那有了这套互不干扰的积木,是不是任何函数都能用它们拼出来?
|
||||||
|
|
||||||
|
**Host (Male)**: 只要这个函数不太离谱,具体说是它的平方的平均值是有限的,那它就能写成这些积木的加权叠加。每一块前面配一个系数,系数大代表这个函数里那个阶数的成分多。
|
||||||
|
|
||||||
|
**Host (Female)**: 就像把一个向量沿着一组坐标轴分解,每个轴上投影多少。这里的轴就是不同阶数的 Hermite 积木。
|
||||||
|
|
||||||
|
**Host (Male)**: 比喻得非常准。好,现在重头戏来了:为什么这套工具对 LeJEPA 这么要命。
|
||||||
|
|
||||||
|
**Host (Female)**: 我正想问。前面铺垫这么多,关键的转折在哪?
|
||||||
|
|
||||||
|
**Host (Male)**: 关键在于那个生成正样本对的过程,数学上叫 OU 过程。你可以把它想象成:拿原始的表示,乘上一个介于零和一之间的系数,再掺进一点点随机噪声,得到第二个视角。
|
||||||
|
|
||||||
|
**Host (Female)**: 那个介于零和一的系数,我们就叫它相关强度吧。它怎么影响不同阶数的积木?
|
||||||
|
|
||||||
|
**Host (Male)**: 这就是最神奇的地方。线性成分,也就是第一阶,经过这个过程之后,两边的相关性正好等于那个系数本身。但二阶成分的相关性,是这个系数的平方。三阶是三次方。
|
||||||
|
|
||||||
|
**Host (Female)**: 等等,因为这个系数小于一,所以平方会更小,三次方更更小。也就是阶数越高,相关性掉得越快?
|
||||||
|
|
||||||
|
**Host (Male)**: 对,是指数级地掉。高阶的非线性成分,经过这个过程之后几乎就被冲淡没了。只有线性成分保留得最结实。
|
||||||
|
|
||||||
|
**Host (Female)**: 我好像猜到结论了。如果模型的目标是让正样本对的相关性尽可能大……
|
||||||
|
|
||||||
|
**Host (Male)**: 聪明。既然线性成分留下的相关性最高,非线性成分都被打了折扣,那最优策略自然就是:只保留线性成分,把所有非线性成分统统丢掉。
|
||||||
|
|
||||||
|
**Host (Female)**: 所以模型被这个机制温柔地逼着,学成了一个本质上线性的表示。这就是他们那个核心定理的直觉来源。
|
||||||
|
|
||||||
|
**Host (Male)**: 正是。研究者还给了一个很贴心的量,叫谱权重,专门衡量一个表示里每个阶数的成分占了多大比例。
|
||||||
|
|
||||||
|
**Host (Female)**: 谱权重怎么理解?给我个画面感。
|
||||||
|
|
||||||
|
**Host (Male)**: 你就想象一个饼图。整张饼是这个表示的总能量。线性成分切走一块,二阶切走一块,三阶再一块。每一块的占比就是那个阶数的谱权重,所有块加起来正好是百分之百。
|
||||||
|
|
||||||
|
**Host (Female)**: 那如果一个表示是纯线性的,饼图就是线性那一块占满整张,对吧?
|
||||||
|
|
||||||
|
**Host (Male)**: 完全正确。纯线性,线性那块就是百分之百。纯二次,二阶那块占满。混合的,就是好几块都有。而 LeJEPA 想要的理想状态,就是把整张饼都给线性那一块。
|
||||||
|
|
||||||
|
**Host (Female)**: 我帮大家把今天的几个要点串一下。第一,Hermite 多项式是高斯世界里的频率分解工具,类比傅里叶。
|
||||||
|
|
||||||
|
**Host (Male)**: 第二,它最核心的性质是正交性,不同阶数互不干扰,所以任意合理的函数都能干净地拆成这些积木的叠加。
|
||||||
|
|
||||||
|
**Host (Female)**: 第三,那个生成正样本对的 OU 过程,对越高阶的成分削减得越狠,相关性按阶数指数衰减。
|
||||||
|
|
||||||
|
**Host (Male)**: 第四,因此最大化相关性的最优解,就是只留线性成分,这就推出了所谓的线性可识别性,也是整套理论的基石。
|
||||||
|
|
||||||
|
**Host (Female)**: 讲得太顺了。如果听众还想往下走,下一站是什么?
|
||||||
|
|
||||||
|
**Host (Male)**: 下一站就是去看那个相关性按阶数衰减的公式到底从哪来,背后有个叫 Mehler 公式的东西,会把今天这个直觉彻底坐实。
|
||||||
|
|
||||||
|
**Host (Female)**: 好,那我们下期接着聊。谢谢大家收听,记得,数学不可怕,可怕的是没人陪你拆积木。我们下次见!
|
||||||
|
|
||||||
|
**Host (Male)**: 下次见,拜拜!
|
||||||
|
After Width: | Height: | Size: 541 KiB |
|
After Width: | Height: | Size: 590 KiB |
|
After Width: | Height: | Size: 554 KiB |
|
After Width: | Height: | Size: 617 KiB |
|
After Width: | Height: | Size: 548 KiB |
|
After Width: | Height: | Size: 562 KiB |
|
After Width: | Height: | Size: 622 KiB |
|
After Width: | Height: | Size: 584 KiB |
|
After Width: | Height: | Size: 532 KiB |
|
After Width: | Height: | Size: 636 KiB |
|
After Width: | Height: | Size: 532 KiB |
@@ -0,0 +1,259 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Hermite 多项式 · 配套幻灯片 · 风格预览</title>
|
||||||
|
|
||||||
|
<!-- KaTeX 公式渲染 -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<!-- 字体:思源系 + 等宽 -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;900&family=Noto+Sans+SC:wght@300;500;700;900&family=JetBrains+Mono:wght@400;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
*{margin:0;padding:0;box-sizing:border-box;}
|
||||||
|
html,body{width:100%;height:100%;background:#0a0a0c;overflow:hidden;font-family:"Noto Sans SC",sans-serif;}
|
||||||
|
|
||||||
|
/* ---- tab 切换条(在 stage 外,不被 scale 压缩)---- */
|
||||||
|
#tabbar{position:fixed;top:0;left:0;right:0;height:52px;background:#16161a;display:flex;align-items:center;
|
||||||
|
gap:6px;padding:0 18px;z-index:1000;border-bottom:1px solid #2a2a30;}
|
||||||
|
#tabbar .brand{color:#7a7a85;font-size:13px;font-family:"JetBrains Mono",monospace;margin-right:18px;letter-spacing:.05em;}
|
||||||
|
#tabbar button{background:transparent;border:1px solid #34343c;color:#b8b8c0;font-size:13px;padding:7px 16px;
|
||||||
|
border-radius:6px;cursor:pointer;font-family:"Noto Sans SC",sans-serif;transition:.2s;}
|
||||||
|
#tabbar button:hover{border-color:#56566a;color:#fff;}
|
||||||
|
#tabbar button.on{background:#fff;color:#111;border-color:#fff;font-weight:700;}
|
||||||
|
#tabbar .hint{margin-left:auto;color:#55555f;font-size:12px;font-family:"JetBrains Mono",monospace;}
|
||||||
|
|
||||||
|
/* ---- 舞台缩放 ---- */
|
||||||
|
#wrap{position:fixed;top:52px;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;}
|
||||||
|
.stage{width:1920px;height:1080px;transform-origin:center center;position:relative;}
|
||||||
|
.deck{display:none;width:1920px;height:1080px;position:absolute;top:0;left:0;}
|
||||||
|
.deck.show{display:block;}
|
||||||
|
|
||||||
|
/* 每版内部用左右两屏并排展示「封面 + 内容页」缩略 */
|
||||||
|
.pair{display:flex;width:1920px;height:1080px;}
|
||||||
|
.frame{flex:1;height:100%;position:relative;overflow:hidden;}
|
||||||
|
.frame.left{border-right:2px solid rgba(255,255,255,.06);}
|
||||||
|
.flabel{position:absolute;top:22px;left:26px;z-index:5;font-family:"JetBrains Mono",monospace;font-size:18px;
|
||||||
|
letter-spacing:.1em;opacity:.5;}
|
||||||
|
|
||||||
|
.katex{font-size:1em;}
|
||||||
|
|
||||||
|
/* ============ 版 A:深空学术 Deep Space ============ */
|
||||||
|
.A{background:radial-gradient(120% 120% at 75% 15%, #11202a 0%, #0a0e14 55%, #07090d 100%);color:#e8eef2;}
|
||||||
|
.A .glow{position:absolute;width:680px;height:680px;border-radius:50%;
|
||||||
|
background:radial-gradient(circle,rgba(46,196,182,.18),transparent 70%);top:-180px;right:-120px;filter:blur(8px);}
|
||||||
|
.A .cov{padding:120px 100px;height:100%;display:flex;flex-direction:column;justify-content:center;position:relative;}
|
||||||
|
.A .kic{font-family:"JetBrains Mono",monospace;color:#2ec4b6;font-size:26px;letter-spacing:.25em;margin-bottom:28px;}
|
||||||
|
.A .ttl{font-family:"Noto Sans SC";font-weight:900;font-size:118px;line-height:1.04;letter-spacing:-.01em;}
|
||||||
|
.A .ttl em{font-style:normal;color:#2ec4b6;}
|
||||||
|
.A .sub{margin-top:40px;font-size:30px;color:#9fb0ba;font-weight:300;max-width:760px;line-height:1.5;}
|
||||||
|
.A .meta{position:absolute;bottom:80px;left:100px;font-family:"JetBrains Mono",monospace;font-size:20px;color:#56727d;}
|
||||||
|
|
||||||
|
.A2{background:radial-gradient(120% 120% at 20% 90%, #11202a 0%, #0a0e14 60%, #07090d 100%);color:#e8eef2;padding:96px 100px;display:flex;flex-direction:column;}
|
||||||
|
.A2 h2{font-size:74px;font-weight:900;line-height:1.1;}
|
||||||
|
.A2 h2 em{font-style:normal;color:#ffb703;}
|
||||||
|
.A2 .lead{margin-top:18px;font-size:28px;color:#9fb0ba;font-weight:300;}
|
||||||
|
.A2 .body{flex:1;display:flex;align-items:center;gap:60px;margin-top:30px;}
|
||||||
|
.A2 .fbox{flex:1;background:rgba(46,196,182,.06);border:1px solid rgba(46,196,182,.22);border-radius:18px;
|
||||||
|
padding:54px 50px;font-size:46px;color:#eafcf9;text-align:center;}
|
||||||
|
.A2 .fbox .small{font-size:24px;color:#7fd8cf;margin-top:24px;font-family:"JetBrains Mono",monospace;}
|
||||||
|
.A2 .deca{flex:.9;}
|
||||||
|
.A2 .row{display:flex;align-items:center;gap:18px;margin:20px 0;font-size:30px;}
|
||||||
|
.A2 .chip{font-family:"JetBrains Mono",monospace;font-size:24px;padding:6px 16px;border-radius:8px;background:#13343a;color:#2ec4b6;}
|
||||||
|
.A2 .bar{height:14px;border-radius:7px;background:linear-gradient(90deg,#2ec4b6,#ffb703);}
|
||||||
|
|
||||||
|
/* ============ 版 B:黑曜极简 Swiss Mono ============ */
|
||||||
|
.B{background:#0d0d0d;color:#f2f2ef;}
|
||||||
|
.B .cov{padding:110px 110px;height:100%;display:flex;flex-direction:column;position:relative;}
|
||||||
|
.B .topline{display:flex;align-items:center;gap:24px;font-family:"JetBrains Mono",monospace;font-size:20px;color:#888;letter-spacing:.1em;}
|
||||||
|
.B .topline .rule{flex:1;height:1px;background:#3a3a3a;}
|
||||||
|
.B .big{margin-top:auto;font-family:"Noto Serif SC";font-weight:900;font-size:140px;line-height:.98;letter-spacing:-.02em;}
|
||||||
|
.B .big span{display:block;color:#ff5e3a;}
|
||||||
|
.B .cov .foot{margin-top:46px;font-size:28px;color:#9a9a96;font-weight:300;max-width:900px;line-height:1.45;}
|
||||||
|
.B .idx{position:absolute;top:96px;right:110px;font-family:"Space Grotesk";font-size:200px;font-weight:700;color:#161616;line-height:1;}
|
||||||
|
|
||||||
|
.B2{background:#0d0d0d;color:#f2f2ef;padding:96px 110px;display:flex;flex-direction:column;}
|
||||||
|
.B2 .topline{display:flex;align-items:center;gap:24px;font-family:"JetBrains Mono",monospace;font-size:18px;color:#888;letter-spacing:.1em;}
|
||||||
|
.B2 .topline .rule{flex:1;height:1px;background:#3a3a3a;}
|
||||||
|
.B2 h2{margin-top:34px;font-family:"Noto Serif SC";font-weight:900;font-size:86px;line-height:1.02;}
|
||||||
|
.B2 h2 b{color:#ff5e3a;}
|
||||||
|
.B2 .body{flex:1;display:flex;align-items:center;gap:70px;margin-top:20px;}
|
||||||
|
.B2 .fbox{flex:1;border:2px solid #ff5e3a;border-radius:4px;padding:60px 40px;text-align:center;font-size:50px;}
|
||||||
|
.B2 .fbox .small{font-size:24px;color:#bdbdb8;margin-top:26px;font-family:"JetBrains Mono",monospace;letter-spacing:.05em;}
|
||||||
|
.B2 .deca{flex:.85;}
|
||||||
|
.B2 .row{display:flex;align-items:center;gap:20px;font-size:32px;margin:22px 0;font-family:"Noto Sans SC";}
|
||||||
|
.B2 .num{font-family:"Space Grotesk";font-weight:700;font-size:40px;color:#ff5e3a;width:120px;}
|
||||||
|
.B2 .bar{height:10px;background:#ff5e3a;border-radius:2px;}
|
||||||
|
|
||||||
|
/* ============ 版 C:暖纸学刊 Warm Editorial ============ */
|
||||||
|
.C{background:#f4efe6;color:#1d2733;}
|
||||||
|
.C .cov{padding:120px 110px;height:100%;display:grid;grid-template-columns:1fr;align-content:center;position:relative;}
|
||||||
|
.C .tag{font-family:"JetBrains Mono",monospace;font-size:22px;color:#b25d3a;letter-spacing:.2em;margin-bottom:30px;}
|
||||||
|
.C .ttl{font-family:"Noto Serif SC";font-weight:900;font-size:120px;line-height:1.06;color:#16202b;}
|
||||||
|
.C .ttl em{font-style:italic;color:#b25d3a;font-family:"Noto Serif SC";}
|
||||||
|
.C .sub{margin-top:38px;font-size:30px;color:#52606d;font-weight:400;max-width:820px;line-height:1.55;}
|
||||||
|
.C .seal{position:absolute;bottom:90px;right:110px;width:140px;height:140px;border:2px solid #b25d3a;border-radius:50%;
|
||||||
|
display:flex;align-items:center;justify-content:center;text-align:center;font-family:"Noto Serif SC";color:#b25d3a;font-size:20px;line-height:1.3;}
|
||||||
|
.C .ln{position:absolute;left:110px;right:110px;bottom:70px;height:1px;background:#cbbfa9;}
|
||||||
|
|
||||||
|
.C2{background:#f4efe6;color:#1d2733;padding:96px 110px;display:flex;flex-direction:column;}
|
||||||
|
.C2 .tag{font-family:"JetBrains Mono",monospace;font-size:20px;color:#b25d3a;letter-spacing:.18em;}
|
||||||
|
.C2 h2{font-family:"Noto Serif SC";font-weight:900;font-size:80px;line-height:1.08;margin-top:14px;color:#16202b;}
|
||||||
|
.C2 h2 em{font-style:italic;color:#b25d3a;}
|
||||||
|
.C2 .body{flex:1;display:flex;align-items:center;gap:64px;margin-top:24px;}
|
||||||
|
.C2 .fbox{flex:1;background:#fbf8f1;border:1px solid #d8ccb4;border-radius:10px;padding:56px 46px;text-align:center;
|
||||||
|
font-size:48px;color:#1d2733;box-shadow:0 18px 40px -28px rgba(80,60,30,.5);}
|
||||||
|
.C2 .fbox .small{font-size:23px;color:#8a6b4a;margin-top:24px;font-family:"JetBrains Mono",monospace;}
|
||||||
|
.C2 .deca{flex:.9;}
|
||||||
|
.C2 .row{display:flex;align-items:center;gap:18px;font-size:30px;margin:20px 0;}
|
||||||
|
.C2 .chip{font-family:"Noto Serif SC";font-weight:600;font-size:26px;color:#b25d3a;width:90px;}
|
||||||
|
.C2 .bar{height:12px;border-radius:6px;background:linear-gradient(90deg,#b25d3a,#d9a441);}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="tabbar">
|
||||||
|
<span class="brand">HERMITE · 风格预览</span>
|
||||||
|
<button class="on" data-deck="A">A · 深空学术</button>
|
||||||
|
<button data-deck="B">B · 黑曜极简</button>
|
||||||
|
<button data-deck="C">C · 暖纸学刊</button>
|
||||||
|
<span class="hint">每版=封面 + 典型内容页(OU 衰减)|选定后展开完整版</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="stage" id="stage">
|
||||||
|
|
||||||
|
<!-- ===================== 版 A ===================== -->
|
||||||
|
<div class="deck show" data-deck="A">
|
||||||
|
<div class="pair">
|
||||||
|
<div class="frame left A">
|
||||||
|
<span class="flabel">封面</span>
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="cov">
|
||||||
|
<div class="kic">SELF-SUPERVISED · 谱分解</div>
|
||||||
|
<div class="ttl">Hermite<br><em>多项式</em></div>
|
||||||
|
<div class="sub">高斯世界里的「频率分解」工具——配套播客讲解</div>
|
||||||
|
<div class="meta">EP.01 · 时长 7:43 · LeJEPA 理论基石</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="frame A2">
|
||||||
|
<span class="flabel">内容页</span>
|
||||||
|
<h2>为什么<em>线性</em>成分最值钱</h2>
|
||||||
|
<div class="lead">OU 过程让相关性按阶数指数衰减</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="fbox">
|
||||||
|
$\mathbb{E}[He_n(z')\,He_n(z)] = \rho^{\,n} \cdot n!$
|
||||||
|
<div class="small">阶数越高 → 相关性掉得越快</div>
|
||||||
|
</div>
|
||||||
|
<div class="deca">
|
||||||
|
<div class="row"><span class="chip">1 阶</span><div class="bar" style="width:88%"></div></div>
|
||||||
|
<div class="row"><span class="chip">2 阶</span><div class="bar" style="width:48%"></div></div>
|
||||||
|
<div class="row"><span class="chip">3 阶</span><div class="bar" style="width:24%"></div></div>
|
||||||
|
<div class="row" style="font-size:24px;color:#9fb0ba;margin-top:30px;">最优解:只保留线性成分 → 线性可识别性</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ===================== 版 B ===================== -->
|
||||||
|
<div class="deck" data-deck="B">
|
||||||
|
<div class="pair">
|
||||||
|
<div class="frame left B">
|
||||||
|
<span class="flabel" style="color:#fff">封面</span>
|
||||||
|
<div class="cov">
|
||||||
|
<div class="idx">He</div>
|
||||||
|
<div class="topline"><span>谱分解 / SPECTRAL</span><span class="rule"></span><span>EP.01</span></div>
|
||||||
|
<div class="big">埃尔米特<span>多项式</span></div>
|
||||||
|
<div class="foot">高斯世界里的频率分解工具 —— 配套播客讲解 · 7 分 43 秒</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="frame B2">
|
||||||
|
<span class="flabel" style="color:#fff">内容页</span>
|
||||||
|
<div class="topline"><span>05 / OU 衰减</span><span class="rule"></span><span>ρⁿ</span></div>
|
||||||
|
<h2>为什么<b>线性</b>成分最值钱</h2>
|
||||||
|
<div class="body">
|
||||||
|
<div class="fbox">
|
||||||
|
$\mathbb{E}[He_n(z')\,He_n(z)] = \rho^{\,n} n!$
|
||||||
|
<div class="small">阶数越高 → 衰减越快</div>
|
||||||
|
</div>
|
||||||
|
<div class="deca">
|
||||||
|
<div class="row"><span class="num">ρ¹</span><div class="bar" style="width:90%"></div></div>
|
||||||
|
<div class="row"><span class="num">ρ²</span><div class="bar" style="width:46%"></div></div>
|
||||||
|
<div class="row"><span class="num">ρ³</span><div class="bar" style="width:22%"></div></div>
|
||||||
|
<div class="row" style="font-size:26px;color:#9a9a96;margin-top:28px;">→ 只留线性 = 线性可识别性</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ===================== 版 C ===================== -->
|
||||||
|
<div class="deck" data-deck="C">
|
||||||
|
<div class="pair">
|
||||||
|
<div class="frame left C">
|
||||||
|
<span class="flabel" style="color:#b25d3a">封面</span>
|
||||||
|
<div class="cov">
|
||||||
|
<div class="tag">SPECTRAL DECOMPOSITION · 第一讲</div>
|
||||||
|
<div class="ttl">Hermite <em>多项式</em></div>
|
||||||
|
<div class="sub">高斯世界里的「频率分解」工具<br>配套播客讲解 · 全长 7 分 43 秒</div>
|
||||||
|
<div class="seal">谱<br>分解</div>
|
||||||
|
<div class="ln"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="frame C2">
|
||||||
|
<span class="flabel" style="color:#b25d3a">内容页</span>
|
||||||
|
<div class="tag">05 · OU 过程与衰减</div>
|
||||||
|
<h2>为什么<em>线性</em>成分最值钱</h2>
|
||||||
|
<div class="body">
|
||||||
|
<div class="fbox">
|
||||||
|
$\mathbb{E}[He_n(z')\,He_n(z)] = \rho^{\,n}\, n!$
|
||||||
|
<div class="small">阶数越高,相关性指数衰减</div>
|
||||||
|
</div>
|
||||||
|
<div class="deca">
|
||||||
|
<div class="row"><span class="chip">ρ¹</span><div class="bar" style="width:90%"></div></div>
|
||||||
|
<div class="row"><span class="chip">ρ²</span><div class="bar" style="width:46%"></div></div>
|
||||||
|
<div class="row"><span class="chip">ρ³</span><div class="bar" style="width:22%"></div></div>
|
||||||
|
<div class="row" style="font-size:24px;color:#6b5640;margin-top:28px;">最优策略:只保留线性 → 线性可识别性</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 舞台自适应缩放
|
||||||
|
function fit(){
|
||||||
|
const s=Math.min((window.innerWidth)/1920,(window.innerHeight-52)/1080);
|
||||||
|
document.getElementById('stage').style.transform=`scale(${s})`;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize',fit); fit();
|
||||||
|
|
||||||
|
// tab 切换
|
||||||
|
document.querySelectorAll('#tabbar button').forEach(b=>{
|
||||||
|
b.addEventListener('click',()=>{
|
||||||
|
const d=b.dataset.deck;
|
||||||
|
document.querySelectorAll('#tabbar button').forEach(x=>x.classList.toggle('on',x===b));
|
||||||
|
document.querySelectorAll('.deck').forEach(x=>x.classList.toggle('show',x.dataset.deck===d));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// KaTeX 渲染
|
||||||
|
window.addEventListener('DOMContentLoaded',()=>{
|
||||||
|
function r(){ if(window.renderMathInElement){
|
||||||
|
renderMathInElement(document.body,{delimiters:[{left:'$',right:'$',display:false}]});
|
||||||
|
} else setTimeout(r,120); }
|
||||||
|
r();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,405 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Hermite 多项式 · 高斯世界里的频率分解工具</title>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
设计系统(深空学术 Deep Space)
|
||||||
|
背景:radial #11202a → #0a0e14 → #07090d(暗青底,章节用不同 glow 方位制造节奏)
|
||||||
|
色:primary 青绿 #2ec4b6 / accent 琥珀 #ffb703 / 文本 #e8eef2 / 次级 #9fb0ba / mono #56727d
|
||||||
|
字:标题 Noto Sans SC 900;正文 Noto Sans SC 300/500;公式与标签 JetBrains Mono / KaTeX
|
||||||
|
字号:H1 110-118 / H2 70-78 / 卡标题 34-40 / 正文 26-30 / mono 18-22(震撼态,整体偏大)
|
||||||
|
节奏:封面=大字+留白;类比/正交=卡片;OU/谱权重=图形化条;小结=网格。
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;500;700;900&family=JetBrains+Mono:wght@400;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
*{margin:0;padding:0;box-sizing:border-box;}
|
||||||
|
:root{
|
||||||
|
--bg0:#07090d; --teal:#2ec4b6; --amber:#ffb703;
|
||||||
|
--ink:#e8eef2; --ink2:#9fb0ba; --mono:#56727d; --line:rgba(255,255,255,.08);
|
||||||
|
}
|
||||||
|
html,body{width:100%;height:100%;background:var(--bg0);overflow:hidden;
|
||||||
|
font-family:"Noto Sans SC",sans-serif;color:var(--ink);}
|
||||||
|
|
||||||
|
/* 舞台缩放 */
|
||||||
|
#wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;}
|
||||||
|
.stage{width:1920px;height:1080px;transform-origin:center center;position:relative;}
|
||||||
|
|
||||||
|
.slide{position:absolute;inset:0;padding:96px 110px 120px;display:flex;flex-direction:column;
|
||||||
|
background:radial-gradient(120% 120% at 75% 12%, #11202a 0%, #0a0e14 56%, #07090d 100%);}
|
||||||
|
.slide:not(.active){display:none !important;}
|
||||||
|
.slide.posBL{background:radial-gradient(120% 120% at 18% 92%, #11202a 0%, #0a0e14 60%, #07090d 100%);}
|
||||||
|
.slide.posCR{background:radial-gradient(130% 130% at 95% 50%, #12232c 0%, #0a0e14 58%, #07090d 100%);}
|
||||||
|
|
||||||
|
.glow{position:absolute;width:620px;height:620px;border-radius:50%;pointer-events:none;
|
||||||
|
background:radial-gradient(circle,rgba(46,196,182,.16),transparent 70%);top:-160px;right:-110px;filter:blur(6px);}
|
||||||
|
.glow.amber{background:radial-gradient(circle,rgba(255,183,3,.13),transparent 70%);}
|
||||||
|
|
||||||
|
/* 页眉小标 + 页脚 */
|
||||||
|
.kicker{font-family:"JetBrains Mono",monospace;color:var(--teal);font-size:22px;letter-spacing:.18em;
|
||||||
|
text-transform:uppercase;display:flex;align-items:center;gap:16px;}
|
||||||
|
.kicker .ln{width:54px;height:2px;background:var(--teal);opacity:.7;}
|
||||||
|
.page-footer{position:absolute;left:110px;right:110px;bottom:60px;display:flex;justify-content:space-between;
|
||||||
|
align-items:center;font-family:"JetBrains Mono",monospace;font-size:18px;color:var(--mono);}
|
||||||
|
.page-footer .prog{flex:1;margin:0 30px;height:2px;background:rgba(255,255,255,.08);position:relative;border-radius:2px;}
|
||||||
|
.page-footer .prog i{position:absolute;left:0;top:0;height:100%;background:linear-gradient(90deg,var(--teal),var(--amber));border-radius:2px;transition:width .4s;}
|
||||||
|
|
||||||
|
h1{font-weight:900;font-size:116px;line-height:1.03;letter-spacing:-.01em;}
|
||||||
|
h1 em{font-style:normal;color:var(--teal);}
|
||||||
|
h2{font-weight:900;font-size:74px;line-height:1.08;margin-top:22px;}
|
||||||
|
h2 em{font-style:normal;color:var(--amber);}
|
||||||
|
.lead{font-size:29px;color:var(--ink2);font-weight:300;margin-top:18px;line-height:1.5;max-width:1300px;}
|
||||||
|
|
||||||
|
.content{flex:1;display:flex;align-items:center;min-height:0;}
|
||||||
|
|
||||||
|
.katex{font-size:1em;}
|
||||||
|
.fbox{background:rgba(46,196,182,.06);border:1px solid rgba(46,196,182,.24);border-radius:18px;
|
||||||
|
padding:46px 44px;text-align:center;color:#eafcf9;}
|
||||||
|
.fbox .small{font-size:23px;color:#7fd8cf;margin-top:22px;font-family:"JetBrains Mono",monospace;}
|
||||||
|
|
||||||
|
/* 通用卡片 */
|
||||||
|
.cards{display:flex;gap:36px;width:100%;}
|
||||||
|
.card{flex:1;background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:18px;padding:42px 38px;}
|
||||||
|
.card .ct{font-size:36px;font-weight:700;margin-bottom:18px;}
|
||||||
|
.card .cb{font-size:26px;color:var(--ink2);font-weight:300;line-height:1.55;}
|
||||||
|
.card .cf{margin-top:22px;font-size:30px;color:var(--teal);}
|
||||||
|
|
||||||
|
/* 封面 */
|
||||||
|
.cover{justify-content:center;}
|
||||||
|
.cover .meta{position:absolute;bottom:72px;left:110px;font-family:"JetBrains Mono",monospace;font-size:21px;color:var(--mono);}
|
||||||
|
|
||||||
|
/* 衰减条 */
|
||||||
|
.barrow{display:flex;align-items:center;gap:20px;margin:22px 0;font-size:30px;}
|
||||||
|
.barrow .chip{font-family:"JetBrains Mono",monospace;font-size:24px;padding:7px 16px;border-radius:8px;
|
||||||
|
background:#13343a;color:var(--teal);min-width:96px;text-align:center;}
|
||||||
|
.barrow .track{flex:1;height:16px;border-radius:8px;background:rgba(255,255,255,.06);position:relative;overflow:hidden;}
|
||||||
|
.barrow .track i{position:absolute;left:0;top:0;height:100%;border-radius:8px;
|
||||||
|
background:linear-gradient(90deg,var(--teal),var(--amber));}
|
||||||
|
.barrow .val{font-family:"JetBrains Mono",monospace;font-size:24px;color:var(--ink2);min-width:70px;}
|
||||||
|
|
||||||
|
/* 表格类比 */
|
||||||
|
table.cmp{width:100%;border-collapse:collapse;font-size:28px;}
|
||||||
|
table.cmp th,table.cmp td{padding:24px 26px;text-align:left;border-bottom:1px solid var(--line);}
|
||||||
|
table.cmp th{font-family:"JetBrains Mono",monospace;font-size:22px;color:var(--mono);letter-spacing:.08em;font-weight:400;}
|
||||||
|
table.cmp td.k{color:var(--ink2);font-weight:300;width:24%;}
|
||||||
|
table.cmp td .fr{color:var(--teal);}
|
||||||
|
table.cmp td .he{color:var(--amber);}
|
||||||
|
|
||||||
|
/* 谱权重饼图 */
|
||||||
|
.pie{width:340px;height:340px;border-radius:50%;flex-shrink:0;}
|
||||||
|
.legend{margin-left:60px;}
|
||||||
|
.legend .li{display:flex;align-items:center;gap:18px;font-size:30px;margin:18px 0;}
|
||||||
|
.legend .dot{width:26px;height:26px;border-radius:6px;}
|
||||||
|
|
||||||
|
/* 列表 */
|
||||||
|
ul.pts{list-style:none;}
|
||||||
|
ul.pts li{font-size:31px;font-weight:300;color:var(--ink);line-height:1.5;margin:24px 0;padding-left:46px;position:relative;}
|
||||||
|
ul.pts li::before{content:"";position:absolute;left:0;top:16px;width:22px;height:22px;border-radius:6px;
|
||||||
|
background:linear-gradient(135deg,var(--teal),var(--amber));}
|
||||||
|
ul.pts li b{color:var(--teal);font-weight:700;}
|
||||||
|
|
||||||
|
/* 小结网格 */
|
||||||
|
.grid4{display:grid;grid-template-columns:1fr 1fr;gap:30px;width:100%;}
|
||||||
|
.grid4 .g{background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:16px;padding:34px 34px;}
|
||||||
|
.grid4 .g .n{font-family:"Space Grotesk";font-weight:700;font-size:40px;color:var(--teal);}
|
||||||
|
.grid4 .g .t{font-size:28px;margin-top:8px;line-height:1.45;color:var(--ink);font-weight:300;}
|
||||||
|
.grid4 .g .t b{color:var(--amber);font-weight:700;}
|
||||||
|
|
||||||
|
/* 导航键(在 stage 外,避免被 scale 压缩)*/
|
||||||
|
.nav{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:900;display:flex;gap:10px;align-items:center;}
|
||||||
|
.nav button{background:#16242b;border:1px solid #2a3c44;color:#cfe;font-size:15px;padding:9px 18px;border-radius:8px;cursor:pointer;font-family:"JetBrains Mono",monospace;}
|
||||||
|
.nav button:hover{background:#1d3038;}
|
||||||
|
.nav .pg{color:#6f8a93;font-family:"JetBrains Mono",monospace;font-size:14px;padding:0 8px;}
|
||||||
|
.hintkey{position:fixed;top:14px;right:18px;z-index:900;color:#42535b;font-family:"JetBrains Mono",monospace;font-size:13px;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="hintkey">← → 翻页 · F 全屏 · 刷新记忆当前页</div>
|
||||||
|
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="stage" id="stage">
|
||||||
|
|
||||||
|
<!-- 1 封面 -->
|
||||||
|
<section class="slide active cover">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>SELF-SUPERVISED · 谱分解 · EP.01</div>
|
||||||
|
<h1 style="margin-top:34px;">Hermite<br><em>多项式</em></h1>
|
||||||
|
<p class="lead" style="margin-top:38px;">高斯世界里的「频率分解」工具<br>—— 配套播客讲解,从直觉到 LeJEPA 的理论基石</p>
|
||||||
|
<div class="meta">配套音频 7:43 · 双主播对话 · 数学不可怕,可怕的是没人陪你拆积木</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 2 动机 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>01 · 动机</div>
|
||||||
|
<h2>我们需要一把<em>拆函数的刀</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<ul class="pts">
|
||||||
|
<li>LeJEPA 的证明要回答:编码器的表示里,<b>哪一部分</b>对「正样本对」的相关性贡献最大?</li>
|
||||||
|
<li>正样本对 = 同一内容的两个视角,模型希望它们的表示尽量像。</li>
|
||||||
|
<li>要回答这个问题,得先能把<b>任意函数拆成一块块</b>——就像傅里叶把声音拆成不同频率的波。</li>
|
||||||
|
<li>在高斯(钟形)分布下,这套「积木」就是 <b>Hermite 多项式</b>。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 3 傅里叶类比 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>02 · 类比</div>
|
||||||
|
<h2>傅里叶之于周期,<em>Hermite</em> 之于高斯</h2>
|
||||||
|
<div class="content">
|
||||||
|
<table class="cmp">
|
||||||
|
<tr><th>维度</th><th>傅里叶级数</th><th>Hermite 展开</th></tr>
|
||||||
|
<tr><td class="k">适用场景</td><td><span class="fr">周期函数</span></td><td><span class="he">高斯分布下的函数</span></td></tr>
|
||||||
|
<tr><td class="k">基函数</td><td><span class="fr">$\sin nx,\ \cos nx$</span></td><td><span class="he">$He_0,He_1,He_2,\dots$</span></td></tr>
|
||||||
|
<tr><td class="k">正交性</td><td><span class="fr">在区间上积分为 0</span></td><td><span class="he">在高斯期望下为 0</span></td></tr>
|
||||||
|
<tr><td class="k">完备性</td><td><span class="fr">任意周期函数可展开</span></td><td><span class="he">任意 $L^2(\gamma)$ 函数可展开</span></td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 4 定义与递推 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>03 · 定义</div>
|
||||||
|
<h2>积木长什么样 & <em>递推</em>搭出来</h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="fbox" style="flex:1;font-size:34px;line-height:2;">
|
||||||
|
$He_0=1,\quad He_1=z$<br>
|
||||||
|
$He_2=z^2-1$<br>
|
||||||
|
$He_3=z^3-3z$<br>
|
||||||
|
$He_4=z^4-6z^2+3$
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<div class="fbox" style="font-size:40px;">
|
||||||
|
$He_{n+1}(z)=z\,He_n(z)-n\,He_{n-1}(z)$
|
||||||
|
<div class="small">下一块 = z × 当前块 − 阶数 × 前一块</div>
|
||||||
|
</div>
|
||||||
|
<p class="lead" style="margin-top:30px;font-size:26px;">验证:$z\cdot z-1\cdot 1=z^2-1=He_2$ ✓</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 5 正交性 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>04 · 核心性质</div>
|
||||||
|
<h2>正交性:不同阶数<em>互不干扰</em></h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="fbox" style="flex:1.1;font-size:34px;">
|
||||||
|
$\mathbb{E}\big[He_m(z)\,He_n(z)\big]=\begin{cases}n! & m=n\\[4pt]0 & m\neq n\end{cases}$
|
||||||
|
<div class="small">$z\sim\mathcal N(0,1)$,期望对钟形曲线取</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="ct">最小例子验证</div>
|
||||||
|
<div class="cb" style="font-size:28px;line-height:1.8;">
|
||||||
|
$\mathbb{E}[He_1\cdot He_2]=\mathbb{E}[z^3-z]$<br>
|
||||||
|
高斯的奇数阶矩为 0 → $=0-0=0$ ✓
|
||||||
|
</div>
|
||||||
|
<div class="cf" style="font-size:26px;">就像不同频率的正弦波互相正交</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 6 完备性 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>05 · 完备性</div>
|
||||||
|
<h2>任意函数都能<em>拆开重组</em></h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="fbox" style="flex:1;font-size:36px;">
|
||||||
|
$h(z)=\sum_{d=0}^{\infty}c_d\,He_d(z)$
|
||||||
|
<div class="small">$c_d=\dfrac{\mathbb{E}[h(z)\,He_d(z)]}{d!}$</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<p class="lead" style="font-size:30px;">只要 $\mathbb{E}[h(z)^2]<\infty$(有限能量),就能写成这些积木的<b style="color:var(--teal)">加权叠加</b>。</p>
|
||||||
|
<p class="lead" style="font-size:30px;margin-top:24px;">就像把一个向量沿正交坐标轴分解——每个轴上投影多少,系数 $c_d$ 就有多大。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 7 OU 衰减 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>06 · 关键转折</div>
|
||||||
|
<h2>OU 过程让相关性<em>按阶数指数衰减</em></h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="fbox" style="flex:.95;font-size:34px;">
|
||||||
|
$\mathbb{E}[He_n(z')He_n(z)]=\rho^{\,n}\cdot n!$
|
||||||
|
<div class="small">$z'=\rho z+\sqrt{1-\rho^2}\,\eta,\quad 0<\rho<1$</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1.05;">
|
||||||
|
<div class="barrow"><span class="chip">1 阶</span><div class="track"><i style="width:90%"></i></div><span class="val">ρ¹</span></div>
|
||||||
|
<div class="barrow"><span class="chip">2 阶</span><div class="track"><i style="width:50%"></i></div><span class="val">ρ²</span></div>
|
||||||
|
<div class="barrow"><span class="chip">3 阶</span><div class="track"><i style="width:26%"></i></div><span class="val">ρ³</span></div>
|
||||||
|
<p class="lead" style="font-size:26px;margin-top:18px;">阶数越高 → 相关性掉得越快 → 高阶非线性几乎被冲淡。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 8 线性可识别性 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>07 · 结论</div>
|
||||||
|
<h2>最优解:<em>只保留线性成分</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<ul class="pts">
|
||||||
|
<li>对齐损失要<b>最大化</b>正样本对的相关性。</li>
|
||||||
|
<li>线性成分贡献 $\rho$;非线性成分贡献 $\rho^d<\rho\ (d\ge 2)$,被打了折扣。</li>
|
||||||
|
<li>于是最优策略就是:<b>留下线性,丢掉所有非线性</b>。</li>
|
||||||
|
<li>模型被这个机制温柔地逼成一个本质线性的表示 —— 这就是<b>线性可识别性</b>,整套定理的直觉来源。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 9 谱权重 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>08 · 度量工具</div>
|
||||||
|
<h2>谱权重:一张<em>能量饼图</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<div class="pie" style="background:conic-gradient(var(--teal) 0 62%, var(--amber) 62% 84%, #4a6b74 84% 100%);"></div>
|
||||||
|
<div class="legend">
|
||||||
|
<div class="li"><span class="dot" style="background:var(--teal)"></span>线性 $w_1$ —— 我们想要的成分</div>
|
||||||
|
<div class="li"><span class="dot" style="background:var(--amber)"></span>二阶 $w_2$ —— 被 OU 衰减更多</div>
|
||||||
|
<div class="li"><span class="dot" style="background:#4a6b74"></span>更高阶 —— 衰减最狠</div>
|
||||||
|
<div class="li" style="font-size:24px;color:var(--ink2);margin-top:14px;font-family:'JetBrains Mono',monospace;">
|
||||||
|
$w_d\ge 0,\quad w_0=0,\quad \textstyle\sum w_d=1$</div>
|
||||||
|
<div class="li" style="font-size:25px;color:var(--ink2);">理想状态:整张饼都给线性那一块。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 10 小结 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>09 · 小结</div>
|
||||||
|
<h2>四句话<em>带走全场</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<div class="grid4">
|
||||||
|
<div class="g"><div class="n">01</div><div class="t">Hermite 是高斯世界的<b>频率分解工具</b>,类比傅里叶。</div></div>
|
||||||
|
<div class="g"><div class="n">02</div><div class="t"><b>正交性</b>让任意合理函数都能干净地拆成这些积木叠加。</div></div>
|
||||||
|
<div class="g"><div class="n">03</div><div class="t">OU 过程使相关性按 <b>ρᵈ</b> 指数衰减,高阶削减更狠。</div></div>
|
||||||
|
<div class="g"><div class="n">04</div><div class="t">最大化相关性 → 只留线性 → <b>线性可识别性</b>。</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 11 尾页 -->
|
||||||
|
<section class="slide cover posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>下一站</div>
|
||||||
|
<h1 style="font-size:92px;margin-top:30px;">Mehler 公式<br><em>把直觉坐实</em></h1>
|
||||||
|
<p class="lead" style="margin-top:34px;font-size:30px;">下一讲深入 $\rho^d$ 衰减的来源 —— 它来自 OU 过程的转移核在 Hermite 基下的展开。</p>
|
||||||
|
<div class="meta">谢谢收听 · 配套音频 hermite_polynomials-podcast.mp3 · 我们下次见</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="nav">
|
||||||
|
<button id="prev">← 上一页</button>
|
||||||
|
<span class="pg" id="pg">1 / 11</span>
|
||||||
|
<button id="next">下一页 →</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const STAGE = document.getElementById('stage');
|
||||||
|
const slides = Array.from(document.querySelectorAll('.slide'));
|
||||||
|
const total = slides.length;
|
||||||
|
const KEY = 'hermite_deck_page';
|
||||||
|
|
||||||
|
// 读回上次页码
|
||||||
|
let cur = parseInt(localStorage.getItem(KEY) || '0', 10);
|
||||||
|
if (isNaN(cur) || cur < 0 || cur >= total) cur = 0;
|
||||||
|
|
||||||
|
function fit(){
|
||||||
|
const s = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
|
||||||
|
STAGE.style.transform = `scale(${s})`;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', fit); fit();
|
||||||
|
|
||||||
|
function show(i){
|
||||||
|
cur = (i + total) % total;
|
||||||
|
slides.forEach((s, idx) => s.classList.toggle('active', idx === cur));
|
||||||
|
document.getElementById('pg').textContent = `${cur + 1} / ${total}`;
|
||||||
|
// 进度条
|
||||||
|
const w = ((cur) / (total - 1) * 100).toFixed(1) + '%';
|
||||||
|
document.querySelectorAll('.page-footer .prog i').forEach(b => b.style.width = w);
|
||||||
|
localStorage.setItem(KEY, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给每页注入页脚(带进度条)—— 封面/尾页也加,保持节奏统一
|
||||||
|
slides.forEach((s, idx) => {
|
||||||
|
const f = document.createElement('div');
|
||||||
|
f.className = 'page-footer';
|
||||||
|
f.innerHTML = `<span>Hermite 多项式 · 谱分解</span><span class="prog"><i></i></span><span>${String(idx+1).padStart(2,'0')} / ${String(total).padStart(2,'0')}</span>`;
|
||||||
|
s.appendChild(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('prev').addEventListener('click', () => show(cur - 1));
|
||||||
|
document.getElementById('next').addEventListener('click', () => show(cur + 1));
|
||||||
|
|
||||||
|
// 键盘
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); show(cur + 1); }
|
||||||
|
else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); show(cur - 1); }
|
||||||
|
else if (e.key === 'Home') show(0);
|
||||||
|
else if (e.key === 'End') show(total - 1);
|
||||||
|
else if (e.key === 'f' || e.key === 'F') {
|
||||||
|
if (!document.fullscreenElement) document.documentElement.requestFullscreen();
|
||||||
|
else document.exitFullscreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点击舞台右/左半屏翻页
|
||||||
|
document.getElementById('wrap').addEventListener('click', (e) => {
|
||||||
|
if (e.target.closest('.nav')) return;
|
||||||
|
if (e.clientX > window.innerWidth * 0.5) show(cur + 1); else show(cur - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// KaTeX 渲染
|
||||||
|
function renderMath(){
|
||||||
|
if (window.renderMathInElement){
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
delimiters: [
|
||||||
|
{left:'$$', right:'$$', display:true},
|
||||||
|
{left:'$', right:'$', display:false}
|
||||||
|
],
|
||||||
|
throwOnError:false
|
||||||
|
});
|
||||||
|
} else { setTimeout(renderMath, 120); }
|
||||||
|
}
|
||||||
|
// URL 参数:?page=N(1-based 定位单页,用于截图/导出)、?clean=1(隐藏 UI)
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const pageParam = params.get('page');
|
||||||
|
if (pageParam !== null) {
|
||||||
|
const p = parseInt(pageParam, 10);
|
||||||
|
if (!isNaN(p) && p >= 1 && p <= total) cur = p - 1;
|
||||||
|
}
|
||||||
|
if (params.get('clean') === '1') {
|
||||||
|
document.body.classList.add('clean');
|
||||||
|
const navEl = document.querySelector('.nav'); if (navEl) navEl.style.display = 'none';
|
||||||
|
const hk = document.querySelector('.hintkey'); if (hk) hk.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', () => { renderMath(); show(cur); });
|
||||||
|
// 兜底:若 DOMContentLoaded 已过
|
||||||
|
if (document.readyState !== 'loading') { renderMath(); show(cur); }
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""用火山引擎 v3 单向流式 TTS(/api/v3/tts/unidirectional)把双人对话脚本合成为一个 MP3。
|
||||||
|
|
||||||
|
鉴权:请求头 x-api-key + X-Api-Resource-Id(新版方式,区别于旧版 Bearer;{token})。
|
||||||
|
用法:
|
||||||
|
VOLC_API_KEY=<你的key> python3 synth_volc_v3.py \
|
||||||
|
--script-file hermite_polynomials-script.json \
|
||||||
|
--output-file output/hermite_polynomials-podcast.mp3
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
ENDPOINT = "https://openspeech.bytedance.com/api/v3/tts/unidirectional"
|
||||||
|
RESOURCE_ID = "volc.service_type.10029"
|
||||||
|
|
||||||
|
# 男女两个大模型情感音色(v2 mars bigtts)
|
||||||
|
VOICE_MALE = "zh_male_beijingxiaoye_emo_v2_mars_bigtts"
|
||||||
|
VOICE_FEMALE = "zh_female_roumeinvyou_emo_v2_mars_bigtts"
|
||||||
|
|
||||||
|
ADDITIONS = json.dumps(
|
||||||
|
{
|
||||||
|
"disable_markdown_filter": True,
|
||||||
|
"enable_language_detector": True,
|
||||||
|
"enable_latex_tn": True,
|
||||||
|
"disable_default_bit_rate": True,
|
||||||
|
"max_length_to_filter_parenthesis": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def synth_line(api_key: str, text: str, speaker: str, retries: int = 3) -> bytes:
|
||||||
|
"""合成一句,返回 mp3 字节。失败抛异常。"""
|
||||||
|
headers = {
|
||||||
|
"x-api-key": api_key,
|
||||||
|
"X-Api-Resource-Id": RESOURCE_ID,
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
"req_params": {
|
||||||
|
"text": text,
|
||||||
|
"speaker": speaker,
|
||||||
|
"additions": ADDITIONS,
|
||||||
|
"audio_params": {"format": "mp3", "sample_rate": 24000},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_err = None
|
||||||
|
for attempt in range(retries):
|
||||||
|
try:
|
||||||
|
r = requests.post(ENDPOINT, headers=headers, json=payload, timeout=60)
|
||||||
|
if r.status_code != 200:
|
||||||
|
last_err = f"HTTP {r.status_code}: {r.text[:200]}"
|
||||||
|
time.sleep(1.0 + attempt)
|
||||||
|
continue
|
||||||
|
# 响应体可能是单个 JSON,也可能是多段(流式)。逐段解析 data 累积。
|
||||||
|
audio = b""
|
||||||
|
text_body = r.text.strip()
|
||||||
|
# 尝试按行分割的多 JSON(流式 unidirectional 常见)
|
||||||
|
chunks = []
|
||||||
|
for line in text_body.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
chunks.append(line)
|
||||||
|
if not chunks:
|
||||||
|
chunks = [text_body]
|
||||||
|
ok = False
|
||||||
|
for c in chunks:
|
||||||
|
try:
|
||||||
|
obj = json.loads(c)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
if obj.get("code") not in (0, None):
|
||||||
|
last_err = f"code={obj.get('code')} msg={obj.get('message')}"
|
||||||
|
continue
|
||||||
|
d = obj.get("data")
|
||||||
|
if d:
|
||||||
|
audio += base64.b64decode(d)
|
||||||
|
ok = True
|
||||||
|
if ok and audio:
|
||||||
|
return audio
|
||||||
|
last_err = last_err or "no audio data in response"
|
||||||
|
time.sleep(1.0 + attempt)
|
||||||
|
except Exception as e: # noqa
|
||||||
|
last_err = str(e)
|
||||||
|
time.sleep(1.0 + attempt)
|
||||||
|
raise RuntimeError(f"合成失败: {last_err}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("--script-file", required=True)
|
||||||
|
ap.add_argument("--output-file", required=True)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
api_key = os.getenv("VOLC_API_KEY")
|
||||||
|
if not api_key:
|
||||||
|
print("ERROR: 需要环境变量 VOLC_API_KEY", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
with open(args.script_file, encoding="utf-8") as f:
|
||||||
|
script = json.load(f)
|
||||||
|
lines = script["lines"]
|
||||||
|
total = len(lines)
|
||||||
|
print(f"加载脚本:{script.get('title','')},共 {total} 句")
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(args.output_file) or ".", exist_ok=True)
|
||||||
|
|
||||||
|
all_audio = b""
|
||||||
|
ok_count = 0
|
||||||
|
for i, line in enumerate(lines, 1):
|
||||||
|
speaker = VOICE_MALE if line["speaker"] == "male" else VOICE_FEMALE
|
||||||
|
text = line["paragraph"]
|
||||||
|
try:
|
||||||
|
audio = synth_line(api_key, text, speaker)
|
||||||
|
all_audio += audio
|
||||||
|
ok_count += 1
|
||||||
|
print(f"[{i}/{total}] {line['speaker']:6s} ok ({len(audio)} bytes)")
|
||||||
|
except Exception as e: # noqa
|
||||||
|
print(f"[{i}/{total}] {line['speaker']:6s} FAIL: {e}")
|
||||||
|
time.sleep(0.15) # 轻微限速
|
||||||
|
|
||||||
|
if not all_audio:
|
||||||
|
print("ERROR: 没有任何一句合成成功", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(args.output_file, "wb") as f:
|
||||||
|
f.write(all_audio)
|
||||||
|
print(f"\n完成:{ok_count}/{total} 句成功,已写出 {args.output_file}({len(all_audio)} bytes)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""把 OU/Mehler 幻灯片 + 已有播客音频合成为 MP4(复用第一篇流程)。
|
||||||
|
|
||||||
|
流程:读已有音频时长 → 按每句字符占比分配到 12 页 → Chrome 截 12 页 → ffmpeg 合成。
|
||||||
|
用法:python3 build_video2.py
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
SCRIPT_JSON = os.path.join(HERE, "ou_mehler-script.json")
|
||||||
|
SLIDE_HTML = os.path.join(HERE, "slides", "OU 过程与 Mehler 公式.html")
|
||||||
|
OUT_DIR = os.path.join(HERE, "output")
|
||||||
|
SHOT_DIR = os.path.join(OUT_DIR, "shots")
|
||||||
|
AUDIO_IN = os.path.join(OUT_DIR, "ou_mehler-podcast.mp3")
|
||||||
|
VIDEO_OUT = os.path.join(OUT_DIR, "ou_mehler-video.mp4")
|
||||||
|
CHROME = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||||
|
|
||||||
|
NUM_PAGES = 12
|
||||||
|
# 句(1-based) -> 页(1-based)。共 44 句、12 页。
|
||||||
|
# 1 封面 / 2 核心问题 / 3 OU直觉 / 4 离散定义 / 5 三性质 / 6 Mehler / 7 核心推论
|
||||||
|
# 8 数值例子 / 9 对齐损失 / 10 衰减图 / 11 小结 / 12 尾页
|
||||||
|
LINE_TO_PAGE = {
|
||||||
|
1: 1, 2: 1, # 封面
|
||||||
|
3: 2, # 核心问题
|
||||||
|
4: 3, 5: 3, 6: 3, # OU 物理直觉
|
||||||
|
7: 4, 8: 4, 9: 4, # 离散定义
|
||||||
|
10: 5, 11: 5, 12: 5, 13: 5, 14: 5, 15: 5, # 三性质
|
||||||
|
16: 6, 17: 6, 18: 6, 19: 6, 20: 6, # Mehler 公式
|
||||||
|
21: 7, 22: 7, 23: 7, # 核心推论
|
||||||
|
24: 8, 25: 8, 26: 8, 27: 8, 28: 8, 29: 8, # 数值例子
|
||||||
|
30: 9, 31: 9, 32: 9, 33: 9, 34: 9, # 对齐损失
|
||||||
|
35: 10, 36: 10, # 衰减图示
|
||||||
|
37: 11, 38: 11, 39: 11, 40: 11, 41: 11, # 小结
|
||||||
|
42: 12, 43: 12, 44: 12, # 尾页
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run(cmd):
|
||||||
|
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
|
||||||
|
def ffprobe_dur(path):
|
||||||
|
out = subprocess.check_output(
|
||||||
|
["ffprobe", "-v", "error", "-show_entries", "format=duration",
|
||||||
|
"-of", "default=noprint_wrappers=1:nokey=1", path])
|
||||||
|
return float(out.strip())
|
||||||
|
|
||||||
|
|
||||||
|
def step1_page_durations():
|
||||||
|
total = ffprobe_dur(AUDIO_IN)
|
||||||
|
lines = json.load(open(SCRIPT_JSON, encoding="utf-8"))["lines"]
|
||||||
|
page_chars = {p: 0 for p in range(1, NUM_PAGES + 1)}
|
||||||
|
for i, line in enumerate(lines, 1):
|
||||||
|
page_chars[LINE_TO_PAGE.get(i, NUM_PAGES)] += len(line["paragraph"].strip())
|
||||||
|
grand = sum(page_chars.values())
|
||||||
|
page_dur = {p: total * page_chars[p] / grand for p in page_chars}
|
||||||
|
page_dur[NUM_PAGES] += (total - sum(page_dur.values()))
|
||||||
|
print(f"音频总时长 {total:.2f}s,分配到 {NUM_PAGES} 页:")
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
print(f" page {p:>2}: {page_dur[p]:6.2f}s ({page_chars[p]} 字)")
|
||||||
|
return page_dur
|
||||||
|
|
||||||
|
|
||||||
|
def step2_screenshots():
|
||||||
|
os.makedirs(SHOT_DIR, exist_ok=True)
|
||||||
|
file_url = "file://" + SLIDE_HTML.replace(" ", "%20")
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
out = os.path.join(SHOT_DIR, f"page_{p:02d}.png")
|
||||||
|
run([CHROME, "--headless=new", "--disable-gpu", "--hide-scrollbars",
|
||||||
|
"--force-device-scale-factor=1", "--window-size=1920,1080",
|
||||||
|
f"--screenshot={out}", "--virtual-time-budget=2800",
|
||||||
|
f"{file_url}?page={p}&clean=1"])
|
||||||
|
if not os.path.exists(out):
|
||||||
|
raise RuntimeError(f"截图失败 page {p}")
|
||||||
|
print(f"截图 page {p:02d} ✓")
|
||||||
|
|
||||||
|
|
||||||
|
def step3_video(page_dur):
|
||||||
|
tmp_list = os.path.join(SHOT_DIR, "vlist.txt")
|
||||||
|
with open(tmp_list, "w") as lf:
|
||||||
|
for p in range(1, NUM_PAGES + 1):
|
||||||
|
img = os.path.join(SHOT_DIR, f"page_{p:02d}.png")
|
||||||
|
dur = max(page_dur[p], 0.8)
|
||||||
|
vid = os.path.join(SHOT_DIR, f"v_{p:02d}.mp4")
|
||||||
|
run(["ffmpeg", "-y", "-loop", "1", "-i", img, "-t", f"{dur:.3f}",
|
||||||
|
"-r", "30", "-pix_fmt", "yuv420p",
|
||||||
|
"-vf", "scale=1920:1080:force_original_aspect_ratio=decrease,"
|
||||||
|
"pad=1920:1080:(ow-iw)/2:(oh-ih)/2",
|
||||||
|
"-c:v", "libx264", "-preset", "medium", "-crf", "20", vid])
|
||||||
|
lf.write(f"file '{vid}'\n")
|
||||||
|
print(f"页视频 {p:02d} {dur:.2f}s ✓")
|
||||||
|
silent = os.path.join(SHOT_DIR, "silent.mp4")
|
||||||
|
run(["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", tmp_list, "-c", "copy", silent])
|
||||||
|
run(["ffmpeg", "-y", "-i", silent, "-i", AUDIO_IN,
|
||||||
|
"-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-shortest", VIDEO_OUT])
|
||||||
|
print(f"\n✅ 视频已输出:{VIDEO_OUT} ({ffprobe_dur(VIDEO_OUT):.1f}s)")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not os.path.exists(AUDIO_IN):
|
||||||
|
print(f"ERROR: 找不到音频 {AUDIO_IN}", file=sys.stderr); sys.exit(1)
|
||||||
|
print("=== 步骤 1/3:分配每页时长 ===")
|
||||||
|
page_dur = step1_page_durations()
|
||||||
|
print("\n=== 步骤 2/3:截取 12 页 ===")
|
||||||
|
step2_screenshots()
|
||||||
|
print("\n=== 步骤 3/3:ffmpeg 合成 ===")
|
||||||
|
step3_video(page_dur)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"title": "OU 过程与 Mehler 公式:为什么高阶成分被罚得更狠",
|
||||||
|
"locale": "zh",
|
||||||
|
"lines": [
|
||||||
|
{"speaker": "male", "paragraph": "Hello Deer!欢迎回来。上一期我们聊了 Hermite 多项式,留了个尾巴——相关性为什么会按阶数指数衰减。今天就来把这个坑填上。"},
|
||||||
|
{"speaker": "female", "paragraph": "对,上次最后那个悬念我一直惦记着。今天的主角是两个名字,OU 过程和 Mehler 公式。先说说,它们是用来干嘛的?"},
|
||||||
|
{"speaker": "male", "paragraph": "LeJEPA 训练时需要正样本对,也就是同一个内容的两个视角。问题是:这两个视角是怎么造出来的?为什么这种造法会让高阶的非线性成分被惩罚得更重?"},
|
||||||
|
{"speaker": "female", "paragraph": "造正样本对的办法,就是 OU 过程,全名奥恩斯坦-乌伦贝克过程。这名字有点吓人,但物理图像其实很可爱对吧?"},
|
||||||
|
{"speaker": "male", "paragraph": "非常可爱。你就想象一个小球,被一根弹簧拴在原点。弹簧一直想把它拉回中心,这叫均值回归;同时周围有随机的小扰动在推它,像布朗运动。"},
|
||||||
|
{"speaker": "female", "paragraph": "所以小球既被往回拉、又被随机推。这一拉一推的拉扯,就是 OU 过程。那它在 LeJEPA 里具体长什么样?"},
|
||||||
|
{"speaker": "male", "paragraph": "论文用的是离散版本,一步到位:新的视角 z 撇,等于 ρ 乘以原来的 z,再加上根号下一减 ρ 平方,乘一个全新的高斯噪声。"},
|
||||||
|
{"speaker": "female", "paragraph": "这里的 ρ 是关键,介于零和一之间。它就是上一期我们叫的相关强度,对吧?"},
|
||||||
|
{"speaker": "male", "paragraph": "正是。ρ 越接近一,新视角就越像原来的;ρ 越接近零,两个视角就越不相关。实践里一般取零点八到零点九五之间。"},
|
||||||
|
{"speaker": "female", "paragraph": "明白。那这个造法有几个很妙的性质,我们一个个说。第一个是平稳性?"},
|
||||||
|
{"speaker": "male", "paragraph": "对。如果原来的 z 服从标准高斯,那么造出来的 z 撇也服从同一个标准高斯。算一下就知道:均值还是零,方差还是一,因为 ρ 平方加上一减 ρ 平方正好等于一。"},
|
||||||
|
{"speaker": "female", "paragraph": "漂亮,造完之后分布纹丝不动。这意味着两个视角是平起平坐的,没有谁更特殊。第二个性质呢?"},
|
||||||
|
{"speaker": "male", "paragraph": "第二个是相关性可控。两个视角的协方差正好等于 ρ。所以 ρ 就像一个旋钮,你拧大它两个视角就更像,拧小就更不像,完全在你掌控之中。"},
|
||||||
|
{"speaker": "female", "paragraph": "一个旋钮控制相似度,这设计真干净。第三个性质?"},
|
||||||
|
{"speaker": "male", "paragraph": "第三个叫加性噪声。整个转移可以拆成两块:一块是线性漂移 ρ 乘 z,另一块是独立的噪声。干净的线性加噪声结构,正好满足论文要的假设。"},
|
||||||
|
{"speaker": "female", "paragraph": "好,三个性质都很温和。那真正的硬核来了——Mehler 公式。它到底说了什么?"},
|
||||||
|
{"speaker": "male", "paragraph": "Mehler 公式是 OU 过程的谱定理。一句话说:它把 OU 过程的转移规律,在 Hermite 这套积木的基底下展开了,而且每一阶积木前面的系数,正好是 ρ 的那一阶次方。"},
|
||||||
|
{"speaker": "female", "paragraph": "等等,让我抓住重点:d 阶的 Hermite 成分,前面挂的系数是 ρ 的 d 次方?"},
|
||||||
|
{"speaker": "male", "paragraph": "完全正确。这就是全部魔法的来源。把它用到编码器的某个分量上,就得到一个特别干净的式子:两个视角在这个分量上的相关性,等于各阶谱权重乘以 ρ 的对应次方,再全部加起来。"},
|
||||||
|
{"speaker": "female", "paragraph": "谱权重我们上期讲过,就是那张能量饼图里每一阶占的比例。那现在把这个和数跟 ρ 比一比,会怎样?"},
|
||||||
|
{"speaker": "male", "paragraph": "这就是核心推论。因为每一项里 ρ 的 d 次方都小于等于 ρ 本身——d 至少是一嘛——所以整个加权和一定小于等于 ρ。而所有权重加起来是一,所以上界恰好就是 ρ。"},
|
||||||
|
{"speaker": "female", "paragraph": "所以相关性最多就是 ρ,封顶了。那什么时候能正好取到这个上限?"},
|
||||||
|
{"speaker": "male", "paragraph": "只有一种情况:全部权重都压在一阶上,也就是编码器是纯线性的。只要有任何一个二阶或更高阶的权重大于零,那一项就会严格变小,整个和就够不到 ρ 了。"},
|
||||||
|
{"speaker": "female", "paragraph": "所以等号成立,当且仅当纯线性。这个当且仅当太关键了。我们来点具体数字找找感觉?"},
|
||||||
|
{"speaker": "male", "paragraph": "好。取 ρ 等于零点九。纯线性编码器,相关性就是零点九的一次方,等于零点九,完美顶到上限。"},
|
||||||
|
{"speaker": "female", "paragraph": "纯二次的呢?"},
|
||||||
|
{"speaker": "male", "paragraph": "纯二次,相关性是零点九的平方,等于零点八一,已经掉了零点零九。纯三次是零点九的三次方,约零点七三,掉得更多。"},
|
||||||
|
{"speaker": "female", "paragraph": "那要是一半线性、一半二次的混合呢?"},
|
||||||
|
{"speaker": "male", "paragraph": "混合的就是两者加权平均,零点五乘零点九加零点五乘零点八一,约等于零点八五五。介于两者之间,但仍然够不到零点九。结论很清楚:非线性成分越多,相关性越低。"},
|
||||||
|
{"speaker": "female", "paragraph": "数字一摆,趋势一目了然。那这跟 LeJEPA 真正要优化的目标,是怎么挂上钩的?"},
|
||||||
|
{"speaker": "male", "paragraph": "LeJEPA 的对齐损失,本质是让两个视角的表示尽量接近,写开之后就等于一个常数减去所有分量相关性的总和。所以最小化损失,就等价于最大化相关性总和。"},
|
||||||
|
{"speaker": "female", "paragraph": "而我们刚证明了每个相关性最多是 ρ……"},
|
||||||
|
{"speaker": "male", "paragraph": "对,所以对齐损失有一个下界,正比于一减 ρ。而这个最好的下界,当且仅当每一个编码器分量都是线性的时候才能达到。"},
|
||||||
|
{"speaker": "female", "paragraph": "于是结论就水落石出了:最优编码器必须是线性的。这正是定理一的心脏。"},
|
||||||
|
{"speaker": "male", "paragraph": "一点没错。我们再用一张画面感的图收一下尾:ρ 等于零点九时,一阶零点九、二阶零点八一、三阶零点七三、四阶零点六六、五阶零点五九,像一排越来越短的条。"},
|
||||||
|
{"speaker": "female", "paragraph": "非线性成分的相关性随阶数指数往下掉,越高阶越吃亏。这画面我记住了。我们把今天五个要点串一下?"},
|
||||||
|
{"speaker": "male", "paragraph": "第一,OU 过程用一拉一推的方式造正样本对,相似度由 ρ 这个旋钮控制。"},
|
||||||
|
{"speaker": "female", "paragraph": "第二,平稳性保证两个视角分布相同;相关性恰好是 ρ;结构是线性漂移加独立噪声。"},
|
||||||
|
{"speaker": "male", "paragraph": "第三,Mehler 公式说,d 阶 Hermite 成分的相关性是 ρ 的 d 次方。"},
|
||||||
|
{"speaker": "female", "paragraph": "第四,核心不等式:相关性等于各阶权重乘 ρ 的对应次方之和,最多到 ρ,等号当且仅当纯线性。"},
|
||||||
|
{"speaker": "male", "paragraph": "第五,因此最小化对齐损失就是最大化相关性,逼着编码器学成线性——这就是定理一。"},
|
||||||
|
{"speaker": "female", "paragraph": "完美闭环。下一站去哪?"},
|
||||||
|
{"speaker": "male", "paragraph": "下一讲我们把 Hermite 展开和今天的 OU 衰减正式拼起来,组装成定理一的完整证明,叫谱分解与线性可识别性。"},
|
||||||
|
{"speaker": "female", "paragraph": "好,那我们下期见。谢谢大家收听,记得,弹簧拉小球,ρ 拧大小——我们下次接着拆。拜拜!"}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# OU 过程与 Mehler 公式:为什么高阶成分被罚得更狠(播客文字稿)
|
||||||
|
|
||||||
|
> 来源文档:[`JEPA/math/02_ou_process_mehler.md`](../../../JEPA/math/02_ou_process_mehler.md)
|
||||||
|
> 形式:双主播(男 / 女)对话讲解,约 8 分钟
|
||||||
|
> 配套脚本:[`ou_mehler-script.json`](ou_mehler-script.json)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**男主播:** Hello Deer!欢迎回来。上一期我们聊了 Hermite 多项式,留了个尾巴——相关性为什么会按阶数指数衰减。今天就来把这个坑填上。
|
||||||
|
|
||||||
|
**女主播:** 对,上次最后那个悬念我一直惦记着。今天的主角是两个名字,OU 过程和 Mehler 公式。先说说,它们是用来干嘛的?
|
||||||
|
|
||||||
|
**男主播:** LeJEPA 训练时需要正样本对,也就是同一个内容的两个视角。问题是:这两个视角是怎么造出来的?为什么这种造法会让高阶的非线性成分被惩罚得更重?
|
||||||
|
|
||||||
|
**女主播:** 造正样本对的办法,就是 OU 过程,全名奥恩斯坦-乌伦贝克过程。这名字有点吓人,但物理图像其实很可爱对吧?
|
||||||
|
|
||||||
|
**男主播:** 非常可爱。你就想象一个小球,被一根弹簧拴在原点。弹簧一直想把它拉回中心,这叫均值回归;同时周围有随机的小扰动在推它,像布朗运动。
|
||||||
|
|
||||||
|
**女主播:** 所以小球既被往回拉、又被随机推。这一拉一推的拉扯,就是 OU 过程。那它在 LeJEPA 里具体长什么样?
|
||||||
|
|
||||||
|
**男主播:** 论文用的是离散版本,一步到位:新的视角 z 撇,等于 ρ 乘以原来的 z,再加上根号下一减 ρ 平方,乘一个全新的高斯噪声。
|
||||||
|
|
||||||
|
**女主播:** 这里的 ρ 是关键,介于零和一之间。它就是上一期我们叫的相关强度,对吧?
|
||||||
|
|
||||||
|
**男主播:** 正是。ρ 越接近一,新视角就越像原来的;ρ 越接近零,两个视角就越不相关。实践里一般取零点八到零点九五之间。
|
||||||
|
|
||||||
|
**女主播:** 明白。那这个造法有几个很妙的性质,我们一个个说。第一个是平稳性?
|
||||||
|
|
||||||
|
**男主播:** 对。如果原来的 z 服从标准高斯,那么造出来的 z 撇也服从同一个标准高斯。算一下就知道:均值还是零,方差还是一,因为 ρ 平方加上一减 ρ 平方正好等于一。
|
||||||
|
|
||||||
|
**女主播:** 漂亮,造完之后分布纹丝不动。这意味着两个视角是平起平坐的,没有谁更特殊。第二个性质呢?
|
||||||
|
|
||||||
|
**男主播:** 第二个是相关性可控。两个视角的协方差正好等于 ρ。所以 ρ 就像一个旋钮,你拧大它两个视角就更像,拧小就更不像,完全在你掌控之中。
|
||||||
|
|
||||||
|
**女主播:** 一个旋钮控制相似度,这设计真干净。第三个性质?
|
||||||
|
|
||||||
|
**男主播:** 第三个叫加性噪声。整个转移可以拆成两块:一块是线性漂移 ρ 乘 z,另一块是独立的噪声。干净的线性加噪声结构,正好满足论文要的假设。
|
||||||
|
|
||||||
|
**女主播:** 好,三个性质都很温和。那真正的硬核来了——Mehler 公式。它到底说了什么?
|
||||||
|
|
||||||
|
**男主播:** Mehler 公式是 OU 过程的谱定理。一句话说:它把 OU 过程的转移规律,在 Hermite 这套积木的基底下展开了,而且每一阶积木前面的系数,正好是 ρ 的那一阶次方。
|
||||||
|
|
||||||
|
**女主播:** 等等,让我抓住重点:d 阶的 Hermite 成分,前面挂的系数是 ρ 的 d 次方?
|
||||||
|
|
||||||
|
**男主播:** 完全正确。这就是全部魔法的来源。把它用到编码器的某个分量上,就得到一个特别干净的式子:两个视角在这个分量上的相关性,等于各阶谱权重乘以 ρ 的对应次方,再全部加起来。
|
||||||
|
|
||||||
|
**女主播:** 谱权重我们上期讲过,就是那张能量饼图里每一阶占的比例。那现在把这个和数跟 ρ 比一比,会怎样?
|
||||||
|
|
||||||
|
**男主播:** 这就是核心推论。因为每一项里 ρ 的 d 次方都小于等于 ρ 本身——d 至少是一嘛——所以整个加权和一定小于等于 ρ。而所有权重加起来是一,所以上界恰好就是 ρ。
|
||||||
|
|
||||||
|
**女主播:** 所以相关性最多就是 ρ,封顶了。那什么时候能正好取到这个上限?
|
||||||
|
|
||||||
|
**男主播:** 只有一种情况:全部权重都压在一阶上,也就是编码器是纯线性的。只要有任何一个二阶或更高阶的权重大于零,那一项就会严格变小,整个和就够不到 ρ 了。
|
||||||
|
|
||||||
|
**女主播:** 所以等号成立,当且仅当纯线性。这个当且仅当太关键了。我们来点具体数字找找感觉?
|
||||||
|
|
||||||
|
**男主播:** 好。取 ρ 等于零点九。纯线性编码器,相关性就是零点九的一次方,等于零点九,完美顶到上限。
|
||||||
|
|
||||||
|
**女主播:** 纯二次的呢?
|
||||||
|
|
||||||
|
**男主播:** 纯二次,相关性是零点九的平方,等于零点八一,已经掉了零点零九。纯三次是零点九的三次方,约零点七三,掉得更多。
|
||||||
|
|
||||||
|
**女主播:** 那要是一半线性、一半二次的混合呢?
|
||||||
|
|
||||||
|
**男主播:** 混合的就是两者加权平均,零点五乘零点九加零点五乘零点八一,约等于零点八五五。介于两者之间,但仍然够不到零点九。结论很清楚:非线性成分越多,相关性越低。
|
||||||
|
|
||||||
|
**女主播:** 数字一摆,趋势一目了然。那这跟 LeJEPA 真正要优化的目标,是怎么挂上钩的?
|
||||||
|
|
||||||
|
**男主播:** LeJEPA 的对齐损失,本质是让两个视角的表示尽量接近,写开之后就等于一个常数减去所有分量相关性的总和。所以最小化损失,就等价于最大化相关性总和。
|
||||||
|
|
||||||
|
**女主播:** 而我们刚证明了每个相关性最多是 ρ……
|
||||||
|
|
||||||
|
**男主播:** 对,所以对齐损失有一个下界,正比于一减 ρ。而这个最好的下界,当且仅当每一个编码器分量都是线性的时候才能达到。
|
||||||
|
|
||||||
|
**女主播:** 于是结论就水落石出了:最优编码器必须是线性的。这正是定理一的心脏。
|
||||||
|
|
||||||
|
**男主播:** 一点没错。我们再用一张画面感的图收一下尾:ρ 等于零点九时,一阶零点九、二阶零点八一、三阶零点七三、四阶零点六六、五阶零点五九,像一排越来越短的条。
|
||||||
|
|
||||||
|
**女主播:** 非线性成分的相关性随阶数指数往下掉,越高阶越吃亏。这画面我记住了。我们把今天五个要点串一下?
|
||||||
|
|
||||||
|
**男主播:** 第一,OU 过程用一拉一推的方式造正样本对,相似度由 ρ 这个旋钮控制。
|
||||||
|
|
||||||
|
**女主播:** 第二,平稳性保证两个视角分布相同;相关性恰好是 ρ;结构是线性漂移加独立噪声。
|
||||||
|
|
||||||
|
**男主播:** 第三,Mehler 公式说,d 阶 Hermite 成分的相关性是 ρ 的 d 次方。
|
||||||
|
|
||||||
|
**女主播:** 第四,核心不等式:相关性等于各阶权重乘 ρ 的对应次方之和,最多到 ρ,等号当且仅当纯线性。
|
||||||
|
|
||||||
|
**男主播:** 第五,因此最小化对齐损失就是最大化相关性,逼着编码器学成线性——这就是定理一。
|
||||||
|
|
||||||
|
**女主播:** 完美闭环。下一站去哪?
|
||||||
|
|
||||||
|
**男主播:** 下一讲我们把 Hermite 展开和今天的 OU 衰减正式拼起来,组装成定理一的完整证明,叫谱分解与线性可识别性。
|
||||||
|
|
||||||
|
**女主播:** 好,那我们下期见。谢谢大家收听,记得,弹簧拉小球,ρ 拧大小——我们下次接着拆。拜拜!
|
||||||
|
After Width: | Height: | Size: 537 KiB |
|
After Width: | Height: | Size: 554 KiB |
|
After Width: | Height: | Size: 540 KiB |
|
After Width: | Height: | Size: 618 KiB |
|
After Width: | Height: | Size: 543 KiB |
|
After Width: | Height: | Size: 550 KiB |
|
After Width: | Height: | Size: 609 KiB |
|
After Width: | Height: | Size: 543 KiB |
|
After Width: | Height: | Size: 534 KiB |
|
After Width: | Height: | Size: 626 KiB |
|
After Width: | Height: | Size: 562 KiB |
|
After Width: | Height: | Size: 530 KiB |
@@ -0,0 +1,357 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>OU 过程与 Mehler 公式 · 为什么高阶成分被罚得更狠</title>
|
||||||
|
|
||||||
|
<!-- 设计系统沿用「深空学术 Deep Space」:暗青径向底 + 青绿 #2ec4b6 / 琥珀 #ffb703 -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;500;700;900&family=JetBrains+Mono:wght@400;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
*{margin:0;padding:0;box-sizing:border-box;}
|
||||||
|
:root{--bg0:#07090d;--teal:#2ec4b6;--amber:#ffb703;--ink:#e8eef2;--ink2:#9fb0ba;--mono:#56727d;--line:rgba(255,255,255,.08);}
|
||||||
|
html,body{width:100%;height:100%;background:var(--bg0);overflow:hidden;font-family:"Noto Sans SC",sans-serif;color:var(--ink);}
|
||||||
|
#wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;}
|
||||||
|
.stage{width:1920px;height:1080px;transform-origin:center center;position:relative;}
|
||||||
|
.slide{position:absolute;inset:0;padding:96px 110px 120px;display:flex;flex-direction:column;
|
||||||
|
background:radial-gradient(120% 120% at 75% 12%, #11202a 0%, #0a0e14 56%, #07090d 100%);}
|
||||||
|
.slide:not(.active){display:none !important;}
|
||||||
|
.slide.posBL{background:radial-gradient(120% 120% at 18% 92%, #11202a 0%, #0a0e14 60%, #07090d 100%);}
|
||||||
|
.slide.posCR{background:radial-gradient(130% 130% at 95% 50%, #12232c 0%, #0a0e14 58%, #07090d 100%);}
|
||||||
|
.glow{position:absolute;width:620px;height:620px;border-radius:50%;pointer-events:none;
|
||||||
|
background:radial-gradient(circle,rgba(46,196,182,.16),transparent 70%);top:-160px;right:-110px;filter:blur(6px);}
|
||||||
|
.glow.amber{background:radial-gradient(circle,rgba(255,183,3,.13),transparent 70%);}
|
||||||
|
.kicker{font-family:"JetBrains Mono",monospace;color:var(--teal);font-size:22px;letter-spacing:.18em;text-transform:uppercase;display:flex;align-items:center;gap:16px;}
|
||||||
|
.kicker .ln{width:54px;height:2px;background:var(--teal);opacity:.7;}
|
||||||
|
.page-footer{position:absolute;left:110px;right:110px;bottom:60px;display:flex;justify-content:space-between;align-items:center;font-family:"JetBrains Mono",monospace;font-size:18px;color:var(--mono);}
|
||||||
|
.page-footer .prog{flex:1;margin:0 30px;height:2px;background:rgba(255,255,255,.08);position:relative;border-radius:2px;}
|
||||||
|
.page-footer .prog i{position:absolute;left:0;top:0;height:100%;background:linear-gradient(90deg,var(--teal),var(--amber));border-radius:2px;transition:width .4s;}
|
||||||
|
h1{font-weight:900;font-size:112px;line-height:1.03;letter-spacing:-.01em;}
|
||||||
|
h1 em{font-style:normal;color:var(--teal);}
|
||||||
|
h2{font-weight:900;font-size:72px;line-height:1.08;margin-top:22px;}
|
||||||
|
h2 em{font-style:normal;color:var(--amber);}
|
||||||
|
.lead{font-size:29px;color:var(--ink2);font-weight:300;margin-top:18px;line-height:1.5;max-width:1320px;}
|
||||||
|
.content{flex:1;display:flex;align-items:center;min-height:0;}
|
||||||
|
.katex{font-size:1em;}
|
||||||
|
.fbox{background:rgba(46,196,182,.06);border:1px solid rgba(46,196,182,.24);border-radius:18px;padding:46px 44px;text-align:center;color:#eafcf9;}
|
||||||
|
.fbox .small{font-size:23px;color:#7fd8cf;margin-top:22px;font-family:"JetBrains Mono",monospace;}
|
||||||
|
.cards{display:flex;gap:36px;width:100%;}
|
||||||
|
.card{flex:1;background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:18px;padding:40px 36px;}
|
||||||
|
.card .ct{font-size:34px;font-weight:700;margin-bottom:16px;color:var(--teal);}
|
||||||
|
.card .cb{font-size:25px;color:var(--ink2);font-weight:300;line-height:1.55;}
|
||||||
|
.barrow{display:flex;align-items:center;gap:20px;margin:18px 0;font-size:30px;}
|
||||||
|
.barrow .chip{font-family:"JetBrains Mono",monospace;font-size:23px;padding:7px 15px;border-radius:8px;background:#13343a;color:var(--teal);min-width:120px;text-align:center;}
|
||||||
|
.barrow .track{flex:1;height:16px;border-radius:8px;background:rgba(255,255,255,.06);position:relative;overflow:hidden;}
|
||||||
|
.barrow .track i{position:absolute;left:0;top:0;height:100%;border-radius:8px;background:linear-gradient(90deg,var(--teal),var(--amber));}
|
||||||
|
.barrow .val{font-family:"JetBrains Mono",monospace;font-size:23px;color:var(--ink2);min-width:120px;}
|
||||||
|
ul.pts{list-style:none;}
|
||||||
|
ul.pts li{font-size:31px;font-weight:300;color:var(--ink);line-height:1.5;margin:22px 0;padding-left:46px;position:relative;}
|
||||||
|
ul.pts li::before{content:"";position:absolute;left:0;top:16px;width:22px;height:22px;border-radius:6px;background:linear-gradient(135deg,var(--teal),var(--amber));}
|
||||||
|
ul.pts li b{color:var(--teal);font-weight:700;}
|
||||||
|
table.cmp{width:100%;border-collapse:collapse;font-size:28px;}
|
||||||
|
table.cmp th,table.cmp td{padding:22px 24px;text-align:left;border-bottom:1px solid var(--line);}
|
||||||
|
table.cmp th{font-family:"JetBrains Mono",monospace;font-size:21px;color:var(--mono);letter-spacing:.06em;font-weight:400;}
|
||||||
|
table.cmp td.k{color:var(--ink2);font-weight:300;}
|
||||||
|
table.cmp td .hl{color:var(--teal);}
|
||||||
|
table.cmp td .am{color:var(--amber);}
|
||||||
|
.grid4{display:grid;grid-template-columns:1fr 1fr;gap:28px;width:100%;}
|
||||||
|
.grid4 .g{background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:16px;padding:32px 32px;}
|
||||||
|
.grid4 .g .n{font-family:"Space Grotesk";font-weight:700;font-size:38px;color:var(--teal);}
|
||||||
|
.grid4 .g .t{font-size:27px;margin-top:8px;line-height:1.45;color:var(--ink);font-weight:300;}
|
||||||
|
.grid4 .g .t b{color:var(--amber);font-weight:700;}
|
||||||
|
.cover{justify-content:center;}
|
||||||
|
.cover .meta{position:absolute;bottom:72px;left:110px;font-family:"JetBrains Mono",monospace;font-size:21px;color:var(--mono);}
|
||||||
|
.nav{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:900;display:flex;gap:10px;align-items:center;}
|
||||||
|
.nav button{background:#16242b;border:1px solid #2a3c44;color:#cfe;font-size:15px;padding:9px 18px;border-radius:8px;cursor:pointer;font-family:"JetBrains Mono",monospace;}
|
||||||
|
.nav button:hover{background:#1d3038;}
|
||||||
|
.nav .pg{color:#6f8a93;font-family:"JetBrains Mono",monospace;font-size:14px;padding:0 8px;}
|
||||||
|
.hintkey{position:fixed;top:14px;right:18px;z-index:900;color:#42535b;font-family:"JetBrains Mono",monospace;font-size:13px;}
|
||||||
|
.spring{display:flex;align-items:center;gap:6px;font-size:40px;color:var(--teal);}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="hintkey">← → 翻页 · F 全屏</div>
|
||||||
|
<div id="wrap"><div class="stage" id="stage">
|
||||||
|
|
||||||
|
<!-- 1 封面 -->
|
||||||
|
<section class="slide active cover">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>SELF-SUPERVISED · 谱分解 · EP.02</div>
|
||||||
|
<h1 style="margin-top:34px;">OU 过程<br>与 <em>Mehler 公式</em></h1>
|
||||||
|
<p class="lead" style="margin-top:38px;">正样本对怎么造?为什么高阶非线性成分被罚得更狠?</p>
|
||||||
|
<div class="meta">配套播客 · 双主播对话 · 上接 Hermite 多项式,下启线性可识别性</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 2 核心问题 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>00 · 核心问题</div>
|
||||||
|
<h2>正样本对从<em>哪里来</em>?</h2>
|
||||||
|
<div class="content">
|
||||||
|
<ul class="pts">
|
||||||
|
<li>LeJEPA 训练需要「正样本对」——同一内容的两个视角 $(z, z')$。</li>
|
||||||
|
<li>这对视角是<b>怎么生成</b>的?答案是 <b>OU 过程</b>。</li>
|
||||||
|
<li>为什么这种生成方式,会让<b>高阶 Hermite 成分被更强地惩罚</b>?</li>
|
||||||
|
<li>解开它的钥匙,是 <b>Mehler 公式</b>。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 3 OU 物理直觉 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>01 · 物理直觉</div>
|
||||||
|
<h2>弹簧上的<em>小球</em></h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="card" style="flex:1;">
|
||||||
|
<div class="ct">弹簧力 · 均值回归</div>
|
||||||
|
<div class="cb">把小球持续拉回原点,不让它跑远。</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="flex:1;">
|
||||||
|
<div class="ct">随机扰动 · 布朗噪声</div>
|
||||||
|
<div class="cb">周围的随机推搡,让小球抖动。</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="flex:1;">
|
||||||
|
<div class="ct">一拉一推 = OU 过程</div>
|
||||||
|
<div class="cb">两股力量的拉扯,正是 Ornstein–Uhlenbeck 过程的图像。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 4 离散 OU 定义 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>02 · 定义</div>
|
||||||
|
<h2>LeJEPA 用的<em>离散一步转移</em></h2>
|
||||||
|
<div class="content" style="gap:60px;">
|
||||||
|
<div class="fbox" style="flex:1.1;font-size:42px;">
|
||||||
|
$z' = \rho\,z + \sqrt{1-\rho^{2}}\;\eta$
|
||||||
|
<div class="small">$\eta\sim\mathcal N(0,I),\quad \rho\in(0,1)$</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<p class="lead" style="font-size:30px;">$\rho$ 是<b style="color:var(--teal)">相关系数</b>——两个视角的相似度旋钮。</p>
|
||||||
|
<p class="lead" style="font-size:28px;margin-top:18px;">$\rho\to1$:几乎相同视角;$\rho\to0$:相互独立。实践取 $\rho\in[0.8,0.95]$。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 5 三性质 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>03 · 三个性质</div>
|
||||||
|
<h2>OU 过程的<em>三块基石</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<div class="cards">
|
||||||
|
<div class="card"><div class="ct">① 平稳性</div><div class="cb">$z\sim\mathcal N(0,I)\Rightarrow z'\sim\mathcal N(0,I)$<br>均值 0、方差 $\rho^2+(1-\rho^2)=1$。两视角分布相同。</div></div>
|
||||||
|
<div class="card"><div class="ct">② 相关可控</div><div class="cb">$\mathrm{Cov}(z',z)=\rho\,I$<br>$\rho$ 直接 = 相似度,一个旋钮说了算。</div></div>
|
||||||
|
<div class="card"><div class="ct">③ 加性噪声</div><div class="cb">$z'=\rho z+\eta$:线性漂移 + 独立噪声。<br>满足论文的加性噪声假设。</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 6 Mehler 公式 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>04 · 谱定理</div>
|
||||||
|
<h2>Mehler 公式:<em>每阶挂 ρᵈ</em></h2>
|
||||||
|
<div class="content" style="gap:56px;">
|
||||||
|
<div class="fbox" style="flex:1.15;font-size:30px;">
|
||||||
|
$p(z'\mid z)=\varphi(z')\displaystyle\sum_{d=0}^{\infty}\rho^{d}\,\frac{He_d(z)He_d(z')}{d!}$
|
||||||
|
<div class="small">OU 转移核在 Hermite 基下展开</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<div class="fbox" style="font-size:30px;">
|
||||||
|
$\mathbb{E}[h_i(z)\,h_i(z')]=\displaystyle\sum_{d=0}^{\infty}\rho^{d}\,w_d$
|
||||||
|
<div class="small">$w_d$=第 $i$ 分量在 $d$ 阶上的谱权重</div>
|
||||||
|
</div>
|
||||||
|
<p class="lead" style="font-size:26px;margin-top:22px;">关键:<b style="color:var(--amber)">d 阶成分的系数 = ρ 的 d 次方</b>。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 7 核心推论 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>05 · 核心推论</div>
|
||||||
|
<h2>相关性<em>封顶在 ρ</em></h2>
|
||||||
|
<div class="content" style="gap:56px;">
|
||||||
|
<div class="fbox" style="flex:1.1;font-size:28px;line-height:2;">
|
||||||
|
$\mathrm{corr}_i=\displaystyle\sum_{d\ge1}w_d\,\rho^{d}\le\sum_{d\ge1}w_d\,\rho=\rho$
|
||||||
|
<div class="small">因为 $\rho^d\le\rho\ (d\ge1)$,且 $\sum w_d=1$</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<p class="lead" style="font-size:30px;">等号成立 <b style="color:var(--teal)">当且仅当 $w_1=1$</b>——编码器纯线性。</p>
|
||||||
|
<p class="lead" style="font-size:27px;margin-top:18px;">只要有任何 $w_{d_0}>0\ (d_0\ge2)$,那一项就严格变小,和够不到 $\rho$。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 8 数值例子 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>06 · 数值例子</div>
|
||||||
|
<h2>取 <em>ρ = 0.9</em> 算给你看</h2>
|
||||||
|
<div class="content">
|
||||||
|
<table class="cmp">
|
||||||
|
<tr><th>编码器</th><th>谱权重</th><th>相关性 corrᵢ</th><th>与 0.9 的差距</th></tr>
|
||||||
|
<tr><td class="k">纯线性 $h=z$</td><td><span class="hl">$w_1=1$</span></td><td><span class="hl">$0.9^1=0.900$</span></td><td>0 | 最优</td></tr>
|
||||||
|
<tr><td class="k">纯二次 $h=z^2-1$</td><td>$w_2=1$</td><td><span class="am">$0.9^2=0.810$</span></td><td>−0.090</td></tr>
|
||||||
|
<tr><td class="k">纯三次 $h=z^3-3z$</td><td>$w_3=1$</td><td><span class="am">$0.9^3=0.729$</span></td><td>−0.171</td></tr>
|
||||||
|
<tr><td class="k">混合 各半</td><td>$w_1=w_2=0.5$</td><td>$0.855$</td><td>−0.045</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 9 与对齐损失 -->
|
||||||
|
<section class="slide posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>07 · 训练联系</div>
|
||||||
|
<h2>对齐损失的<em>下界</em></h2>
|
||||||
|
<div class="content" style="gap:56px;">
|
||||||
|
<div class="fbox" style="flex:1.05;font-size:28px;line-height:1.9;">
|
||||||
|
$\mathcal L_{\text{align}}=\mathbb{E}\|h(z')-h(z)\|^2$<br>
|
||||||
|
$=2n-2\sum_i \mathrm{corr}_i\;\ge\;2(1-\rho)\,n$
|
||||||
|
<div class="small">最小化损失 ⟺ 最大化相关性之和</div>
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;">
|
||||||
|
<p class="lead" style="font-size:31px;">等号成立 <b style="color:var(--teal)">当且仅当每个 $h_i$ 都是线性的</b>。</p>
|
||||||
|
<p class="lead" style="font-size:28px;margin-top:18px;">这就是定理一的心脏:<b style="color:var(--amber)">最优编码器必须线性</b>。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 10 衰减图示 -->
|
||||||
|
<section class="slide posCR">
|
||||||
|
<div class="glow"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>08 · 直觉图示</div>
|
||||||
|
<h2>ρ = 0.9 时<em>逐阶衰减</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<div style="width:100%;">
|
||||||
|
<div class="barrow"><span class="chip">d=1 线性</span><div class="track"><i style="width:90%"></i></div><span class="val">ρ¹ = 0.900</span></div>
|
||||||
|
<div class="barrow"><span class="chip">d=2 二次</span><div class="track"><i style="width:81%"></i></div><span class="val">ρ² = 0.810</span></div>
|
||||||
|
<div class="barrow"><span class="chip">d=3 三次</span><div class="track"><i style="width:72.9%"></i></div><span class="val">ρ³ = 0.729</span></div>
|
||||||
|
<div class="barrow"><span class="chip">d=4 四次</span><div class="track"><i style="width:65.6%"></i></div><span class="val">ρ⁴ = 0.656</span></div>
|
||||||
|
<div class="barrow"><span class="chip">d=5 五次</span><div class="track"><i style="width:59%"></i></div><span class="val">ρ⁵ = 0.590</span></div>
|
||||||
|
<p class="lead" style="font-size:27px;margin-top:20px;">非线性成分的相关性随阶数<b style="color:var(--amber)">指数衰减</b>——越高阶越吃亏。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 11 小结 -->
|
||||||
|
<section class="slide">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>09 · 小结</div>
|
||||||
|
<h2>五句话<em>带走全场</em></h2>
|
||||||
|
<div class="content">
|
||||||
|
<div class="grid4">
|
||||||
|
<div class="g"><div class="n">01</div><div class="t">OU 过程「一拉一推」造正样本对,相似度由 <b>ρ</b> 控制。</div></div>
|
||||||
|
<div class="g"><div class="n">02</div><div class="t"><b>平稳性</b> + 协方差 = ρ + 线性漂移加噪声,三性质齐备。</div></div>
|
||||||
|
<div class="g"><div class="n">03</div><div class="t"><b>Mehler</b>:d 阶 Hermite 成分相关性 = ρᵈ。</div></div>
|
||||||
|
<div class="g"><div class="n">04</div><div class="t">核心不等式 corrᵢ = Σ wᵈ ρᵈ ≤ ρ,等号 ⟺ <b>纯线性</b>。</div></div>
|
||||||
|
<div class="g" style="grid-column:1 / -1;"><div class="n">05</div><div class="t">最小化对齐损失 → 最大化相关性 → <b>编码器必须线性</b>(定理一)。</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 12 尾页 -->
|
||||||
|
<section class="slide cover posBL">
|
||||||
|
<div class="glow amber"></div>
|
||||||
|
<div class="kicker"><span class="ln"></span>下一站</div>
|
||||||
|
<h1 style="font-size:88px;margin-top:30px;">谱分解<br><em>与线性可识别性</em></h1>
|
||||||
|
<p class="lead" style="margin-top:34px;font-size:30px;">下一讲把 Hermite 展开与 OU 衰减正式拼起来,组装成定理一的完整证明。</p>
|
||||||
|
<div class="meta">谢谢收听 · 配套音频 ou_mehler-podcast.mp3 · 弹簧拉小球,ρ 拧大小 · 我们下次见</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div class="nav">
|
||||||
|
<button id="prev">← 上一页</button>
|
||||||
|
<span class="pg" id="pg">1 / 12</span>
|
||||||
|
<button id="next">下一页 →</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const STAGE = document.getElementById('stage');
|
||||||
|
const slides = Array.from(document.querySelectorAll('.slide'));
|
||||||
|
const total = slides.length;
|
||||||
|
const KEY = 'ou_mehler_deck_page';
|
||||||
|
|
||||||
|
let cur = parseInt(localStorage.getItem(KEY) || '0', 10);
|
||||||
|
if (isNaN(cur) || cur < 0 || cur >= total) cur = 0;
|
||||||
|
|
||||||
|
function fit(){
|
||||||
|
const s = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
|
||||||
|
STAGE.style.transform = `scale(${s})`;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', fit); fit();
|
||||||
|
|
||||||
|
function show(i){
|
||||||
|
cur = (i + total) % total;
|
||||||
|
slides.forEach((s, idx) => s.classList.toggle('active', idx === cur));
|
||||||
|
document.getElementById('pg').textContent = `${cur + 1} / ${total}`;
|
||||||
|
const w = ((cur) / (total - 1) * 100).toFixed(1) + '%';
|
||||||
|
document.querySelectorAll('.page-footer .prog i').forEach(b => b.style.width = w);
|
||||||
|
localStorage.setItem(KEY, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
slides.forEach((s, idx) => {
|
||||||
|
const f = document.createElement('div');
|
||||||
|
f.className = 'page-footer';
|
||||||
|
f.innerHTML = `<span>OU 过程 · Mehler 公式</span><span class="prog"><i></i></span><span>${String(idx+1).padStart(2,'0')} / ${String(total).padStart(2,'0')}</span>`;
|
||||||
|
s.appendChild(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('prev').addEventListener('click', () => show(cur - 1));
|
||||||
|
document.getElementById('next').addEventListener('click', () => show(cur + 1));
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); show(cur + 1); }
|
||||||
|
else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); show(cur - 1); }
|
||||||
|
else if (e.key === 'Home') show(0);
|
||||||
|
else if (e.key === 'End') show(total - 1);
|
||||||
|
else if (e.key === 'f' || e.key === 'F') {
|
||||||
|
if (!document.fullscreenElement) document.documentElement.requestFullscreen();
|
||||||
|
else document.exitFullscreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('wrap').addEventListener('click', (e) => {
|
||||||
|
if (e.target.closest('.nav')) return;
|
||||||
|
if (e.clientX > window.innerWidth * 0.5) show(cur + 1); else show(cur - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderMath(){
|
||||||
|
if (window.renderMathInElement){
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
delimiters: [
|
||||||
|
{left:'$$', right:'$$', display:true},
|
||||||
|
{left:'$', right:'$', display:false}
|
||||||
|
],
|
||||||
|
throwOnError:false
|
||||||
|
});
|
||||||
|
} else { setTimeout(renderMath, 120); }
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const pageParam = params.get('page');
|
||||||
|
if (pageParam !== null) {
|
||||||
|
const p = parseInt(pageParam, 10);
|
||||||
|
if (!isNaN(p) && p >= 1 && p <= total) cur = p - 1;
|
||||||
|
}
|
||||||
|
if (params.get('clean') === '1') {
|
||||||
|
document.body.classList.add('clean');
|
||||||
|
const navEl = document.querySelector('.nav'); if (navEl) navEl.style.display = 'none';
|
||||||
|
const hk = document.querySelector('.hintkey'); if (hk) hk.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', () => { renderMath(); show(cur); });
|
||||||
|
if (document.readyState !== 'loading') { renderMath(); show(cur); }
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||