Files
gaojie 5de86388db
Sync to site1 / sync (push) Has been cancelled
Add interactive HTML pages for planning explainer and spectral explainer
- Created planning_explainer.html to demonstrate orthogonal invariance and optimal planning with interactive controls and visualizations.
- Created spectral_explainer.html to illustrate spectral decomposition and linear identifiability, featuring adjustable spectral weights and real-time correlation calculations.
2026-06-02 05:05:39 +08:00

179 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>谱分解与线性可识别性 — 交互式探索</title>
<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=Spectral:ital,wght@0,400;0,600;1,400&family=Sora:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
<style>
:root{--bg:#0e1116;--panel:#161b22;--panel-2:#1b222c;--line:#232b36;--txt:#e6edf3;--txt-2:#8b949e;--txt-3:#5c6672;--linear:#4cc9f0;--linear-soft:rgba(76,201,240,.16);--nl:#f4a261;--nl-soft:rgba(244,162,97,.16);--ok:#56d364;--r:14px;}
*{box-sizing:border-box;}html,body{margin:0;height:100%;}
body{background:radial-gradient(1200px 700px at 78% -8%,rgba(76,201,240,.06),transparent 60%),var(--bg);color:var(--txt);font-family:'Sora',system-ui,sans-serif;-webkit-font-smoothing:antialiased;overflow:hidden;}
.app{height:100vh;display:grid;grid-template-columns:320px 1fr 330px;grid-template-rows:auto 1fr;grid-template-areas:"head head head" "ctrl stage read";gap:18px;padding:22px 26px;}
header{grid-area:head;display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;}
header .kicker{font:500 12px/1 'JetBrains Mono',monospace;letter-spacing:.32em;color:var(--linear);text-transform:uppercase;}
header h1{margin:0;font-family:'Spectral',serif;font-weight:600;font-size:30px;}
header h1 em{color:var(--txt-2);font-style:italic;font-weight:400;}
header .sub{font-size:13px;color:var(--txt-2);max-width:560px;line-height:1.5;}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);}
.controls{grid-area:ctrl;padding:20px;display:flex;flex-direction:column;gap:20px;overflow-y:auto;}
.block .label{font:600 11px/1 'JetBrains Mono',monospace;letter-spacing:.18em;color:var(--txt-3);text-transform:uppercase;margin-bottom:10px;}
.srow{display:flex;align-items:center;gap:12px;margin-bottom:6px;}
.srow .nm{font:500 12px 'JetBrains Mono',monospace;width:78px;}
.srow .nm.d1{color:var(--linear);}.srow .nm.dN{color:var(--nl);}
.srow .vv{font:600 12px 'JetBrains Mono',monospace;color:var(--txt-2);width:42px;text-align:right;}
input[type=range]{-webkit-appearance:none;flex:1;height:4px;border-radius:4px;background:#2a323d;cursor:pointer;}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;background:#eaf6fb;border:3px solid var(--linear);}
input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:#eaf6fb;border:3px solid var(--linear);}
input.nl::-webkit-slider-thumb{border-color:var(--nl);}input.nl::-moz-range-thumb{border-color:var(--nl);}
.hint{font-size:12px;color:var(--txt-3);line-height:1.55;margin-top:8px;}
.preset{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;}
.preset button{flex:1;padding:8px 6px;border-radius:8px;border:1px solid var(--line);background:var(--panel-2);color:var(--txt-2);font:500 11px 'Sora';cursor:pointer;}
.preset button:hover{border-color:var(--linear);color:var(--linear);}
.big-corr{font:700 34px/1 'JetBrains Mono',monospace;}
.stage{grid-area:stage;padding:18px 20px 16px;display:flex;flex-direction:column;gap:14px;min-height:0;}
.stage .ttl h2{margin:0;font-family:'Spectral',serif;font-weight:600;font-size:18px;}
.canvas-wrap{position:relative;flex:1;min-height:0;border-radius:10px;overflow:hidden;background:#0b0e13;border:1px solid var(--line);}
canvas{display:block;width:100%;height:100%;}
.roadmap{flex:none;display:flex;gap:8px;}
.step{flex:1;padding:10px 8px;border-radius:9px;border:1px solid var(--line);background:#0b0e13;font-size:11px;line-height:1.35;color:var(--txt-3);transition:.25s;}
.step.on{border-color:var(--linear);color:var(--txt);background:var(--linear-soft);}
.step b{display:block;font:700 11px 'JetBrains Mono',monospace;color:var(--linear);margin-bottom:3px;}
.reading{grid-area:read;padding:22px;display:flex;flex-direction:column;gap:16px;overflow-y:auto;}
.reading h3{margin:0;font-family:'Spectral',serif;font-weight:600;font-size:17px;}
.formula{font:500 14px 'JetBrains Mono',monospace;background:#0b0e13;border:1px solid var(--line);border-radius:8px;padding:14px 16px;line-height:1.7;}
.formula .hi{color:var(--linear);}.formula .hl{color:var(--nl);}
.verdict{margin-top:auto;padding:16px;border-radius:10px;font-family:'Spectral',serif;font-size:14px;line-height:1.6;}
.verdict.win{background:linear-gradient(135deg,rgba(86,211,100,.16),transparent 70%);border:1px solid rgba(86,211,100,.4);}
.verdict.lose{background:linear-gradient(135deg,var(--nl-soft),transparent 70%);border:1px solid rgba(244,162,97,.4);}
.verdict b{color:var(--linear);}
.src{font:400 11px 'JetBrains Mono',monospace;color:var(--txt-3);}
.navbar{position:fixed;bottom:14px;left:50%;transform:translateX(-50%);display:flex;gap:6px;background:rgba(22,27,34,.9);border:1px solid var(--line);border-radius:30px;padding:6px 10px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:20;}
.navbar a{font:500 12px 'JetBrains Mono',monospace;color:var(--txt-2);text-decoration:none;padding:5px 11px;border-radius:20px;}
.navbar a:hover{color:var(--linear);}.navbar a.on{background:var(--linear-soft);color:var(--linear);}
::-webkit-scrollbar{width:8px;height:8px;}::-webkit-scrollbar-thumb{background:#2a323d;border-radius:8px;}
@media (max-width:1080px){.app{grid-template-columns:1fr;grid-template-rows:repeat(4,auto);grid-template-areas:"head" "ctrl" "stage" "read";overflow:auto;height:auto;}body{overflow:auto;}.canvas-wrap{height:300px;flex:none;}}
</style>
</head>
<body>
<div class="app">
<header>
<div style="display:flex;flex-direction:column;gap:6px;">
<span class="kicker">LeJEPA · Topic 3 · 定理 1</span>
<h1>谱分解 <em>与线性可识别性</em></h1>
</div>
<p class="sub">调节编码器的谱权重 <b style="color:var(--linear)">w₁</b>/<b style="color:var(--nl)">w₂,w₃</b>(自动归一化),实时计算相关性 <b>corr = Σ wᵈ·ρᵈ</b>,看它何时能触到上界 ρ——只有纯线性(w₁=1)才能取等。</p>
</header>
<section class="card controls">
<div class="block">
<div class="label">谱权重 wᵈ(Σ=1 自动归一化)</div>
<div class="srow"><span class="nm d1">w₁ 线性</span><input id="w1" class="lin" type="range" min="0" max="1" step="0.01" value="1" aria-label="w1" title="w1"/><span class="vv" id="v1">1.00</span></div>
<div class="srow"><span class="nm dN">w₂ 二次</span><input id="w2" class="nl" type="range" min="0" max="1" step="0.01" value="0" aria-label="w2" title="w2"/><span class="vv" id="v2">0.00</span></div>
<div class="srow"><span class="nm dN">w₃ 三次</span><input id="w3" class="nl" type="range" min="0" max="1" step="0.01" value="0" aria-label="w3" title="w3"/><span class="vv" id="v3">0.00</span></div>
<div class="preset">
<button data-p="1,0,0">纯线性</button>
<button data-p="0,1,0">纯二次</button>
<button data-p="0.5,0.5,0">各半</button>
<button data-p="0.6,0.25,0.15">混合</button>
</div>
<div class="hint">谱权重 = 编码器各阶非线性成分占总方差的比例。w₀=0(零均值),Σwᵈ=1(单位方差)。</div>
</div>
<div class="block">
<div class="label">相关性 ρ</div>
<div class="srow"><span class="nm">ρ</span><input id="rho" class="lin" type="range" min="0.05" max="0.97" step="0.01" value="0.90" aria-label="rho" title="rho"/><span class="vv" id="vr">0.90</span></div>
</div>
<div class="block">
<div class="label">当前相关性 corr</div>
<div class="big-corr" id="corrTxt">0.900</div>
<div class="hint">上界 = ρ。差距 = ρ − corr ≥ 0,仅纯线性时为 0。</div>
</div>
</section>
<section class="card stage">
<div class="ttl"><h2>corr = Σ wᵈ·ρᵈ 相对上界 ρ</h2></div>
<div class="canvas-wrap"><canvas id="cv"></canvas></div>
<div class="roadmap" id="roadmap"></div>
</section>
<section class="card reading">
<h3>关键不等式</h3>
<div class="formula">corr = Σ<sub>d≥1</sub> w<sub>d</sub><span class="hl">ρ<sup>d</sup></span> ≤ Σ w<sub>d</sub><span class="hi">ρ</span> = <span class="hi">ρ</span><br><br>等号 ⟺ ∀d≥2: w<sub>d</sub>=0 ⟺ <span class="hi">w₁=1</span></div>
<h3 style="margin-top:2px;">从相关到正交</h3>
<div class="formula">corr=ρ → h(z)=Az(线性)<br>h(z)~N(0,I) → AAᵀ=I<br><span class="hi">h(z)=Qz, Q∈O(n)</span></div>
<div class="verdict win" id="verdict"></div>
<div class="src">来源:JEPA/math/03_spectral_identifiability.md</div>
</section>
</div>
<nav class="navbar" id="nav"></nav>
<script>
const NAV=[["01","Hermite","hermite_explainer.html"],["02","OU·Mehler","ou_mehler_explainer.html"],["03","谱分解","spectral_explainer.html"],["04","高斯唯一","gaussian_uniqueness_explainer.html"],["05","近似界","approx_bound_explainer.html"],["06","规划等价","planning_explainer.html"]];
const nav=document.getElementById('nav');NAV.forEach(([n,t,f])=>{const a=document.createElement('a');a.href=f;a.textContent=n+' '+t;if(f==='spectral_explainer.html')a.className='on';nav.appendChild(a);});
const STEPS=[["步骤1","Hermite 展开 hᵢ=ΣcₐHeₐ"],["步骤2","Mehler: corr=Σwᵈρᵈ"],["步骤3","corr≤ρ, 等号⟺w₁=1"],["步骤4","L=2(1−ρ)n 最优"],["步骤5","每个 hᵢ 线性"],["步骤6","AAᵀ=I → 正交 Q"]];
const rm=document.getElementById('roadmap');STEPS.forEach(([b,t])=>{const d=document.createElement('div');d.className='step';d.innerHTML='<b>'+b+'</b>'+t;rm.appendChild(d);});
let w=[1,0,0], rho=0.90;
const ids=['w1','w2','w3'], vids=['v1','v2','v3'];
function readW(changed){
let raw=ids.map(id=>+document.getElementById(id).value);
let s=raw[0]+raw[1]+raw[2];
if(s<=0){raw=[1,0,0];s=1;}
w=raw.map(x=>x/s);
ids.forEach((id,i)=>{document.getElementById(id).value=w[i];document.getElementById(vids[i]).textContent=w[i].toFixed(2);});
draw();
}
ids.forEach(id=>document.getElementById(id).addEventListener('input',()=>readW(id)));
document.querySelectorAll('.preset button').forEach(b=>b.addEventListener('click',()=>{const p=b.dataset.p.split(',').map(Number);ids.forEach((id,i)=>document.getElementById(id).value=p[i]);readW();}));
const rhoEl=document.getElementById('rho');
rhoEl.addEventListener('input',e=>{rho=+e.target.value;document.getElementById('vr').textContent=rho.toFixed(2);draw();});
const cv=document.getElementById('cv'),ctx=cv.getContext('2d');
function fit(){const r=cv.getBoundingClientRect(),dpr=devicePixelRatio||1;cv.width=r.width*dpr;cv.height=r.height*dpr;return{w:r.width,h:r.height,dpr};}
function corrVal(){return w[0]*rho+w[1]*rho*rho+w[2]*rho*rho*rho;}
function draw(){
const {w:W,h:H,dpr}=fit();ctx.setTransform(dpr,0,0,dpr,0,0);ctx.clearRect(0,0,W,H);
const padL=70,padR=40,padT=30,padB=40,x0=padL,x1=W-padR,y0=padT,y1=H-padB;
const sy=v=>y1-v*(y1-y0);
// grid
ctx.strokeStyle='#1c2530';ctx.lineWidth=1;ctx.font="11px 'JetBrains Mono',monospace";ctx.fillStyle='#5c6672';
for(let g=0;g<=10;g++){const v=g/10,py=sy(v);ctx.beginPath();ctx.moveTo(x0,py);ctx.lineTo(x1,py);ctx.stroke();ctx.fillText(v.toFixed(1),x0-34,py+4);}
// 上界 ρ 虚线
ctx.strokeStyle='var(--linear)';ctx.strokeStyle='#4cc9f0';ctx.setLineDash([6,5]);ctx.lineWidth=1.8;ctx.beginPath();ctx.moveTo(x0,sy(rho));ctx.lineTo(x1,sy(rho));ctx.stroke();ctx.setLineDash([]);
ctx.fillStyle='#4cc9f0';ctx.font="600 13px 'JetBrains Mono',monospace";ctx.fillText('上界 ρ = '+rho.toFixed(2),x1-150,sy(rho)-8);
// 三个堆叠贡献柱: w1ρ, w2ρ², w3ρ³ 累加
const cx=(x0+x1)/2, bw=140;
const parts=[[w[0]*rho,'#4cc9f0','w₁ρ'],[w[1]*rho*rho,'#f4a261','w₂ρ²'],[w[2]*rho*rho*rho,'#e76f51','w₃ρ³']];
let acc=0;
parts.forEach(([val,col,lab])=>{if(val<=0)return;const yT=sy(acc+val),yB=sy(acc);ctx.fillStyle=col;ctx.globalAlpha=.9;ctx.fillRect(cx-bw/2,yT,bw,yB-yT);ctx.globalAlpha=1;
if(yB-yT>18){ctx.fillStyle='#0b0e13';ctx.font="700 12px 'JetBrains Mono',monospace";ctx.textAlign='center';ctx.fillText(lab+'='+val.toFixed(3),cx,(yT+yB)/2+4);ctx.textAlign='left';}acc+=val;});
// corr 顶标
const c=corrVal();
ctx.strokeStyle='#56d364';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(cx-bw/2-20,sy(c));ctx.lineTo(cx+bw/2+20,sy(c));ctx.stroke();
ctx.fillStyle='#56d364';ctx.font="700 14px 'JetBrains Mono',monospace";ctx.textAlign='center';ctx.fillText('corr = '+c.toFixed(3),cx,sy(c)-9);ctx.textAlign='left';
// gap 标注
const gap=rho-c;
ctx.fillStyle=gap<1e-4?'#56d364':'#f4a261';ctx.font="500 12px 'JetBrains Mono',monospace";
ctx.fillText('gap = ρ corr = '+gap.toFixed(3),x0+6,y0+16);
document.getElementById('corrTxt').textContent=c.toFixed(3);
document.getElementById('corrTxt').style.color=gap<1e-4?'#56d364':'#f4a261';
// 路线图高亮:纯线性点亮全部 6 步
const pure=w[0]>0.999;
STEPS.forEach((_,i)=>{rm.children[i].classList.toggle('on', pure ? true : i<3);});
const v=document.getElementById('verdict');
if(pure){v.className='verdict win';v.innerHTML='<b>corr = ρ,触到上界!</b> 编码器是纯线性的 h(z)=Az,叠加高斯约束 AAᵀ=I → <b>h(z)=Qz(正交)</b>。这正是<strong>线性可识别性</strong>(定理 1)。';}
else{v.className='verdict lose';v.innerHTML='存在 d≥2 的非线性权重 → corr < ρ,<b style="color:var(--nl)">gap = '+gap.toFixed(3)+'</b>。对齐损失未达最优,编码器不是最优解。把 <b style="color:var(--linear)">w₁ 拉到 1</b> 试试。';}
}
window.addEventListener('resize',draw);
readW();draw();
</script>
</body>
</html>