Skip to content

Commit e404dbe

Browse files
committed
feat: 新增 proj-len-demo 随机投影链长度平方分布演示(卡方/乘积卡方/深度对数正态)
1 parent 9aa0ea6 commit e404dbe

8 files changed

Lines changed: 1702 additions & 0 deletions

File tree

index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,22 @@ <h2>双随机投影的点积分布:Variance-Gamma 与夹角的遗忘<span clas
184184
</div>
185185
</a>
186186
</li>
187+
<li class="tool-card">
188+
<a href="web-tools/proj-len-demo/">
189+
<h2>随机投影链的长度平方分布:卡方、乘积卡方与深度对数正态<span class="arrow"></span></h2>
190+
<p>
191+
单位向量经高斯矩阵链投影后的长度平方 s = ‖B···BA X‖²:L=1 为卡方(伽马)、
192+
L=2 为 Bessel-K₀ 乘积伽马(精确闭式)、深链趋近对数正态——均值恒为 c = H/D
193+
(fan-in 保值),中位数却 ≈ c·e^(−L/H) 随深度萎缩:LayerNorm 的随机矩阵注脚。
194+
quenched 对照展示长度统计的 self-averaging。
195+
</p>
196+
<div class="tags">
197+
<span class="tag">随机矩阵</span>
198+
<span class="tag">深度网络初始化</span>
199+
<span class="tag">蒙特卡洛模拟</span>
200+
</div>
201+
</a>
202+
</li>
187203
<li class="tool-card">
188204
<a href="web-tools/noise-ops-demo/">
189205
<h2>噪音向量的基本运算:加、数乘、点积<span class="arrow"></span></h2>

web-tools/proj-len-demo/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# proj-len-demo:随机投影链的长度平方分布(卡方、乘积卡方与深度对数正态)
2+
3+
交互式网页工具,演示单位向量 $X \in \mathbb{R}^D$ 经过高斯矩阵链后的长度平方
4+
5+
$$s = \|B_{L-1}\cdots B_1 A\,X\|^2$$
6+
7+
的分布:$A$ 为 $H\times D$(元素方差 $1/D$,初始化缩放),$B_l$ 为 $H\times H$
8+
(方差 $1/H$,fan-in),$L$ = 矩阵总数。这是残差流上每层变换的初始化统计的
9+
零模型;姊妹篇:`spectrum-demo`(奇异值谱)、`proj-dot-demo`(投影点积)。
10+
11+
**核心结构:卡方因子化(精确)。** 条件于上一层输出 $Y$,下一层
12+
$\|BY\|^2 = (\|Y\|^2/H)\,\chi^2_H$,且卡方部分与 $\|Y\|^2$ 独立,递推得
13+
14+
$$s = \frac{1}{D}\,\chi^2_H \cdot \prod_{l=1}^{L-1}\frac{\chi^2_H}{H}
15+
\qquad(\text{L 个独立卡方因子})$$
16+
17+
与 $X$ 的方向严格无关(各向同性——与 proj-dot-demo 的"夹角遗忘"同源)。
18+
19+
**三条主线:**
20+
21+
1. **$L=1$:伽马分布** $\chi^2_H/D$($H{=}1$ 原点 $s^{-1/2}$ 发散;$H{=}2$ 指数分布;
22+
大 $H$ 高斯化)。均值 $c = H/D$:fan-in 缩放下 $\mathbb E\|BX\|^2 = \|X\|^2$ 逐层保值。
23+
2. **$L=2$:独立伽马乘积 = Bessel-$K_0$ 闭式**
24+
$f(s) = \frac{2s^{k-1}K_0(2\sqrt{s/\theta_1\theta_2})}{\Gamma(k)^2(\theta_1\theta_2)^k}$
25+
($k=H/2$,$\theta_1=2/D$,$\theta_2=2/H$)。均值仍 $c$,相对方差从 $2/H$ 涨到
26+
$\approx 4/H$;右尾 $e^{-2\sqrt{s/\theta_1\theta_2}}$ 是拉伸指数——重尾化的第一层
27+
(对数纵轴下肉眼可见与伽马直线的差别)。
28+
3. **$L\ge3$:深度对数正态。** $\ln s \approx \mathcal N(\mu,\sigma^2)$,
29+
$\mu = -\ln D + L(\ln2 + \psi(H/2)) - (L-1)\ln H$,$\sigma^2 = L\,\psi'(H/2)$。
30+
**均值 $c$ 不变,中位数 $\approx c\,e^{-L/H}$ 指数萎缩**——均值被重尾撑着,
31+
典型样本塌缩(均值/中位数 $\approx e^{L/H}$)。这给了 LayerNorm 存在意义的
32+
随机矩阵注脚:Norm 压掉的正是这种深度方向的对数正态涨落;也与 dynamical
33+
isometry 文献相连(高斯矩阵谱宽 $4\sqrt c$ 不 concentrate,逐层涨落不可避免)。
34+
35+
**quenched 对照(方案二:固定矩阵链,随机 $X$ 球面均匀)。** $s = X^\top W X$,
36+
$W = M^\top M$($M$ = 合成链)。球面二次型精确矩:
37+
38+
$$\mathbb E_X[s] = \mathrm{tr}W/D,\qquad
39+
\mathrm{Var}_X(s) = \frac{2[\mathrm{tr}(W^2) - (\mathrm{tr}W)^2/D]}{D(D+2)}$$
40+
41+
**self-averaging:实例内方差 ≈ annealed 方差的大部分**(球面约束下谱加权的
42+
$(1{+}c)$ 修正被 $-(\mathrm{tr}W)^2/D$ 项抵消),换一批矩阵直方图形状不动、
43+
仅中心平移;实例中心 $\mathrm{tr}W/D$ 的跳动($L$ 层精确,逐层全方差律递推)
44+
45+
$$\mathrm{Var}(\mathrm{tr}W/D) = \frac{L(L-1+2c)}{D^2}
46+
\qquad(\text{逐层全方差律递推,谱二阶矩 } m_2 = L{+}c)$$
47+
48+
($L{=}1$ 即 $2H/D^3$;随 $L$ 平方增长——深链时平方和的自平均也变差)
49+
50+
随维度消失——因为 $\mathrm{tr}W = \|M\|_F^2$ 是**平方和**(强自平均),对照
51+
proj-dot-demo 的 $\mathrm{tr}M = \langle M_a,M_b\rangle_F$ 是**符号和**
52+
(涨落 $\sqrt{H/D}$ 不消失)。同为二次型,长度统计稳健、点积均值脆弱。
53+
54+
## 用法
55+
56+
直接用浏览器打开 `index.html` 即可(ECharts 走 CDN,需要联网)。
57+
58+
- **方案切换**:一(随机矩阵,annealed)/ 二(固定链,quenched)。方案二可换种子
59+
观察直方图不动、中心微跳。
60+
- **层数 L**:1(卡方)/ 2($K_0$ 乘积)/ 3–16(对数正态近似;L≥3 无初等闭式,
61+
精确密度是 Meijer G)。
62+
- **H、D 滑杆**(对数刻度),$c = H/D$ 在附注中显示。
63+
- **横轴**:归一 $\div c$ 或原始 $s$;线性或对数刻度(深链重尾建议对数)。
64+
- **纵轴**:线性或对数(看拉伸指数尾)。
65+
- 标线:均值 $c$(灰虚线)与中位数 $c\,e^{-L/H}$(橙点线)随 $L$ 分离——
66+
本演示最有冲击力的画面。
67+
- 统计表:样本均值/标准差/中位数/$\ln s$ 矩 vs 理论;方案二附加 $\mathrm{tr}W/D$
68+
与中心跳动幅度 $\sqrt{2H/D^3}$。
69+
70+
## 文件结构
71+
72+
- `index.html`:页面骨架与公式块
73+
- `js/theory.js`:纯数学层(Lanczos Γ、NR 系数 Bessel-$K_{0,1}$、digamma/trigamma
74+
渐近展开、伽马/$K_0$ 乘积密度、链矩与对数域参数、quenched 球面矩),无 DOM 依赖
75+
- `js/app.js`:种子化 PRNG、卡方因子采样(方案一)、链合成 $M = B\cdots BA$
76+
($O(LH^2D)$ 一次)+ 球面采样(每样本 $O(HD)$)、ECharts 渲染(对数坐标)
77+
- `css/style.css`:样式
78+
- `test/theory-selftest.js`:theory.js 的 node 自检
79+
`node web-tools/proj-len-demo/test/theory-selftest.js`
80+
- `test/plot_proj_len_density.py`:Python 蒙特卡洛对照(四子图),
81+
输出 `<仓库根>/output/proj-len-density.png`
82+
83+
## 数值验证
84+
85+
- `test/theory-selftest.js`:$\psi/\psi'$ 锚点($-\gamma$、$\pi^2/6$、$\pi^2/2$ 等)、
86+
伽马密度特例($H{=}2$ 逐点等于指数分布、原点行为)、$K_0$ 乘积密度的特例恒等与
87+
归一化/解析矩($\mathbb E[P^m] = [\Gamma(k{+}m)/\Gamma(k)]^2(\theta_1\theta_2)^m$,
88+
对数网格数值积分)、链矩公式、quenched 球面矩精确值;
89+
- Python 侧对照:$L{=}1,2$ 均值/方差与理论吻合;$L{=}8$ 样本中位数 $0.2216$ vs
90+
LN 近似 $0.2205$,均值/中位数 $1.129$ vs $e^{L/H} = 1.133$;quenched 三个种子的
91+
实例均值逐一吻合 $\mathrm{tr}W/D$、实例 std 吻合球面公式,中心跳动(±0.008)与
92+
$\sqrt{L(L{-}1{+}2c)}/D = 0.0068$ 同量级——self-averaging 成立。
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
* {
2+
box-sizing: border-box;
3+
}
4+
5+
body {
6+
margin: 0;
7+
padding: 24px;
8+
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
9+
background: #f6f7f9;
10+
color: #24292f;
11+
}
12+
13+
header h1 {
14+
margin: 0 0 8px;
15+
font-size: 22px;
16+
}
17+
18+
.header-row {
19+
display: flex;
20+
align-items: baseline;
21+
gap: 24px;
22+
}
23+
24+
.header-row h1 {
25+
margin: 0;
26+
white-space: nowrap;
27+
}
28+
29+
.subtitle {
30+
margin: 0 0 16px;
31+
color: #57606a;
32+
font-size: 13px;
33+
line-height: 1.6;
34+
}
35+
36+
.legend-note {
37+
padding: 1px 6px;
38+
border-radius: 4px;
39+
}
40+
41+
.note-blue {
42+
color: #2563eb;
43+
background: #eff6ff;
44+
}
45+
46+
.note-red {
47+
color: #b91c1c;
48+
background: #fef2f2;
49+
}
50+
51+
.note-purple {
52+
color: #7c3aed;
53+
background: #f3e8ff;
54+
}
55+
56+
.note-teal {
57+
color: #0d9488;
58+
background: #f0fdfa;
59+
}
60+
61+
.controls {
62+
display: flex;
63+
flex-wrap: wrap;
64+
gap: 24px;
65+
align-items: center;
66+
padding: 12px 16px;
67+
background: #fff;
68+
border: 1px solid #d0d7de;
69+
border-radius: 8px;
70+
margin-bottom: 16px;
71+
}
72+
73+
.control {
74+
display: flex;
75+
align-items: center;
76+
gap: 10px;
77+
}
78+
79+
.control label {
80+
font-size: 14px;
81+
white-space: nowrap;
82+
}
83+
84+
.control-slider {
85+
flex: 1 1 280px;
86+
}
87+
88+
.control-slider input[type="range"] {
89+
flex: 1;
90+
width: auto;
91+
min-width: 140px;
92+
}
93+
94+
.control input[type="number"] {
95+
width: 80px;
96+
padding: 4px 6px;
97+
border: 1px solid #d0d7de;
98+
border-radius: 6px;
99+
font-size: 14px;
100+
}
101+
102+
.control select {
103+
padding: 4px 6px;
104+
border: 1px solid #d0d7de;
105+
border-radius: 6px;
106+
font-size: 14px;
107+
background: #fff;
108+
}
109+
110+
.control button {
111+
padding: 4px 12px;
112+
border: 1px solid #d0d7de;
113+
border-radius: 6px;
114+
background: #f6f8fa;
115+
font-size: 13px;
116+
cursor: pointer;
117+
}
118+
119+
.control button:hover {
120+
background: #eaeef2;
121+
}
122+
123+
.control button:disabled,
124+
.control input:disabled {
125+
opacity: 0.45;
126+
cursor: not-allowed;
127+
}
128+
129+
.control-inline label {
130+
display: flex;
131+
align-items: center;
132+
gap: 4px;
133+
cursor: pointer;
134+
}
135+
136+
.control-scheme {
137+
width: 100%;
138+
}
139+
140+
.seg {
141+
display: flex;
142+
flex-wrap: wrap;
143+
gap: 6px 20px;
144+
}
145+
146+
.seg label {
147+
display: inline-flex;
148+
align-items: center;
149+
gap: 4px;
150+
cursor: pointer;
151+
font-size: 14px;
152+
}
153+
154+
main {
155+
display: grid;
156+
grid-template-columns: 1fr;
157+
gap: 16px;
158+
}
159+
160+
.chart-wrap {
161+
background: #fff;
162+
border: 1px solid #d0d7de;
163+
border-radius: 8px;
164+
padding: 12px;
165+
}
166+
167+
.chart {
168+
width: 100%;
169+
height: 460px;
170+
}
171+
172+
.chart-controls {
173+
display: flex;
174+
flex-wrap: wrap;
175+
gap: 8px 28px;
176+
align-items: center;
177+
padding: 2px 4px 10px;
178+
margin-bottom: 6px;
179+
border-bottom: 1px solid #eaeef2;
180+
font-size: 13px;
181+
color: #24292f;
182+
}
183+
184+
.cc-group label {
185+
margin-left: 10px;
186+
display: inline-flex;
187+
align-items: center;
188+
gap: 4px;
189+
cursor: pointer;
190+
}
191+
192+
.chart-note {
193+
margin: 8px 4px 0;
194+
font-size: 12px;
195+
color: #57606a;
196+
line-height: 1.6;
197+
}
198+
199+
.stats-wrap {
200+
margin: 8px 4px 0;
201+
overflow-x: auto;
202+
}
203+
204+
.stats-table {
205+
border-collapse: collapse;
206+
font-size: 12px;
207+
color: #57606a;
208+
}
209+
210+
.stats-table th,
211+
.stats-table td {
212+
border: 1px solid #d0d7de;
213+
padding: 4px 12px;
214+
text-align: left;
215+
}
216+
217+
.stats-table th {
218+
background: #f6f8fa;
219+
color: #24292f;
220+
font-weight: 600;
221+
white-space: nowrap;
222+
}
223+
224+
.formula-block {
225+
border-top: 1px dashed #d0d7de;
226+
margin-top: 10px;
227+
padding-top: 6px;
228+
}
229+
230+
.formula-title {
231+
margin: 2px 0 4px;
232+
}
233+
234+
.formula-block .stats-table {
235+
margin-bottom: 4px;
236+
}

0 commit comments

Comments
 (0)