搜索
bottom↓
回复: 3

AI 数学基础

[复制链接]

出15入258汤圆

发表于 2026-9-25 21:43:13 | 显示全部楼层 |阅读模式
本帖最后由 jadegu 于 2026-9-25 21:42 编辑

AI 做的AI数学基础学习路径


可以玩一下。




  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>AI 数学基础 · 渐进式学习路径(扩展版)</title>
  7. <style>
  8. :root{
  9.   --bg:#f5f7fb; --card:#ffffff; --ink:#202634; --muted:#5b6474;
  10.   --accent:#4353ff; --accent-soft:#eef1ff; --good:#1a936b; --good-soft:#e7f6ee;
  11.   --bad:#d64545; --bad-soft:#fdecec; --line:#e3e7f0; --formula-bg:#f2f5fc;
  12. }
  13. *{box-sizing:border-box}
  14. html{scroll-behavior:smooth}
  15. body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;background:var(--bg);color:var(--ink);line-height:1.7}
  16. a{color:var(--accent)}
  17. header.hero{padding:44px 24px 34px;background:linear-gradient(135deg,#4353ff 0%,#7c3aed 60%,#a21caf 100%);color:#fff}
  18. .hero-inner{max-width:1200px;margin:0 auto}
  19. .hero h1{margin:0 0 8px;font-size:2rem;letter-spacing:.5px}
  20. .hero p.sub{margin:0 0 18px;opacity:.92;font-size:1.02rem}
  21. .path{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:22px}
  22. .path span{background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.35);padding:5px 12px;border-radius:99px;font-size:.85rem}
  23. .progress-wrap{background:rgba(255,255,255,.2);border-radius:99px;height:10px;max-width:440px;overflow:hidden}
  24. #progressBar{height:100%;background:#fff;border-radius:99px;width:0;transition:width .4s}
  25. .progress-note{margin-top:10px;font-size:.88rem;opacity:.9;display:flex;gap:16px;flex-wrap:wrap}
  26. .layout{max-width:1200px;margin:0 auto;padding:28px 24px;display:grid;grid-template-columns:270px 1fr;gap:28px;align-items:start}
  27. nav.toc{background:#fff;border:1px solid var(--line);border-radius:16px;padding:16px;position:sticky;top:16px;max-height:calc(100vh - 32px);overflow:auto}
  28. .toc-group{margin-bottom:14px}
  29. .toc-label{display:block;font-weight:700;font-size:.82rem;color:var(--muted);margin:0 0 6px;letter-spacing:.4px}
  30. .toc-link{display:block;padding:6px 10px;border-radius:8px;font-size:.9rem;color:var(--ink);text-decoration:none;margin-bottom:2px}
  31. .toc-link:hover{background:var(--accent-soft)}
  32. .toc-link.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
  33. .toc-link.done::after{content:" ✓";color:var(--good);font-weight:700}
  34. main{min-width:0}
  35. .module{background:linear-gradient(135deg,#4353ff,#7c3aed);color:#fff;border-radius:16px;padding:22px 26px;margin:0 0 20px}
  36. .module .tag{display:inline-block;background:rgba(255,255,255,.2);padding:2px 10px;border-radius:99px;font-size:.78rem;margin-bottom:8px}
  37. .module h2{margin:0 0 6px;font-size:1.25rem}
  38. .module p{margin:0;opacity:.9;font-size:.95rem}
  39. .lesson{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:26px 28px;margin-bottom:24px;scroll-margin-top:18px;box-shadow:0 1px 3px rgba(20,30,60,.05)}
  40. .lesson-head{display:flex;align-items:baseline;gap:12px;margin-bottom:10px}
  41. .lesson-num{font-weight:800;color:var(--accent);font-size:.9rem;background:var(--accent-soft);padding:3px 10px;border-radius:99px;flex-shrink:0}
  42. .lesson h2{margin:0;font-size:1.3rem}
  43. .lesson p{margin:10px 0}
  44. .lesson ul{margin:10px 0;padding-left:22px}
  45. .lesson li{margin:4px 0}
  46. .formula{font-family:"Cambria Math","STIX Two Math",Georgia,"Times New Roman",serif;font-style:italic;background:var(--formula-bg);padding:11px 16px;border-radius:10px;margin:12px 0;font-size:1.02em;overflow-x:auto;white-space:nowrap}
  47. .frac{display:inline-flex;flex-direction:column;vertical-align:middle;text-align:center;margin:0 3px;font-size:.95em}
  48. .frac>span:first-child{border-bottom:1.5px solid #333;padding:0 5px 2px}
  49. .frac>span:last-child{padding:2px 5px 0}
  50. .callout{border-left:4px solid var(--accent);background:var(--accent-soft);padding:10px 14px;border-radius:0 10px 10px 0;margin:14px 0;font-size:.95rem}
  51. .callout.tip{border-color:var(--good);background:var(--good-soft)}
  52. .callout b{color:var(--accent)}
  53. .callout.tip b{color:var(--good)}
  54. .quiz{border:1.5px dashed var(--accent);border-radius:12px;padding:14px 16px;margin:18px 0 8px;background:#fbfcff}
  55. .quiz-q{margin:0 0 10px;font-weight:600;font-size:.95rem}
  56. .quiz-opt{display:block;width:100%;text-align:left;padding:9px 12px;margin:6px 0;border:1px solid var(--line);border-radius:10px;background:#fff;cursor:pointer;font-size:.92rem;font-family:inherit;color:var(--ink)}
  57. .quiz-opt:hover{border-color:var(--accent)}
  58. .quiz-opt:disabled{cursor:default}
  59. .quiz-opt.correct{background:var(--good-soft);border-color:var(--good);color:var(--good);font-weight:600}
  60. .quiz-opt.wrong{background:var(--bad-soft);border-color:var(--bad);color:var(--bad)}
  61. .quiz-expl{margin:10px 0 0;font-size:.88rem;color:var(--muted)}
  62. .complete-btn{margin-top:16px;border:1.5px solid var(--line);background:#fff;border-radius:99px;padding:8px 18px;cursor:pointer;font-size:.9rem;font-family:inherit;color:var(--ink)}
  63. .complete-btn:hover{border-color:var(--good);color:var(--good)}
  64. .complete-btn.done{background:var(--good);border-color:var(--good);color:#fff;font-weight:600}
  65. .demo-box{border:1px solid var(--line);border-radius:12px;padding:14px;margin:16px 0;background:#fafbfe}
  66. .demo-box .demo-title{font-weight:700;font-size:.95rem;margin:0 0 10px}
  67. canvas{width:100%;height:auto;border:1px solid var(--line);border-radius:10px;background:#fff;display:block}
  68. .controls{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:10px 0;font-size:.9rem}
  69. .controls button{border:1px solid var(--line);background:#fff;border-radius:9px;padding:7px 14px;cursor:pointer;font-family:inherit}
  70. .controls button.primary{background:var(--accent);color:#fff;border-color:var(--accent);font-weight:600}
  71. .controls button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
  72. #gdInfo{font-size:.9rem;color:var(--muted);margin-top:8px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;white-space:pre}

  73. .slider-row{display:flex;align-items:center;gap:10px;margin:8px 0;font-size:.9rem}
  74. .slider-row input[type=range]{flex:1;max-width:320px}
  75. .val{font-weight:700;color:var(--accent);min-width:44px}
  76. .mini{font-size:.8rem;color:var(--muted)}
  77. .chain{font-family:"Cambria Math","STIX Two Math",Georgia,serif;font-style:italic;background:var(--formula-bg);border-radius:10px;padding:12px 16px;margin:10px 0;font-size:.95rem}
  78. .chain div{margin:4px 0}
  79. .lossbar{height:12px;background:#eee;border-radius:99px;overflow:hidden;margin:8px 0}
  80. .lossbar>div{height:100%;background:linear-gradient(90deg,#1a936b,#ff6b35);transition:width .2s}
  81. table.sum{border-collapse:collapse;width:100%;margin:12px 0;font-size:.92rem}
  82. table.sum th,table.sum td{border:1px solid var(--line);padding:8px 12px;text-align:left}
  83. table.sum th{background:var(--formula-bg)}
  84. .checklist{background:var(--good-soft);border-radius:10px;padding:12px 16px;margin:12px 0}
  85. .checklist li{margin:6px 0}
  86. footer{max-width:1200px;margin:0 auto;padding:20px 24px 44px;color:var(--muted);font-size:.85rem;text-align:center}
  87. @media (max-width:900px){
  88.   .layout{grid-template-columns:1fr}
  89.   nav.toc{position:static;max-height:none}
  90.   .toc-group{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:4px}
  91.   .toc-label{grid-column:1/-1}
  92. }
  93. </style>
  94. </head>
  95. <body>
  96. <header class="hero">
  97.   <div class="hero-inner">
  98.     <h1>AI 数学基础 · 渐进式学习路径(扩展版)</h1>
  99.     <p class="sub">22 课 · 6 模块 · 约 5–6 小时 · 从向量到注意力机制,把 AI 背后的数学串成一条线</p>
  100.     <div class="path">
  101.       <span>① 线性代数</span><span>→</span><span>② 微积分</span><span>→</span><span>③ 概率统计</span><span>→</span><span>④ 优化</span><span>→</span><span>⑤ 神经网络数学</span><span>→</span><span>⑥ 综合实战</span>
  102.     </div>
  103.     <div class="progress-wrap"><div id="progressBar"></div></div>
  104.     <div class="progress-note"><span id="progressText">已完成 0 / 22 课</span><span>进度自动保存在浏览器中</span></div>
  105.   </div>
  106. </header>

  107. <div class="layout">
  108. <nav class="toc">
  109.   <div class="toc-group"><span class="toc-label">模块 1 · 线性代数</span>
  110.     <a class="toc-link" href="#l-1-1">1.1 向量与内积</a>
  111.     <a class="toc-link" href="#l-1-2">1.2 矩阵与线性变换</a>
  112.     <a class="toc-link" href="#l-1-3">1.3 行列式·逆·特征值</a>
  113.     <a class="toc-link" href="#l-1-4">1.4 SVD 奇异值分解</a>
  114.   </div>
  115.   <div class="toc-group"><span class="toc-label">模块 2 · 微积分</span>
  116.     <a class="toc-link" href="#l-2-1">2.1 导数与链式法则</a>
  117.     <a class="toc-link" href="#l-2-2">2.2 偏导数与梯度</a>
  118.     <a class="toc-link" href="#l-2-3">2.3 反向传播</a>
  119.   </div>
  120.   <div class="toc-group"><span class="toc-label">模块 3 · 概率与统计</span>
  121.     <a class="toc-link" href="#l-3-1">3.1 概率与分布</a>
  122.     <a class="toc-link" href="#l-3-2">3.2 期望与方差</a>
  123.     <a class="toc-link" href="#l-3-3">3.3 贝叶斯定理</a>
  124.     <a class="toc-link" href="#l-3-4">3.4 熵与交叉熵</a>
  125.     <a class="toc-link" href="#l-3-5">3.5 KL 散度</a>
  126.   </div>
  127.   <div class="toc-group"><span class="toc-label">模块 4 · 优化</span>
  128.     <a class="toc-link" href="#l-4-1">4.1 损失函数</a>
  129.     <a class="toc-link" href="#l-4-2">4.2 梯度下降(演示)</a>
  130.     <a class="toc-link" href="#l-4-3">4.3 学习率与优化器</a>
  131.     <a class="toc-link" href="#l-4-4">4.4 正则化(L1·L2)</a>
  132.   </div>
  133.   <div class="toc-group"><span class="toc-label">模块 5 · 神经网络数学</span>
  134.     <a class="toc-link" href="#l-5-1">5.1 Softmax 推导</a>
  135.     <a class="toc-link" href="#l-5-2">5.2 激活函数比较</a>
  136.     <a class="toc-link" href="#l-5-3">5.3 卷积的数学</a>
  137.     <a class="toc-link" href="#l-5-4">5.4 注意力机制</a>
  138.   </div>
  139.   <div class="toc-group"><span class="toc-label">模块 6 · 综合实战</span>
  140.     <a class="toc-link" href="#l-6-1">6.1 训练一个神经元</a>
  141.     <a class="toc-link" href="#l-6-2">6.2 路线与资源</a>
  142.   </div>
  143. </nav>

  144. <main>
  145. <!-- ================= 模块 1 ================= -->
  146. <section class="module" id="m-1">
  147.   <span class="tag">模块 1</span>
  148.   <h2>线性代数:数据与变换的语言</h2>
  149.   <p>目标:看懂并会算向量和矩阵的运算,理解"神经网络的输入是向量、每一层是一次线性变换",掌握 SVD 降维思想。</p>
  150. </section>

  151. <section class="lesson" id="l-1-1">
  152.   <div class="lesson-head"><span class="lesson-num">1.1</span><h2>向量:AI 的数据语言</h2></div>
  153.   <p>在 AI 里,<b>一切皆向量</b>:一张 28×28 像素的图片展平后是 784 维向量;一个词由 300 维的"词向量"表示;一个样本就是一长串数字。</p>
  154.   <div class="formula">x = (x<sub>1</sub>, x<sub>2</sub>, …, x<sub>n</sub>)<sup>T</sup> —— 一个 n 维向量</div>
  155.   <p>两个基本运算:</p>
  156.   <ul>
  157.     <li><b>加法</b>:a + b = (a<sub>1</sub>+b<sub>1</sub>, a<sub>2</sub>+b<sub>2</sub>, …),逐坐标相加</li>
  158.     <li><b>数乘</b>:λa = (λa<sub>1</sub>, λa<sub>2</sub>, …),把向量"伸缩"</li>
  159.   </ul>
  160.   <p>最重要的运算是<b>内积(点积)</b>:</p>
  161.   <div class="formula">a·b = a<sub>1</sub>b<sub>1</sub> + a<sub>2</sub>b<sub>2</sub> + … + a<sub>n</sub>b<sub>n</sub> = ‖a‖·‖b‖·cos θ</div>
  162.   <p>以及<b>范数</b>(向量的"长度"):</p>
  163.   <div class="formula">‖a‖<sub>2</sub> = √(a<sub>1</sub>² + a<sub>2</sub>² + … + a<sub>n</sub>²)</div>
  164.   <div class="callout tip"><b>💡 直觉:</b>内积 = "按位相乘再求和"。两个向量在每个坐标上同时大,内积就大 → 方向接近、"更相似";内积为 0 表示垂直(不相关)。</div>
  165.   <div class="callout"><b>🎯 AI 联系:</b>"猫"和"狗"的词向量内积很大 → 语义接近;推荐系统、向量检索(数据库)、embedding 相似度都靠内积。</div>
  166.   <div class="callout tip"><b>✏️ 试一试:</b>a=[1,2,3], b=[4,5,6]:a·b = 4+10+18 = <b>32</b>;‖a‖ = √14 ≈ 3.74。心算验证一下。</div>
  167.   <div class="quiz" data-quiz="q-1-1">
  168.     <p class="quiz-q">📝 小测验:内积 a·b 越大,通常说明两个向量……</p>
  169.     <button class="quiz-opt" data-ok="1">方向越接近,越"相似"</button>
  170.     <button class="quiz-opt">长度一定相等</button>
  171.     <button class="quiz-opt">内积一定是负数</button>
  172.     <button class="quiz-opt">内积与方向无关</button>
  173.     <p class="quiz-expl" hidden>✅ 正确!内积越大表示方向越接近("越相似"),这正是词向量和图片特征比较的基础。</p>
  174.   </div>
  175.   <button class="complete-btn" data-lesson="l-1-1">标记完成</button>
  176. </section>

  177. <section class="lesson" id="l-1-2">
  178.   <div class="lesson-head"><span class="lesson-num">1.2</span><h2>矩阵与线性变换</h2></div>
  179.   <p>矩阵就是一个 m 行 × n 列的数字表格。神经网络的每一层核心就是一个矩阵 W:</p>
  180.   <div class="formula">y = Wx + b (y: 输出向量,W: 权重矩阵,x: 输入向量,b: 偏置)</div>
  181.   <p>矩阵乘法的规则:</p>
  182.   <div class="formula">(AB)<sub>ij</sub> = Σ<sub>k</sub> A<sub>ik</sub>·B<sub>kj</sub>  →  (m×n)·(n×p) = (m×p),"内维数"必须相同</div>
  183.   <div class="callout tip"><b>💡 直觉:</b>把矩阵当作一台"变形机器":y = Wx 就是把 x 重新混合、缩放、旋转。W 的每一行,都是"用 x 算出一个新坐标",算的正是行向量与 x 的内积。</div>
  184.   <div class="callout"><b>🎯 AI 联系:</b>W 就是模型<b>学到的参数</b>。W 的行列数决定参数量(输出数 × 输入数);"训练"本质上就是不断调整 W 和 b。</div>
  185.   <div class="callout tip"><b>✏️ 试一试:</b>W = [[2,0],[0,2]],x = [1,3]<sup>T</sup> → y = Wx = [2,6]<sup>T</sup>。这台"机器"做了什么?(把所有坐标放大 2 倍)</div>
  186.   <div class="quiz" data-quiz="q-1-2">
  187.     <p class="quiz-q">📝 小测验:一个 (3×4) 矩阵乘一个 (4×5) 矩阵,结果的形状是?</p>
  188.     <button class="quiz-opt">4×3</button>
  189.     <button class="quiz-opt">3×4</button>
  190.     <button class="quiz-opt" data-ok="1">3×5</button>
  191.     <button class="quiz-opt">无法相乘</button>
  192.     <p class="quiz-expl" hidden>✅ 正确!内维数 4 匹配后消掉,结果取外维数:(3×<b>4</b>)·(<b>4</b>×5) = 3×5。</p>
  193.   </div>
  194.   <button class="complete-btn" data-lesson="l-1-2">标记完成</button>
  195. </section>

  196. <section class="lesson" id="l-1-3">
  197.   <div class="lesson-head"><span class="lesson-num">1.3</span><h2>行列式、逆矩阵与特征值</h2></div>
  198.   <p>三个"进阶概念",知道直觉即可:</p>
  199.   <ul>
  200.     <li><b>行列式 det(W)</b>:变换把面积/体积放大了 det 倍。<b>det = 0</b> 表示空间被"压扁"了(信息丢失),此时矩阵<b>不可逆</b>。</li>
  201.     <li><b>逆矩阵 W⁻¹</b>:满足 W⁻¹W = I,是"撤销变换"的操作。</li>
  202.     <li><b>特征值</b>:Wv = λv —— 向量 v 方向不变,只被拉伸了 λ 倍。</li>
  203.   </ul>
  204.   <div class="formula">det(W)=0 → 不可逆; Wv = λv → v 是特征向量,λ 是特征值</div>
  205.   <div class="callout tip"><b>💡 直觉:</b>特征值告诉我们一次变换"在哪些特殊方向上拉伸了多少"。</div>
  206.   <div class="callout"><b>🎯 AI 联系:</b>降维算法 PCA 就是找数据的"主要方向"(特征向量);det 衡量某层是否丢失信息;大型网络会刻意避免直接求逆矩阵(计算代价太高)。</div>
  207.   <div class="quiz" data-quiz="q-1-3">
  208.     <p class="quiz-q">📝 小测验:det(W) = 0 意味着……</p>
  209.     <button class="quiz-opt">W 是单位矩阵</button>
  210.     <button class="quiz-opt" data-ok="1">W 不可逆,变换把空间"压扁"了</button>
  211.     <button class="quiz-opt">W 一定是对角矩阵</button>
  212.     <button class="quiz-opt">W 的特征值全为 1</button>
  213.     <p class="quiz-expl" hidden>✅ 正确!压扁 = 信息丢失,无法还原,所以不存在逆矩阵。</p>
  214.   </div>
  215.   <button class="complete-btn" data-lesson="l-1-3">标记完成</button>
  216. </section>

  217. <section class="lesson" id="l-1-4">
  218.   <div class="lesson-head"><span class="lesson-num">1.4</span><h2>SVD 奇异值分解</h2></div>
  219.   <p><b>奇异值分解(Singular Value Decomposition)</b>把任意矩阵拆成三个"简单操作"的复合:</p>
  220.   <div class="formula">A = U Σ V<sup>T</sup>  (U: 旋转,Σ: 拉伸,V<sup>T</sup>: 旋转)</div>
  221.   <p>其中:</p>
  222.   <ul>
  223.     <li><b>U</b>(m×m):正交矩阵,列向量是 A 的<b>左奇异向量</b></li>
  224.     <li><b>Σ</b>(m×n 对角):对角线上是<b>奇异值</b> σ₁ ≥ σ₂ ≥ … ≥ 0,表示每个方向的"重要程度"</li>
  225.     <li><b>V<sup>T</sup></b>(n×n):正交矩阵,行向量是 A 的<b>右奇异向量</b></li>
  226.   </ul>
  227.   <p><b>低秩近似:</b>只保留前 k 个奇异值,得到 A 的最佳秩-k 近似:</p>
  228.   <div class="formula">A<sub>k</sub> = Σ<sub>i=1</sub><sup>k</sup> σ<sub>i</sub> u<sub>i</sub> v<sub>i</sub><sup>T</sup></div>
  229.   <div class="callout tip"><b>💡 直觉:</b>SVD 告诉你"这台变形机器最重要的 k 个方向是什么"。丢弃小奇异值 = 丢弃不重要的方向 = 压缩。</div>
  230.   <div class="callout"><b>🎯 AI 联系:</b>① <b>PCA 降维</b>本质就是 SVD(对数据矩阵做 SVD,取前 k 个右奇异向量);② <b>LoRA</b>(大模型微调)用低秩分解 ΔW = BA 近似权重更新;③ 图片压缩、推荐系统矩阵补全都依赖 SVD。</div>
  231.   <div class="callout tip"><b>✏️ 试一试:</b>矩阵 A = [[3,0],[0,1]] 的奇异值是 σ₁=3, σ₂=1。若只保留 σ₁,近似矩阵 [[3,0],[0,0]] 丢掉了什么?(y 方向的信息)</div>
  232.   <div class="quiz" data-quiz="q-1-4">
  233.     <p class="quiz-q">📝 小测验:SVD 中奇异值越大表示……</p>
  234.     <button class="quiz-opt">对应的方向越不重要</button>
  235.     <button class="quiz-opt" data-ok="1">对应的方向"拉伸"越多、越重要</button>
  236.     <button class="quiz-opt">矩阵不可逆</button>
  237.     <button class="quiz-opt">特征值为负</button>
  238.     <p class="quiz-expl" hidden>✅ 正确!奇异值 = 该方向的拉伸倍率,越大越重要,低秩近似保留大的、丢弃小的。</p>
  239.   </div>
  240.   <button class="complete-btn" data-lesson="l-1-4">标记完成</button>
  241. </section>

  242. <!-- ================= 模块 2 ================= -->
  243. <section class="module" id="m-2">
  244.   <span class="tag">模块 2</span>
  245.   <h2>微积分:变化的语言</h2>
  246.   <p>目标:理解导数和链式法则,能回答"某个参数变化一点,损失会怎么变"。</p>
  247. </section>

  248. <section class="lesson" id="l-2-1">
  249.   <div class="lesson-head"><span class="lesson-num">2.1</span><h2>导数与链式法则</h2></div>
  250.   <p>导数 = 瞬时变化率,直观上就是曲线的"坡度"。</p>
  251.   <div class="formula">f′(x) = lim<sub>Δx→0</sub> <span class="frac"><span>f(x+Δx) − f(x)</span><span>Δx</span></span></div>
  252.   <p>常用的几条(背下来就够用):</p>
  253.   <div class="formula">(x<sup>n</sup>)′ = n·x<sup>n−1</sup>  (e<sup>x</sup>)′ = e<sup>x</sup>  (sin x)′ = cos x</div>
  254.   <p><b>链式法则</b>(本课之王):函数套函数时,逐层求导再相乘:</p>
  255.   <div class="formula">d/dx f(g(x)) = f′(g(x)) · g′(x)</div>
  256.   <p>例:f(x) = (2x+1)<sup>3</sup> → f′(x) = 3(2x+1)<sup>2</sup> · 2</p>
  257.   <p>神经网络的激活函数常用 sigmoid:</p>
  258.   <div class="formula">σ(z) = 1 / (1 + e<sup>−z</sup>)  →  σ′(z) = σ(z)(1 − σ(z))</div>
  259.   <div class="callout tip"><b>💡 直觉:</b>链式法则像传送带:把复合函数拆成小块,每块求一次导,然后把它们乘起来。</div>
  260.   <div class="callout"><b>🎯 AI 联系:</b>训练要回答"把 w 改动 ε,损失变化多少" → 就是导数。反向传播(下一课)只是把链式法则用到整张网络。</div>
  261.   <div class="quiz" data-quiz="q-2-1">
  262.     <p class="quiz-q">📝 小测验:f(x) = (3x − 1)² 的导数是?</p>
  263.     <button class="quiz-opt">3(3x − 1)</button>
  264.     <button class="quiz-opt" data-ok="1">6(3x − 1)</button>
  265.     <button class="quiz-opt">2·3x</button>
  266.     <button class="quiz-opt">(3x − 1)³</button>
  267.     <p class="quiz-expl" hidden>✅ 正确!外层求导 2(3x−1)¹,再乘内层导数 3 → 2(3x−1)·3 = 6(3x−1)。</p>
  268.   </div>
  269.   <button class="complete-btn" data-lesson="l-2-1">标记完成</button>
  270. </section>

  271. <section class="lesson" id="l-2-2">
  272.   <div class="lesson-head"><span class="lesson-num">2.2</span><h2>偏导数与梯度</h2></div>
  273.   <p>神经网络的参数不是一个、而是几百万个。对多元函数 f(x, y),<b>偏导数</b>表示只沿一个方向变化的速度:</p>
  274.   <div class="formula">f(x,y) = x²y → ∂f/∂x = 2xy, ∂f/∂y = x²</div>
  275.   <p>把所有偏导数打包成一个向量,就是<b>梯度</b>:</p>
  276.   <div class="formula">∇f = (∂f/∂x, ∂f/∂y, …, ∂f/∂x<sub>n</sub>)</div>
  277.   <div class="callout tip"><b>💡 直觉:</b>球在山坡上,梯度指向"上坡最快"的方向 —— 所以想下山,要朝<b>相反方向</b>(负梯度)走。</div>
  278.   <div class="callout"><b>🎯 AI 联系:</b>损失函数 L 关于所有参数(w₁, w₂, …, w<sub>百万</sub>)的梯度,是一个百万维向量,每个分量告诉你"这个参数该往哪个方向调"。</div>
  279.   <div class="quiz" data-quiz="q-2-2">
  280.     <p class="quiz-q">📝 小测验:f(x, y) = x² + y³,∂f/∂y = ?</p>
  281.     <button class="quiz-opt">2x</button>
  282.     <button class="quiz-opt">2x²y</button>
  283.     <button class="quiz-opt" data-ok="1">3y²</button>
  284.     <button class="quiz-opt">x²</button>
  285.     <p class="quiz-expl" hidden>✅ 正确!对 y 求偏导时把 x 当常数:∂/∂y (x² + y³) = 3y²。</p>
  286.   </div>
  287.   <button class="complete-btn" data-lesson="l-2-2">标记完成</button>
  288. </section>

  289. <section class="lesson" id="l-2-3">
  290.   <div class="lesson-head"><span class="lesson-num">2.3</span><h2>反向传播:层层求导</h2></div>
  291.   <p>看一个最简单的神经元(前向传播):</p>
  292.   <div class="formula">z = wx + b → a = σ(z) → L = (a − t)²</div>
  293.   <p>反向传播就是把链式法则从 L 往外一层层拆:</p>
  294.   <div class="formula">∂L/∂w = (∂L/∂a)·(∂a/∂z)·(∂z/∂w) = 2(a−t) · σ(z)(1−σ(z)) · x</div>
  295.   <div class="callout tip"><b>💡 直觉:</b>链条的每一环 = 某一层的导数。网络再深,也只是把更多环串起来。</div>
  296.   <div class="callout"><b>🎯 AI 联系:</b>这就是"反向传播算法"的全部真相:前向算输出并记录中间量,反向从损失一路推回每个参数。框架里的"autograd"自动帮你做这件事。</div>
  297.   <div class="quiz" data-quiz="q-2-3">
  298.     <p class="quiz-q">📝 小测验:反向传播本质上是……</p>
  299.     <button class="quiz-opt">矩阵乘法的重复计算</button>
  300.     <button class="quiz-opt">贝叶斯定理的应用</button>
  301.     <button class="quiz-opt" data-ok="1">把链式法则从输出层一层层往前套</button>
  302.     <button class="quiz-opt">随机搜索参数空间</button>
  303.     <p class="quiz-expl" hidden>✅ 正确!反向传播 = 链式法则 + 动态规划式的记录复用,没有更多魔法。</p>
  304.   </div>
  305.   <button class="complete-btn" data-lesson="l-2-3">标记完成</button>
  306. </section>

  307. <!-- ================= 模块 3 ================= -->
  308. <section class="module" id="m-3">
  309.   <span class="tag">模块 3</span>
  310.   <h2>概率与统计:不确定性的语言</h2>
  311.   <p>目标:理解分布、期望、贝叶斯、熵与 KL 散度,能读懂模型输出和损失函数的含义。</p>
  312. </section>

  313. <section class="lesson" id="l-3-1">
  314.   <div class="lesson-head"><span class="lesson-num">3.1</span><h2>概率与分布</h2></div>
  315.   <p>随机变量 X 的<b>分布</b>列出每种取值的可能性,概率总和为 1:</p>
  316.   <div class="formula">0 ≤ P(A) ≤ 1  Σ P = 1</div>
  317.   <p>两条基本规则:</p>
  318.   <div class="formula">条件概率:P(A|B) = P(A∩B) / P(B)  独立:P(A∩B) = P(A)·P(B)</div>
  319.   <div class="callout tip"><b>💡 直觉:</b>分布 = 一幅"全景图":不是单个数字,而是所有可能结果各自的可能性。</div>
  320.   <div class="callout"><b>🎯 AI 联系:</b>模型输出的 Softmax 就是一个类别分布:"70% 猫、20% 狗、10% 狮子"——这叫<b>软标签</b>,而不是直接猜一个类。</div>
  321.   <div class="quiz" data-quiz="q-3-1">
  322.     <p class="quiz-q">📝 小测验:掷一次骰子,"点数 ≤ 3" 的概率是?</p>
  323.     <button class="quiz-opt">1/6</button>
  324.     <button class="quiz-opt">2/3</button>
  325.     <button class="quiz-opt" data-ok="1">1/2</button>
  326.     <button class="quiz-opt">1</button>
  327.     <p class="quiz-expl" hidden>✅ 正确!{1, 2, 3} 三种情况,各 1/6,相加 = 3/6 = 1/2。</p>
  328.   </div>
  329.   <button class="complete-btn" data-lesson="l-3-1">标记完成</button>
  330. </section>

  331. <section class="lesson" id="l-3-2">
  332.   <div class="lesson-head"><span class="lesson-num">3.2</span><h2>期望与方差</h2></div>
  333.   <div class="formula">期望 E[X] = Σ xᵢ·pᵢ (加权平均)</div>
  334.   <div class="formula">方差 Var(X) = E[(X − E[X])²] = E[X²] − (E[X])² (波动程度)</div>
  335.   <div class="callout tip"><b>💡 直觉:</b>期望回答"平均来说会是多少",方差回答"结果有多飘"。</div>
  336.   <div class="callout"><b>🎯 AI 联系:</b>训练目标是让<b>数据分布上的期望误差</b>尽量小;SGD 用随机小批量来"估计"这个期望梯度,噪声反而帮助泛化。</div>
  337.   <div class="quiz" data-quiz="q-3-2">
  338.     <p class="quiz-q">📝 小测验:公平骰子的期望点数 E[X] = ?</p>
  339.     <button class="quiz-opt">2</button>
  340.     <button class="quiz-opt">3</button>
  341.     <button class="quiz-opt" data-ok="1">3.5</button>
  342.     <button class="quiz-opt">6</button>
  343.     <p class="quiz-expl" hidden>✅ 正确!E = (1+2+3+4+5+6)×(1/6) = 21/6 = 3.5。</p>
  344.   </div>
  345.   <button class="complete-btn" data-lesson="l-3-2">标记完成</button>
  346. </section>

  347. <section class="lesson" id="l-3-3">
  348.   <div class="lesson-head"><span class="lesson-num">3.3</span><h2>贝叶斯定理</h2></div>
  349.   <p>用新证据更新旧观点:</p>
  350.   <div class="formula">P(A|B) = P(B|A)·P(A) / P(B) (后验 = 似然 × 先验 ÷ 证据)</div>
  351.   <p><b>经典例子:</b>某病患病率 P(A)=1%,检测灵敏度 P(B|A)=99%,健康者假阳性 P(B|¬A)=5%。检测阳性后真的患病的概率是?</p>
  352.   <div class="formula">P(A|B) = 0.01×0.99 / (0.01×0.99 + 0.99×0.05) ≈ 16.7%</div>
  353.   <div class="callout tip"><b>💡 直觉:</b>"阳性 ≠ 一定患病"。先验概率(base rate)非常重要,这也是朴素贝叶斯、垃圾邮件过滤器的思想。</div>
  354.   <div class="callout"><b>🎯 AI 联系:</b>贝叶斯深度学习:模型参数不是固定值,而是一个分布;每次见到新数据,就从先验更新到后验。</div>
  355.   <div class="quiz" data-quiz="q-3-3">
  356.     <p class="quiz-q">📝 小测验:上面的检测例子中,P(A|B) ≈ ?</p>
  357.     <button class="quiz-opt">≈ 99%</button>
  358.     <button class="quiz-opt">≈ 50%</button>
  359.     <button class="quiz-opt">≈ 0.5%</button>
  360.     <button class="quiz-opt" data-ok="1">≈ 16.7%</button>
  361.     <p class="quiz-expl" hidden>✅ 正确!0.0099 / 0.0594 ≈ 16.7%。先验概率让"阳性"远没直觉以为的那么可靠。</p>
  362.   </div>
  363.   <button class="complete-btn" data-lesson="l-3-3">标记完成</button>
  364. </section>

  365. <section class="lesson" id="l-3-4">
  366.   <div class="lesson-head"><span class="lesson-num">3.4</span><h2>熵与交叉熵</h2></div>
  367.   <p><b>熵</b>衡量分布的"不确定程度"(单位 bit):</p>
  368.   <div class="formula">H(p) = − Σ pᵢ·log₂ pᵢ  (确定 → 0;公平硬币 → 1 bit)</div>
  369.   <p><b>交叉熵</b>衡量"真实标签在预测分布下有多意外",二元分类时:</p>
  370.   <div class="formula">L = −[ y·ln p + (1−y)·ln(1−p) ] (y=1 时 L = −ln p)</div>
  371.   <div class="callout tip"><b>💡 直觉:</b>为什么用 log?真实类别的预测概率趋近 0 时("自信地错了"),惩罚 → ∞,逼着模型不敢乱自信。</div>
  372.   <div class="callout"><b>🎯 AI 联系:</b>交叉熵是分类任务的标准损失函数(MSE 也能用,但对"自信地错"惩罚得更猛)。</div>
  373.   <div class="quiz" data-quiz="q-3-4">
  374.     <p class="quiz-q">📝 小测验:真实标签 y = 1 时,预测概率 q 越接近 1,交叉熵……</p>
  375.     <button class="quiz-opt">越大</button>
  376.     <button class="quiz-opt" data-ok="1">越小</button>
  377.     <button class="quiz-opt">保持不变</button>
  378.     <button class="quiz-opt">无法定义</button>
  379.     <p class="quiz-expl" hidden>✅ 正确!y=1 时 L = −ln q,q→1 时 L→0,预测越好损失越小。</p>
  380.   </div>
  381.   <button class="complete-btn" data-lesson="l-3-4">标记完成</button>
  382. </section>

  383. <section class="lesson" id="l-3-5">
  384.   <div class="lesson-head"><span class="lesson-num">3.5</span><h2>KL 散度(Kullback-Leibler)</h2></div>
  385.   <p>KL 散度衡量<b>两个分布之间的距离</b>(非对称):</p>
  386.   <div class="formula">D<sub>KL</sub>(P ‖ Q) = Σ P(x) · log( P(x) / Q(x) )</div>
  387.   <p>性质:</p>
  388.   <ul>
  389.     <li>D<sub>KL</sub>(P ‖ Q) ≥ 0,当且仅当 P = Q 时为 0</li>
  390.     <li><b>非对称</b>:D<sub>KL</sub>(P ‖ Q) ≠ D<sub>KL</sub>(Q ‖ P)</li>
  391.     <li>与交叉熵的关系:H(P, Q) = H(P) + D<sub>KL</sub>(P ‖ Q)</li>
  392.   </ul>
  393.   <div class="callout tip"><b>💡 直觉:</b>用分布 Q 去编码真实分布 P 的数据,比"最优编码"多花了多少信息。KL = 0 → 完全一致。</div>
  394.   <div class="callout"><b>🎯 AI 联系:</b>① <b>知识蒸馏</b>:学生网络的输出分布逼近教师网络 → 最小化 KL;② <b>VAE</b>:正则化项 = KL(后验 ‖ 先验);③ <b>RLHF / PPO</b>:约束新策略不偏离参考策略太远 → KL penalty;④ <b>变分推断</b>的核心目标。</div>
  395.   <div class="callout tip"><b>✏️ 试一试:</b>P = [0.5, 0.5], Q = [0.9, 0.1]:D<sub>KL</sub>(P‖Q) = 0.5·ln(0.5/0.9) + 0.5·ln(0.5/0.1) ≈ 0.5(−0.588) + 0.5(1.609) ≈ <b>0.51</b>。</div>
  396.   <div class="quiz" data-quiz="q-3-5">
  397.     <p class="quiz-q">📝 小测验:KL 散度 D<sub>KL</sub>(P ‖ Q) = 0 意味着……</p>
  398.     <button class="quiz-opt">P 和 Q 都是均匀分布</button>
  399.     <button class="quiz-opt" data-ok="1">P 和 Q 完全相同</button>
  400.     <button class="quiz-opt">P 和 Q 独立</button>
  401.     <button class="quiz-opt">P 的熵为 0</button>
  402.     <p class="quiz-expl" hidden>✅ 正确!KL = 0 ⟺ P(x) = Q(x) 对所有 x 成立,两个分布完全一致。</p>
  403.   </div>
  404.   <button class="complete-btn" data-lesson="l-3-5">标记完成</button>
  405. </section>

  406. <!-- ================= 模块 4 ================= -->
  407. <section class="module" id="m-4">
  408.   <span class="tag">模块 4</span>
  409.   <h2>优化:让模型变好的方法</h2>
  410.   <p>目标:理解损失函数与梯度下降,能直觉地判断学习率大小是否合适,理解正则化。</p>
  411. </section>

  412. <section class="lesson" id="l-4-1">
  413.   <div class="lesson-head"><span class="lesson-num">4.1</span><h2>损失函数:衡量"错多少"</h2></div>
  414.   <p>损失函数 L 把"模型错得有多离谱"压成<b>一个数字</b>,越小越好:</p>
  415.   <div class="formula">回归:MSE = (1/n) · Σ (yᵢ − ŷᵢ)²  分类:交叉熵(见 3.4)</div>
  416.   <p>一个好的损失函数要:① 模型越好值越低;② <b>光滑可导</b>(这样才能用梯度下降)。</p>
  417.   <div class="callout"><b>🎯 AI 联系:</b>整个训练过程 = 最小化 L。"学习"在数学上就是优化问题。</div>
  418.   <div class="quiz" data-quiz="q-4-1">
  419.     <p class="quiz-q">📝 小测验:MSE 什么时候取最小值 0?</p>
  420.     <button class="quiz-opt">预测总是 0 时</button>
  421.     <button class="quiz-opt">样本数很少时</button>
  422.     <button class="quiz-opt" data-ok="1">每个预测都等于真实值时</button>
  423.     <button class="quiz-opt">方差很大时</button>
  424.     <p class="quiz-expl" hidden>✅ 正确!平方项非负,全部为 0 时才整体为 0。</p>
  425.   </div>
  426.   <button class="complete-btn" data-lesson="l-4-1">标记完成</button>
  427. </section>

  428. <section class="lesson" id="l-4-2">
  429.   <div class="lesson-head"><span class="lesson-num">4.2</span><h2>梯度下降:下山算法</h2></div>
  430.   <p>梯度下降的更新规则只有一行:</p>
  431.   <div class="formula">θ<sub>t+1</sub> = θ<sub>t</sub> − η·∇L(θ<sub>t</sub>)</div>
  432.   <p>θ 是参数,η 是学习率(步长)。∇L 指向上坡最快方向 → 减去它就是沿下降方向走一步。</p>
  433.   <div class="callout tip"><b>💡 直觉:</b>像蒙眼下山:感受坡度(梯度),迈一小步(η),再感受,再迈……</div>
  434.   <div class="demo-box">
  435.     <p class="demo-title">🎮 交互演示:调学习率 η,看小球怎么下山</p>
  436.     <canvas id="gdCanvas" width="640" height="320"></canvas>
  437.     <div class="controls">
  438.       <span>曲线:</span>
  439.       <button id="gdFn0" class="on">抛物线 x²</button>
  440.       <button id="gdFn1">起伏曲线</button>
  441.       <button id="gdBtn" class="primary">▶ 开始</button>
  442.       <button id="gdReset">↺ 重置</button>
  443.     </div>
  444.     <div class="slider-row">
  445.       <span>学习率 η =</span><span class="val" id="gdEtaVal">0.40</span>
  446.       <input type="range" id="gdEta" min="0.05" max="2.4" step="0.05" value="0.4">
  447.     </div>
  448.     <div class="slider-row">
  449.       <span>速度(步/秒) =</span><span class="val" id="gdSpeedVal">20</span>
  450.       <input type="range" id="gdSpeed" min="1" max="60" step="1" value="20">
  451.     </div>
  452.     <div id="gdInfo">x = 2.500, f(x) = 6.250, 步数 = 0</div>
  453.     <p class="mini">试试把 η 调到 1.5 或 2.0 再看一遍——发生了什么?</p>
  454.   </div>
  455.   <div class="quiz" data-quiz="q-4-2">
  456.     <p class="quiz-q">📝 小测验:θ ← θ − η∇L 本质上是在……</p>
  457.     <button class="quiz-opt">随机走</button>
  458.     <button class="quiz-opt" data-ok="1">沿损失下降最快的方向走一小步</button>
  459.     <button class="quiz-opt">把参数放大</button>
  460.     <button class="quiz-opt">给参数排序</button>
  461.     <p class="quiz-expl" hidden>✅ 正确!梯度指向上坡最快方向,减掉它 = 沿下降方向走一步。</p>
  462.   </div>
  463.   <button class="complete-btn" data-lesson="l-4-2">标记完成</button>
  464. </section>

  465. <section class="lesson" id="l-4-3">
  466.   <div class="lesson-head"><span class="lesson-num">4.3</span><h2>学习率与优化器</h2></div>
  467.   <ul>
  468.     <li><b>η 太小</b>:慢得像蜗牛,收敛太慢;<b>η 太大</b>:一步迈过谷底,震荡甚至发散(上面的演示里见过)。</li>
  469.     <li><b>SGD(随机梯度下降)</b>:每次只用一小批(mini-batch)样本估计梯度 → 有噪声,但更省、更泛化。</li>
  470.     <li><b>动量(Momentum)</b>:给更新加"惯性",减少震荡、冲过平缓地带。</li>
  471.     <li><b>Adam</b>:给每个参数自适应地调步长,是现代网络的默认选择。</li>
  472.   </ul>
  473.   <div class="callout"><b>🎯 AI 联系:</b>你几乎不需要自己发明优化器——但调学习率曲线(loss vs. 训练步数)是每个工程师的看家本领。</div>
  474.   <div class="quiz" data-quiz="q-4-3">
  475.     <p class="quiz-q">📝 小测验:学习率 η 太大通常会导致……</p>
  476.     <button class="quiz-opt" data-ok="1">震荡甚至发散</button>
  477.     <button class="quiz-opt">收敛更快且必然最优</button>
  478.     <button class="quiz-opt">损失立即变为 0</button>
  479.     <button class="quiz-opt">收敛速度与 η 无关</button>
  480.     <p class="quiz-expl" hidden>✅ 正确!步太长会迈过谷底来回震荡,甚至直接飞出去(发散)。</p>
  481.   </div>
  482.   <button class="complete-btn" data-lesson="l-4-3">标记完成</button>
  483. </section>

  484. <section class="lesson" id="l-4-4">
  485.   <div class="lesson-head"><span class="lesson-num">4.4</span><h2>正则化:L1 与 L2</h2></div>
  486.   <p>模型太复杂会"背答案"(过拟合)。正则化在损失里加一个惩罚项,逼模型"简单":</p>
  487.   <div class="formula">L<sub>reg</sub> = L<sub>original</sub> + λ · Ω(W)</div>
  488.   <table class="sum">
  489.     <tr><th>类型</th><th>惩罚项 Ω(W)</th><th>效果</th><th>直觉</th></tr>
  490.     <tr><td><b>L2(权重衰减)</b></td><td>‖W‖₂² = Σ wᵢ²</td><td>权重趋向小而均匀</td><td>把参数"往原点拉"</td></tr>
  491.     <tr><td><b>L1(Lasso)</b></td><td>‖W‖₁ = Σ |wᵢ|</td><td>很多权重恰好变 0</td><td>自动"剪枝"不重要的连接</td></tr>
  492.     <tr><td><b>Dropout</b></td><td>训练时随机丢弃神经元</td><td>防止依赖单一路径</td><td>相当于隐式集成</td></tr>
  493.   </table>
  494.   <div class="callout tip"><b>💡 直觉:</b>L2 像"弹性绳"把参数拉向 0;L1 像"硬阈值"——不够重要的直接归零。λ 控制惩罚力度。</div>
  495.   <div class="callout"><b>🎯 AI 联系:</b>① 几乎所有现代网络都用 weight decay(L2);② L1 用于稀疏模型 / 特征选择;③ Dropout 是 CNN / Transformer 标配;④ 大模型微调的 LoRA 本身就是一种低秩正则化。</div>
  496.   <div class="quiz" data-quiz="q-4-4">
  497.     <p class="quiz-q">📝 小测验:L1 正则化最显著的效果是……</p>
  498.     <button class="quiz-opt">让所有权重都变大</button>
  499.     <button class="quiz-opt" data-ok="1">让许多权重恰好变为 0(稀疏)</button>
  500.     <button class="quiz-opt">增加模型参数量</button>
  501.     <button class="quiz-opt">加快训练速度</button>
  502.     <p class="quiz-expl" hidden>✅ 正确!L1 的 |w| 在原点不可导,梯度下降会把不重要的权重推到恰好 0。</p>
  503.   </div>
  504.   <button class="complete-btn" data-lesson="l-4-4">标记完成</button>
  505. </section>

  506. <!-- ================= 模块 5 ================= -->
  507. <section class="module" id="m-5">
  508.   <span class="tag">模块 5</span>
  509.   <h2>神经网络数学:核心组件推导</h2>
  510.   <p>目标:理解 Softmax、激活函数、卷积、注意力机制背后的数学,不再把网络当黑箱。</p>
  511. </section>

  512. <section class="lesson" id="l-5-1">
  513.   <div class="lesson-head"><span class="lesson-num">5.1</span><h2>Softmax 推导与性质</h2></div>
  514.   <p>Softmax 把一组<b>任意实数</b>(logits)变成一组<b>概率分布</b>:</p>
  515.   <div class="formula">softmax(z<sub>i</sub>) = e<sup>z<sub>i</sub></sup> / Σ<sub>j</sub> e<sup>z<sub>j</sub></sup></div>
  516.   <p><b>为什么这样设计?</b></p>
  517.   <ul>
  518.     <li>e<sup>z</sup> > 0 → 保证输出非负</li>
  519.     <li>除以总和 → 保证概率和为 1</li>
  520.     <li>指数放大差异 → 最大的 logit 获得最高概率("赢家通吃"倾向)</li>
  521.   </ul>
  522.   <p><b>数值稳定技巧:</b>先减去最大值再算指数,避免溢出:</p>
  523.   <div class="formula">softmax(z<sub>i</sub>) = e<sup>z<sub>i</sub> − z<sub>max</sub></sup> / Σ<sub>j</sub> e<sup>z<sub>j</sub> − z<sub>max</sub></sup></div>
  524.   <p><b>温度参数 τ:</b>控制"自信程度":</p>
  525.   <div class="formula">softmax(z<sub>i</sub>/τ)  τ→0 → 变成 argmax(硬选择);τ→∞ → 均匀分布</div>
  526.   <div class="callout tip"><b>💡 直觉:</b>Softmax = "把分数变成投票比例"。温度高 → 投票分散(不确定);温度低 → 赢家通吃(很自信)。</div>
  527.   <div class="callout"><b>🎯 AI 联系:</b>① 分类模型的最后一层;② 注意力权重计算(见 5.4);③ LLM 生成时采样温度 τ 控制创造性;④ 知识蒸馏中教师/学生都用 Softmax 输出分布。</div>
  528.   <div class="callout tip"><b>✏️ 试一试:</b>z = [2, 1, 0]:e²=7.39, e¹=2.72, e⁰=1 → 总和 11.11 → softmax = [0.665, 0.245, 0.090]。</div>
  529.   <div class="quiz" data-quiz="q-5-1">
  530.     <p class="quiz-q">📝 小测验:Softmax 输出中,哪个分量最大?</p>
  531.     <button class="quiz-opt">对应最小 logit 的分量</button>
  532.     <button class="quiz-opt" data-ok="1">对应最大 logit 的分量</button>
  533.     <button class="quiz-opt">总是第一个分量</button>
  534.     <button class="quiz-opt">随机决定</button>
  535.     <p class="quiz-expl" hidden>✅ 正确!e^z 单调递增,最大的 z 产生最大的 e^z,除以总和后仍最大。</p>
  536.   </div>
  537.   <button class="complete-btn" data-lesson="l-5-1">标记完成</button>
  538. </section>

  539. <section class="lesson" id="l-5-2">
  540.   <div class="lesson-head"><span class="lesson-num">5.2</span><h2>激活函数比较</h2></div>
  541.   <p>激活函数给网络引入<b>非线性</b>——没有它,多层线性变换等价于一层。</p>
  542.   <table class="sum">
  543.     <tr><th>函数</th><th>公式</th><th>导数</th><th>优缺点</th></tr>
  544.     <tr><td><b>Sigmoid</b></td><td>σ(z) = 1/(1+e<sup>−z</sup>)</td><td>σ(z)(1−σ(z))</td><td>输出 (0,1);但 z 大时导数→0(梯度消失)</td></tr>
  545.     <tr><td><b>Tanh</b></td><td>tanh(z) = (e<sup>z</sup>−e<sup>−z</sup>)/(e<sup>z</sup>+e<sup>−z</sup>)</td><td>1 − tanh²(z)</td><td>输出 (−1,1),零中心;仍有梯度消失</td></tr>
  546.     <tr><td><b>ReLU</b></td><td>max(0, z)</td><td>1 (z>0), 0 (z≤0)</td><td>计算快、缓解梯度消失;但 z<0 时梯度=0("死神经元")</td></tr>
  547.     <tr><td><b>Leaky ReLU</b></td><td>max(0.01z, z)</td><td>1 或 0.01</td><td>解决"死神经元"</td></tr>
  548.     <tr><td><b>GELU</b></td><td>z·Φ(z)(Φ 为标准正态 CDF)</td><td>≈ 光滑过渡</td><td>Transformer 默认激活</td></tr>
  549.   </table>
  550.   <div class="callout tip"><b>💡 直觉:</b>ReLU 像"开关"——正信号通过,负信号截断。GELU 像"软开关"——过渡更平滑,训练更稳定。</div>
  551.   <div class="callout"><b>🎯 AI 联系:</b>CNN / MLP 默认 ReLU;Transformer / LLM 默认 GELU 或 Swish;Sigmoid 仍用于二分类输出层和门控机制(LSTM / GRU)。</div>
  552.   <div class="quiz" data-quiz="q-5-2">
  553.     <p class="quiz-q">📝 小测验:ReLU(z) = max(0, z) 在 z = −3 时的导数是?</p>
  554.     <button class="quiz-opt">1</button>
  555.     <button class="quiz-opt" data-ok="1">0</button>
  556.     <button class="quiz-opt">−1</button>
  557.     <button class="quiz-opt">不存在</button>
  558.     <p class="quiz-expl" hidden>✅ 正确!z < 0 时 ReLU 输出恒为 0,导数 = 0(梯度消失 / 死神经元)。</p>
  559.   </div>
  560.   <button class="complete-btn" data-lesson="l-5-2">标记完成</button>
  561. </section>

  562. <section class="lesson" id="l-5-3">
  563.   <div class="lesson-head"><span class="lesson-num">5.3</span><h2>卷积的数学</h2></div>
  564.   <p>卷积(Convolution)是 CNN 的核心运算。对离散信号:</p>
  565.   <div class="formula">(f * g)(t) = Σ<sub>k</sub> f(k) · g(t − k)</div>
  566.   <p>在 CNN 里,"卷积"实际是<b>互相关(cross-correlation)</b>——用滤波器核 K 在输入 X 上滑动:</p>
  567.   <div class="formula">Y[i,j] = Σ<sub>m</sub> Σ<sub>n</sub> X[i+m, j+n] · K[m, n]</div>
  568.   <p>关键参数:</p>
  569.   <ul>
  570.     <li><b>核大小</b>(如 3×3):感受野,决定"看多大范围"</li>
  571.     <li><b>步幅(stride)</b>:滑动间隔,控制输出尺寸</li>
  572.     <li><b>填充(padding)</b>:边界补零,保持尺寸</li>
  573.     <li><b>通道数</b>:每个核"看"所有输入通道,输出多个特征图</li>
  574.   </ul>
  575.   <p>输出尺寸公式:</p>
  576.   <div class="formula">out = ⌊(in − kernel + 2·padding) / stride⌋ + 1</div>
  577.   <div class="callout tip"><b>💡 直觉:</b>卷积核 = "局部模式探测器"。3×3 核在图像上滑动,每次问"这 3×3 小块长什么样?"。多个核 = 多种模式(边缘、纹理、形状)。</div>
  578.   <div class="callout"><b>🎯 AI 联系:</b>① 卷积的<b>权重共享</b>让参数量远小于全连接层;② 感受野逐层扩大 → 深层"看到"整张图;③ 1×1 卷积 = 跨通道的线性变换(通道混合);④ 转置卷积(deconvolution)用于上采样 / 图像生成。</div>
  579.   <div class="callout tip"><b>✏️ 试一试:</b>输入 5×5,核 3×3,stride=1,padding=0 → 输出尺寸 = (5−3)/1 + 1 = <b>3×3</b>。</div>
  580.   <div class="quiz" data-quiz="q-5-3">
  581.     <p class="quiz-q">📝 小测验:卷积核的"权重共享"意味着……</p>
  582.     <button class="quiz-opt">每个位置用不同的参数</button>
  583.     <button class="quiz-opt" data-ok="1">同一个核在整张图上滑动,参数只有一份</button>
  584.     <button class="quiz-opt">核大小等于图像大小</button>
  585.     <button class="quiz-opt">不需要训练</button>
  586.     <p class="quiz-expl" hidden>✅ 正确!一个 3×3 核只有 9 个参数,但它在整张图上每个位置都用同一组参数——这就是权重共享。</p>
  587.   </div>
  588.   <button class="complete-btn" data-lesson="l-5-3">标记完成</button>
  589. </section>

  590. <section class="lesson" id="l-5-4">
  591.   <div class="lesson-head"><span class="lesson-num">5.4</span><h2>注意力机制的数学</h2></div>
  592.   <p>注意力(Attention)让模型"动态地决定看哪里"。核心公式(Scaled Dot-Product Attention):</p>
  593.   <div class="formula">Attention(Q, K, V) = softmax( QK<sup>T</sup> / √d<sub>k</sub> ) · V</div>
  594.   <p>拆解每一步:</p>
  595.   <ul>
  596.     <li><b>Q(Query)</b>:当前 token "我想找什么信息?"</li>
  597.     <li><b>K(Key)</b>:每个 token "我是什么?"</li>
  598.     <li><b>V(Value)</b>:每个 token "我能提供什么信息?"</li>
  599.     <li><b>QK<sup>T</sup></b>:内积 → 相似度矩阵(每个 query 对每个 key 的匹配度)</li>
  600.     <li><b>/ √d<sub>k</sub></b>:缩放,防止内积过大导致 softmax 梯度消失</li>
  601.     <li><b>softmax</b>:把相似度变成权重分布(和为 1)</li>
  602.     <li><b>× V</b>:加权求和 → 每个位置得到"综合了所有相关 token"的新表示</li>
  603.   </ul>
  604.   <p><b>多头注意力:</b>h 个头并行做注意力,拼接后线性变换:</p>
  605.   <div class="formula">MultiHead = Concat(head₁, …, head<sub>h</sub>) · W<sup>O</sup></div>
  606.   <div class="callout tip"><b>💡 直觉:</b>注意力 = "图书馆检索":Q 是你的搜索词,K 是每本书的书名,V 是书的内容。softmax 决定"每本书借多少页"。</div>
  607.   <div class="callout"><b>🎯 AI 联系:</b>① Transformer(GPT / BERT / LLM)的核心组件;② 自注意力:Q=K=V(同一序列自己看自己);③ 交叉注意力:Q 来自解码器,K/V 来自编码器;④ 注意力权重可视化 → 模型"在看哪里"。</div>
  608.   <div class="callout tip"><b>✏️ 试一试:</b>Q=[1,0], K₁=[1,0], K₂=[0,1], d<sub>k</sub>=2。QK₁ᵀ=1, QK₂ᵀ=0 → 缩放后 [1/√2, 0] ≈ [0.71, 0] → softmax ≈ [0.67, 0.33]。Q 更关注 K₁。</div>
  609.   <div class="quiz" data-quiz="q-5-4">
  610.     <p class="quiz-q">📝 小测验:注意力公式中除以 √d<sub>k</sub> 的目的是……</p>
  611.     <button class="quiz-opt">减少计算量</button>
  612.     <button class="quiz-opt" data-ok="1">防止内积过大导致 softmax 饱和(梯度消失)</button>
  613.     <button class="quiz-opt">让输出维度变小</button>
  614.     <button class="quiz-opt">增加非线性</button>
  615.     <p class="quiz-expl" hidden>✅ 正确!d_k 大时 QK^T 方差大 → softmax 输出接近 one-hot → 梯度极小。缩放使方差归一。</p>
  616.   </div>
  617.   <button class="complete-btn" data-lesson="l-5-4">标记完成</button>
  618. </section>

  619. <!-- ================= 模块 6 ================= -->
  620. <section class="module" id="m-6">
  621.   <span class="tag">模块 6</span>
  622.   <h2>综合实战:把一切串起来</h2>
  623.   <p>目标:亲手推一遍前向 + 反向传播,亲眼看着参数被"训练"。</p>
  624. </section>

  625. <section class="lesson" id="l-6-1">
  626.   <div class="lesson-head"><span class="lesson-num">6.1</span><h2>训练一个神经元</h2></div>
  627.   <p>把所有模块全部串起来——一个神经元,输入 x₁, x₂,目标 t = 1.0:</p>
  628.   <div class="formula">前向:z = w₁x₁ + w₂x₂ + b → a = σ(z) → L = (a − t)²</div>
  629.   <div class="formula">反向:∂L/∂wᵢ = 2(a−t) · a(1−a) · xᵢ  更新:wᵢ ← wᵢ − η·∂L/∂wᵢ</div>
  630.   <div class="demo-box">
  631.     <p class="demo-title">🎮 亲手训练:拖动权重试试,或点"训练"</p>
  632.     <div class="slider-row"><span>w₁ =</span><span class="val" id="valW1">0.50</span><input type="range" id="slW1" min="-3" max="3" step="0.05" value="0.5"></div>
  633.     <div class="slider-row"><span>w₂ =</span><span class="val" id="valW2">-0.20</span><input type="range" id="slW2" min="-3" max="3" step="0.05" value="-0.2"></div>
  634.     <div class="slider-row"><span>b =</span><span class="val" id="valB">0.00</span><input type="range" id="slB" min="-2" max="2" step="0.05" value="0"></div>
  635.     <div class="controls">
  636.       <button id="btnNr1" class="primary">训练 1 步(η=0.5)</button>
  637.       <button id="btnNr100">训练 100 步</button>
  638.       <button id="btnNrReset">↺ 重置</button>
  639.       <span class="mini">已训练 <b id="nrSteps">0</b> 步</span>
  640.     </div>
  641.     <div class="chain">
  642.       <div>z = w₁·0.8 + w₂·0.4 + b = <b id="nrZ">0.320</b></div>
  643.       <div>a = σ(z) = <b id="nrA">0.579</b></div>
  644.       <div>∂L/∂a = 2(a−t) = <b id="nrDLa">-0.841</b></div>
  645.       <div>∂a/∂z = a(1−a) = <b id="nrDaz">0.244</b></div>
  646.       <div>∂L/∂w₁ = ∂L/∂a · ∂a/∂z · x₁ = <b id="nrGw1">-0.164</b></div>
  647.       <div>∂L/∂w₂ = ∂L/∂a · ∂a/∂z · x₂ = <b id="nrGw2">-0.082</b></div>
  648.       <div>∂L/∂b = ∂L/∂a · ∂a/∂z = <b id="nrGb">-0.205</b></div>
  649.     </div>
  650.     <div>损失 L = <b id="nrL">0.176</b></div>
  651.     <div class="lossbar"><div id="nrLbar" style="width:17.6%"></div></div>
  652.   </div>
  653.   <p>观察:每训练一步,链式法则的每个乘数实时变化,损失下降,权重自动趋向让 a→1 的值。</p>
  654.   <table class="sum">
  655.     <tr><th>数学工具</th><th>它在哪里出场</th></tr>
  656.     <tr><td>内积 / 矩阵乘法</td><td>计算每个神经元的输入(每层的线性变换)</td></tr>
  657.     <tr><td>SVD / 特征值</td><td>降维、LoRA 低秩近似、理解变换结构</td></tr>
  658.     <tr><td>链式法则</td><td>反向传播求梯度</td></tr>
  659.     <tr><td>梯度</td><td>告诉每个参数往哪个方向调</td></tr>
  660.     <tr><td>期望</td><td>损失是数据分布上的期望误差</td></tr>
  661.     <tr><td>交叉熵 / KL 散度</td><td>分类损失、知识蒸馏、VAE 正则</td></tr>
  662.     <tr><td>Softmax</td><td>分类输出、注意力权重、温度采样</td></tr>
  663.     <tr><td>卷积</td><td>CNN 特征提取、局部模式检测</td></tr>
  664.     <tr><td>注意力 QKV</td><td>Transformer / LLM 的核心运算</td></tr>
  665.     <tr><td>正则化 L1/L2</td><td>防止过拟合、稀疏化、weight decay</td></tr>
  666.     <tr><td>梯度下降</td><td>把上面全部串起来的优化算法</td></tr>
  667.   </table>
  668.   <div class="checklist">
  669.     <b>✅ 自检清单(能全部勾选 = 本模块达标):</b>
  670.     <ul style="margin:8px 0 0">
  671.       <li>能手算一个小矩阵乘积和一次链式求导</li>
  672.       <li>能说出贝叶斯公式,并解释"阳性≠患病"</li>
  673.       <li>能写出梯度下降更新公式并解释 η 的作用</li>
  674.       <li>能解释 Softmax 的温度参数 τ 对输出的影响</li>
  675.       <li>能写出注意力公式并解释 Q、K、V 各自的角色</li>
  676.       <li>能说出 L1 与 L2 正则化的区别</li>
  677.       <li>在上面的演示中,能让损失降到 0.01 以下</li>
  678.     </ul>
  679.   </div>
  680.   <div class="quiz" data-quiz="q-6-1">
  681.     <p class="quiz-q">📝 小测验:当 z → +∞ 时,σ(z) → ?</p>
  682.     <button class="quiz-opt">0</button>
  683.     <button class="quiz-opt">−1</button>
  684.     <button class="quiz-opt" data-ok="1">1</button>
  685.     <button class="quiz-opt">不存在</button>
  686.     <p class="quiz-expl" hidden>✅ 正确!z→+∞ 时 e<sup>−z</sup>→0,所以 σ(z) = 1/(1+e<sup>−z</sup>) → 1。</p>
  687.   </div>
  688.   <button class="complete-btn" data-lesson="l-6-1">标记完成</button>
  689. </section>

  690. <section class="lesson" id="l-6-2">
  691.   <div class="lesson-head"><span class="lesson-num">6.2</span><h2>学习路线与资源</h2></div>
  692.   <p><b>推荐节奏(本页顺序即是):</b></p>
  693.   <ul>
  694.     <li>模块 1:配合 3Blue1Brown《线性代数的本质》看,建立几何直觉;SVD 可参考 Gilbert Strang 的讲解</li>
  695.     <li>模块 2:复习 Khan Academy 导数章节,重点吃透链式法则</li>
  696.     <li>模块 3:MIT 18.05 或 Khan Academy 概率章节;KL 散度参考 Cover & Thomas《信息论》第 2 章</li>
  697.     <li>模块 4:用 Python 从零写一遍梯度下降(不用任何库);正则化部分参考 CS231n 笔记</li>
  698.     <li>模块 5:Softmax / 激活函数看 CS231n;卷积看 Stanford CS231n Lecture 7;注意力读原论文 "Attention Is All You Need"(2017)</li>
  699.     <li>模块 6:跟 fast.ai / PyTorch 教程上手真实训练</li>
  700.   </ul>
  701.   <p><b>精选资源:</b></p>
  702.   <ul>
  703.     <li><b>3Blue1Brown</b>:线性代数 / 微积分 / 神经网络系列(可视化直觉极佳)</li>
  704.     <li><b>《Mathematics for Machine Learning》</b>(Deisenroth 等):免费在线书,数学与 ML 无缝对接</li>
  705.     <li><b>Stanford CS229 Notes</b>:经典机器学习课程讲义,含完整推导</li>
  706.     <li><b>Stanford CS231n</b>:卷积网络与注意力机制的最佳入门课程</li>
  707.     <li><b>"Attention Is All You Need"</b>(Vaswani et al., 2017):Transformer 原论文,数学清晰</li>
  708.     <li><b>PyTorch Tutorial</b>:hands-on,autograd 会帮你验证反向传播</li>
  709.     <li><b>《Deep Learning》(Goodfellow 等)</b>:第 3 章 + 数学附录,进阶圣经</li>
  710.     <li><b>《Dive into Deep Learning》(d2l.ai)</b>:免费交互式教材,含代码</li>
  711.   </ul>
  712.   <p><b>动手练习建议:</b></p>
  713.   <ul>
  714.     <li>① 从零实现线性回归(含梯度下降,拟合 20 个带噪声的点)</li>
  715.     <li>② 用 PyTorch 搭一个 2 层网络解决 XOR 问题</li>
  716.     <li>③ 对同一模型调 3 个学习率,画出 loss 曲线并解释差异</li>
  717.     <li>④ 用 NumPy 手动实现一次 3×3 卷积,与 PyTorch Conv2d 对比验证</li>
  718.     <li>⑤ 用 4 个 token 手算一遍 Self-Attention(Q、K、V 各 2 维),验证 softmax 权重</li>
  719.     <li>⑥ 给线性回归分别加 L1 和 L2 正则化,观察权重变化差异</li>
  720.   </ul>
  721.   <div class="quiz" data-quiz="q-6-2">
  722.     <p class="quiz-q">📝 小测验:学完这 22 课后,下面哪个说法是正确的?</p>
  723.     <button class="quiz-opt">只要层数够深,网络一定能学会任何函数</button>
  724.     <button class="quiz-opt">数学只用来"证明"模型有效,与训练过程无关</button>
  725.     <button class="quiz-opt" data-ok="1">线性代数、微积分、概率统计和优化共同构成训练 LLM 的数学底座</button>
  726.     <button class="quiz-opt">Softmax 和梯度下降没有任何关系</button>
  727.     <p class="quiz-expl" hidden>✅ 正确!前向靠线性代数,反向靠微积分(链式法则),损失建立在概率(交叉熵/期望)之上,而优化器负责最小化它——四者缺一不可。</p>
  728.   </div>
  729.   <button class="complete-btn" data-lesson="l-6-2">标记完成</button>
  730. </section>
  731. </main>
  732. </div>

  733. <footer>
  734.   AI 数学基础 · 渐进式学习路径(扩展版)—— 从向量到注意力机制,把 AI 背后的数学串成一条线。
  735. </footer>

  736. <script>
  737. (function(){
  738.   "use strict";
  739.   const $  = s => document.querySelector(s);
  740.   const $ = s => Array.from(document.querySelectorAll(s));
  741.   const STORE_KEY = 'ai-math-progress-v1';
  742.   const allLessons = $('.complete-btn').map(b => b.dataset.lesson);

  743.   /* ---------- 进度(localStorage 持久化) ---------- */
  744.   let done = new Set();
  745.   try { done = new Set(JSON.parse(localStorage.getItem(STORE_KEY) || '[]')); } catch(e){ done = new Set(); }
  746.   const save = () => { try { localStorage.setItem(STORE_KEY, JSON.stringify([...done])); } catch(e){} };

  747.   function updateProgress(){
  748.     const n = allLessons.filter(id => done.has(id)).length;
  749.     $('#progressText').textContent = '已完成 ' + n + ' / ' + allLessons.length + ' 课';
  750.     $('#progressBar').style.width = (allLessons.length ? (100 * n / allLessons.length) : 0) + '%';
  751.   }
  752.   function markLesson(id, isDone){
  753.     if (isDone) done.add(id); else done.delete(id);
  754.     save();
  755.     const btn = $('.complete-btn[data-lesson="' + id + '"]');
  756.     if (btn){ btn.classList.toggle('done', isDone); btn.textContent = isDone ? '已完成 ✓' : '标记完成'; }
  757.     const link = $('.toc-link[href="#' + id + '"]');
  758.     if (link) link.classList.toggle('done', isDone);
  759.     updateProgress();
  760.   }
  761.   $('.complete-btn').forEach(btn => {
  762.     const id = btn.dataset.lesson;
  763.     if (done.has(id)){ btn.classList.add('done'); btn.textContent = '已完成 ✓'; }
  764.     const link = $('.toc-link[href="#' + id + '"]');
  765.     if (done.has(id) && link) link.classList.add('done');
  766.     btn.addEventListener('click', () => markLesson(id, !done.has(id)));
  767.   });
  768.   updateProgress();

  769.   /* ---------- 目录滚动高亮 ---------- */
  770.   const links = $('.toc-link');
  771.   const targets = links.map(a => document.getElementById(a.getAttribute('href').slice(1)));
  772.   function onScroll(){
  773.     const y = window.scrollY + 90;
  774.     let cur = targets[0];
  775.     targets.forEach(t => { if (t && t.offsetTop <= y) cur = t; });
  776.     links.forEach(a => a.classList.toggle('active', !!cur && a.getAttribute('href') === '#' + cur.id));
  777.   }
  778.   window.addEventListener('scroll', onScroll, { passive: true });
  779.   onScroll();

  780.   /* ---------- 小测验 ---------- */
  781.   $('.quiz').forEach(q => {
  782.     const opts = Array.from(q.querySelectorAll('.quiz-opt'));
  783.     const expl = q.querySelector('.quiz-expl');
  784.     const okBtn = opts.find(b => b.dataset.ok === '1');
  785.     opts.forEach(b => b.addEventListener('click', () => {
  786.       if (q.dataset.answered) return;
  787.       q.dataset.answered = '1';
  788.       opts.forEach(o => { o.disabled = true; if (o === okBtn) o.classList.add('correct'); });
  789.       if (b !== okBtn){
  790.         b.classList.add('wrong');
  791.         if (expl) expl.textContent = '❌ 不对,正确选项已标绿。' + expl.textContent.replace(/^✅\s*正确!/, '');
  792.       }
  793.       if (expl) expl.hidden = false;
  794.     }));
  795.   });


  796.   /* ---------- 4.2 梯度下降演示 ---------- */
  797.   (function(){
  798.     const cv = $('#gdCanvas');
  799.     if (!cv) return;
  800.     const ctx = cv.getContext('2d');
  801.     const fn0 = x => x*x,                       d0 = x => 2*x;
  802.     const fn1 = x => x*x + 0.25*(1 - Math.cos(4*x)), d1 = x => 2*x + Math.sin(4*x);
  803.     const XMIN=-3, XMAX=3, YMIN=-1, YMAX=9;
  804.     const X = x => (x - XMIN) / (XMAX - XMIN) * cv.width;
  805.     const Y = y => cv.height - (y - YMIN) / (YMAX - YMIN) * cv.height;
  806.     const clampX = v => Math.min(Math.max(v, XMIN), XMAX);
  807.     const clampY = v => Math.min(Math.max(v, YMIN), YMAX);
  808.     const fmt = v => Number.isFinite(v) ? v.toFixed(3).padStart(10) : '      ∞  ';
  809.     const playBtn = $('#gdBtn'), info = $('#gdInfo'),
  810.           etaVal = $('#gdEtaVal'), speedVal = $('#gdSpeedVal');

  811.     let eta = +$('#gdEta').value, speed = +$('#gdSpeed').value;
  812.     let fn = 0, x = 2.5, step = 0, raf = null, lastStep = 0, diverged = false;
  813.     const curF = () => fn ? fn1 : fn0;
  814.     const curD = () => fn ? d1 : d0;

  815.     function draw(){
  816.       const W = cv.width, H = cv.height, F = curF();
  817.       ctx.clearRect(0, 0, W, H);
  818.       ctx.strokeStyle = '#e3e7f0'; ctx.lineWidth = 1;
  819.       for (let gx = Math.ceil(XMIN); gx <= XMAX; gx++){ ctx.beginPath(); ctx.moveTo(X(gx), 0); ctx.lineTo(X(gx), H); ctx.stroke(); }
  820.       for (let gy = Math.ceil(YMIN); gy <= YMAX; gy++){ ctx.beginPath(); ctx.moveTo(0, Y(gy)); ctx.lineTo(W, Y(gy)); ctx.stroke(); }
  821.       ctx.strokeStyle = '#9aa3b5';
  822.       ctx.beginPath(); ctx.moveTo(0, Y(0)); ctx.lineTo(W, Y(0)); ctx.stroke();
  823.       ctx.strokeStyle = '#4353ff'; ctx.lineWidth = 2; ctx.beginPath();
  824.       for (let px = 0; px <= W; px++){
  825.         const gx = XMIN + px / W * (XMAX - XMIN);
  826.         px ? ctx.lineTo(px, Y(clampY(F(gx)))) : ctx.moveTo(px, Y(clampY(F(gx))));
  827.       }
  828.       ctx.stroke();
  829.       if (!diverged && step > 0){
  830.         ctx.strokeStyle = 'rgba(214,69,69,.75)'; ctx.lineWidth = 1.5; ctx.setLineDash([5,4]);
  831.         ctx.beginPath(); ctx.moveTo(X(clampX(x)), Y(clampY(F(x)))); ctx.lineTo(0, Y(0)); ctx.stroke(); ctx.setLineDash([]);
  832.       }
  833.       const bx = X(diverged ? (x > 0 ? XMAX : XMIN) : clampX(x));
  834.       const by = Y(clampY(diverged ? F(x > 0 ? XMAX : XMIN) : F(x)));
  835.       ctx.fillStyle = '#d64545';
  836.       ctx.beginPath(); ctx.arc(bx, by, 7, 0, Math.PI*2); ctx.fill();
  837.       ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke();
  838.       if (!diverged){
  839.         info.textContent = 'x = ' + fmt(x) + ' f(x) = ' + fmt(F(x)) + ' 步数 = ' + String(step).padStart(4, ' ');
  840.       }
  841.     }
  842.     function stepOnce(){
  843.       x -= eta * curD()(x);
  844.       step++;
  845.       if (!isFinite(x) || Math.abs(x) > 200){
  846.         diverged = true;
  847.         info.textContent = '⚠ 发散:η = ' + eta.toFixed(2) + ' 太大,x 已飞出界外 —— 调小学习率后按 ↺ 重置';
  848.       }
  849.     }
  850.     function loop(now){
  851.       if (now - lastStep >= 1000 / speed){
  852.         lastStep = now;
  853.         stepOnce();
  854.         if (diverged){
  855.           raf = null;
  856.           playBtn.classList.add('primary'); playBtn.textContent = '▶ 开始';
  857.           draw();
  858.           return;
  859.         }
  860.       }
  861.       draw();
  862.       raf = requestAnimationFrame(loop);
  863.     }
  864.     function resetGd(){
  865.       if (raf){ cancelAnimationFrame(raf); raf = null; }
  866.       diverged = false;
  867.       x = 2.5; step = 0;
  868.       playBtn.classList.add('primary'); playBtn.textContent = '▶ 开始';
  869.       draw();
  870.     }
  871.     $('#gdEta').addEventListener('input', e => {
  872.       eta = +e.target.value;
  873.       etaVal.textContent = eta.toFixed(2);
  874.       if (!raf) draw();
  875.     });
  876.     $('#gdSpeed').addEventListener('input', e => {
  877.       speed = +e.target.value;
  878.       speedVal.textContent = speed;
  879.     });
  880.     $('#gdFn0').addEventListener('click', e => { fn = 0; e.target.classList.add('on'); $('#gdFn1').classList.remove('on'); resetGd(); });
  881.     $('#gdFn1').addEventListener('click', e => { fn = 1; e.target.classList.add('on'); $('#gdFn0').classList.remove('on'); resetGd(); });
  882.     playBtn.addEventListener('click', () => {
  883.       if (raf){
  884.         cancelAnimationFrame(raf); raf = null;
  885.         playBtn.classList.add('primary'); playBtn.textContent = '▶ 开始';
  886.       } else {
  887.         if (diverged) resetGd();
  888.         playBtn.classList.remove('primary'); playBtn.textContent = '⏸ 暂停';
  889.         lastStep = performance.now();
  890.         raf = requestAnimationFrame(loop);
  891.       }
  892.     });
  893.     $('#gdReset').addEventListener('click', resetGd);
  894.     draw();
  895.   })();


  896.   /* ---------- 6.1 神经元训练演示 ---------- */
  897.   (function(){
  898.     const slW1 = $('#slW1'), slW2 = $('#slW2'), slB = $('#slB');
  899.     if (!slW1 || !slW2 || !slB) return;
  900.     const X1 = 0.8, X2 = 0.4, T = 1.0, NR_H = 0.5;
  901.     let steps = 0;
  902.     let state = { w1: 0.5, w2: -0.2, b: 0 };   // 连续状态,不受 step=0.05 量化
  903.     const sig = z => 1 / (1 + Math.exp(-z));

  904.     function render(){
  905.       const z = state.w1*X1 + state.w2*X2 + state.b;
  906.       const a = sig(z);
  907.       const dLa = 2*(a - T), daz = a*(1 - a);
  908.       const L = (a - T)*(a - T);
  909.       $('#valW1').textContent = state.w1.toFixed(2);
  910.       $('#valW2').textContent = state.w2.toFixed(2);
  911.       $('#valB').textContent  = state.b.toFixed(2);
  912.       $('#nrZ').textContent = z.toFixed(3);
  913.       $('#nrA').textContent = a.toFixed(3);
  914.       $('#nrDLa').textContent = dLa.toFixed(3);
  915.       $('#nrDaz').textContent = daz.toFixed(3);
  916.       $('#nrGw1').textContent = (dLa*daz*X1).toFixed(3);
  917.       $('#nrGw2').textContent = (dLa*daz*X2).toFixed(3);
  918.       $('#nrGb').textContent  = (dLa*daz).toFixed(3);
  919.       $('#nrL').textContent = L.toFixed(3);
  920.       $('#nrLbar').style.width = Math.min(100, L*100).toFixed(1) + '%';
  921.       $('#nrSteps').textContent = steps;
  922.     }
  923.     function showSliders(){                     // 滑块只做显示
  924.       slW1.value = state.w1;
  925.       slW2.value = state.w2;
  926.       slB.value  = state.b;
  927.     }
  928.     function train(n){
  929.       for (let i = 0; i < n; i++){
  930.         const z = state.w1*X1 + state.w2*X2 + state.b;
  931.         const a = sig(z);
  932.         const dLa = 2*(a - T), daz = a*(1 - a);
  933.         state.w1 = Math.min(3, Math.max(-3, state.w1 - NR_H*dLa*daz*X1));
  934.         state.w2 = Math.min(3, Math.max(-3, state.w2 - NR_H*dLa*daz*X2));
  935.         state.b  = Math.min(2, Math.max(-2, state.b  - NR_H*dLa*daz));
  936.         steps++;
  937.       }
  938.       showSliders();
  939.       render();
  940.     }
  941.     // 用户手动拖滑块 → 以滑块为准接管状态(这是唯一量化点,符合直觉)
  942.     slW1.addEventListener('input', () => { state.w1 = +slW1.value; render(); });
  943.     slW2.addEventListener('input', () => { state.w2 = +slW2.value; render(); });
  944.     slB.addEventListener('input',  () => { state.b  = +slB.value;  render(); });
  945.     $('#btnNr1').addEventListener('click',  () => train(1));
  946.     $('#btnNr100').addEventListener('click', () => train(100));
  947.     $('#btnNrReset').addEventListener('click', () => {
  948.       steps = 0;
  949.       state = { w1: 0.5, w2: -0.2, b: 0 };
  950.       showSliders();
  951.       render();
  952.     });
  953.     render();
  954.   })();

  955. })();
  956. </script>

  957. </body>
  958. </html>
复制代码

阿莫论坛22周年了!感谢大家的支持与爱护!!

世间万般皆为虚妄,唯有情爱执念最是折磨人心。人心本不可试探,一试便碎;真情更不能考验,一考就断!

出15入9汤圆

发表于 2026-9-25 22:52:40 | 显示全部楼层
本帖最后由 pcwhy 于 2026-9-25 22:55 编辑

这个做的确实可以,一般深度学习课程的数学要求就这些。干脆,直接部署到github上得了。我Linear algebra教学的时候也用了类似的办法给学生划重点。

出0入149汤圆

发表于 5 天前 来自手机 | 显示全部楼层
哈哈,我居然刷屏了整贴纸,顺便还水一贴回复

出15入258汤圆

 楼主| 发表于 5 天前 来自手机 | 显示全部楼层
我也水一贴,做成网站了。
http://guyuqi.top/knowledgebase.html
回帖提示: 反政府言论将被立即封锁ID 。在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2026-10-10 13:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表