<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:version="2.0"><channel><title>Danny&apos;s Blog</title><description>Danny的个人网站</description><link>https://dannyshi.pages.dev/</link><language>en</language><item><title>如何从思源学堂上下载只读的 PDF 课件</title><link>https://dannyshi.pages.dev/blog/misc/pdfdownload/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/misc/pdfdownload/</guid><description>为同学们提供了一种从思源学堂下载pdf的方法</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/misc/pdfdownload/&quot;&gt;https://dannyshi.pages.dev/blog/misc/pdfdownload/&lt;/a&gt;&lt;/blockquote&gt; &lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;笔者在进行离散数学的复习时，发现上传在&lt;a href=&quot;https://lms.xjtu.edu.cn/&quot;&gt;思源学堂&lt;/a&gt;的课件无法被直接下载，于是我顺便研究了下「如何下载网页中的 pdf 文档」这个问题，把方法记录在这里。&lt;/p&gt;
&lt;p&gt;当然这里还是得先说明，下载后的内容仅用于个人学习，请勿作他用，否则可能存在侵权嫌疑。&lt;/p&gt;
&lt;h1&gt;通过获取文件路径进行下载&lt;/h1&gt;
&lt;p&gt;这种方法适用于 HTML5 页面中内嵌 pdf 的下载，基本操作思路是通过开发者工具来找到 pdf 存取的文件路径。&lt;/p&gt;
&lt;p&gt;如果你对 H5 有一些了解，看得懂 Elements 里那些东西，自然是可以从中检索（Ctrl + F）出 .pdf 后缀的文件源，再从 Sources 中确定它的服务器源，从而推断得到它的路径。&lt;/p&gt;
&lt;p&gt;但是，如果是不懂这些的朋友，或许可以尝试更简便的另一种方法。&lt;/p&gt;
&lt;p&gt;我们都知道你所能在网页看到的东西都是存放在服务器的，当你进入网页后它会发送一个请求出去，获取到数据之后再呈现给你。&lt;/p&gt;
&lt;p&gt;那么，我们就可以从它的操作信息中找到我们需要的文件路径。页面中的网络操作信息——比如 HTTP 请求和响应、Cookie 等内容——都会记录在 Network 面板中，我们在这里做点小动作重新请求一次进行筛选就好，具体操作如下：&lt;/p&gt;
&lt;h2&gt;step 1&lt;/h2&gt;
&lt;p&gt;右键选择「检查」或是按下「 F12」 进入开发者工具。
&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.mnveshac.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;step 2&lt;/h2&gt;
&lt;p&gt;点击「 Network 」，选择筛选图标，点击「XHR」。如果此时面板无内容，按下「 Ctrl + R 」重新向服务器请求一次数据。
&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.7lkkzm0lyj.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;step 3&lt;/h2&gt;
&lt;p&gt;找到 pdf 文件，右键选择「Open in new tab」，点击下载即可。如果你刷新出来的 Network 内容较多，可以点击 Size 进行排序。一般来说，pdf 文件都相对比较大，排序后更容易找到它。
&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.73ujb10itj.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;step 4&lt;/h2&gt;
&lt;p&gt;此时我们就可以获取到 .pdf 的地址了，点击下载即可。
&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.32ijwmxofy.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;再次声明：下载后的内容仅用于个人学习，请勿作他用，否则可能存在侵权嫌疑。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate></item><item><title>Paper Reading 5</title><link>https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week5/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week5/</guid><description>04/06-04/12</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week5/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week5/&lt;/a&gt;&lt;/blockquote&gt; &lt;h1&gt;Paper 1&lt;/h1&gt;
&lt;p&gt;&amp;lt;paper-card
  title=&amp;quot;MM-ACT: Learn from Multimodal Parallel Generation to Act&amp;quot;
  description=&amp;quot;一种统一的多模态掩码生成式 VLA 框架：将文本、图像与机器人状态离散为共享 token 空间，在双向 Transformer 中进行上下文共享建模，通过全掩码动作预测与并行解码策略，实现跨模态条件下的高效连续动作生成。&amp;quot;
  href=&amp;quot;&lt;a href=&quot;https://arxiv.org/abs/2512.00975&quot;&gt;https://arxiv.org/abs/2512.00975&lt;/a&gt;&amp;quot;
  image=&amp;quot;&lt;a href=&quot;https://lnscq.github.io/picx-images-hosting/image.wj59qhicm.webp&quot;&gt;https://lnscq.github.io/picx-images-hosting/image.wj59qhicm.webp&lt;/a&gt;&amp;quot;
  badge=&amp;quot;Paper&amp;quot;
  meta=&amp;quot;CVPR · 2026&amp;quot;
  cta=&amp;quot;查看论文&amp;quot;
  accent=&amp;quot;oklch(0.72 0.18 350)&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;/paper-card&gt;&lt;/blockquote&gt;
&lt;h2&gt;MM-ACT: Learn from Multimodal Parallel Generation to Act&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.wj59qhicm.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;当前 VLA（Vision-Language-Action）模型的核心问题可以抽象为两个维度的矛盾：一方面，基于大规模预训练的 VLM 在语义理解与视觉感知上具有明显优势，但其建模目标本质上是静态 token prediction，缺乏对物理世界动态过程的显式建模；另一方面，动作生成通常依赖 imitation learning 或 diffusion-based policy，这类方法强调时序与动力学建模，但往往与 VLM 的预训练目标不一致，从而在联合优化时产生目标错配的问题 。&lt;/p&gt;
&lt;p&gt;现有方法通常沿三条路径发展：一类方法将 VLM 与 action expert 解耦，通过 latent representation 进行信息传递（如 π0），本质上仍然是“语义 → 控制”的级联结构；第二类方法通过引入视觉预测或 world model，使模型能够对未来状态进行建模，从而间接提升规划能力，但这类方法往往更偏 prediction 而非 task-oriented decision；第三类 unified VLA 方法尝试在同一模型中统一 text、image 与 action 的生成，但大多继承 autoregressive 或 hybrid decoding 机制，导致推理效率低或训练复杂度较高 。&lt;/p&gt;
&lt;p&gt;MM-ACT 的出发点在于重新定义这一问题：不是在已有架构上增加模块，而是直接在生成范式上做统一。具体而言，它将三种模态全部离散化为 token，并在同一 Transformer 中，通过 mask token prediction 的方式进行建模，从而在训练目标层面统一 text、image 与 action 的生成过程。&lt;/p&gt;
&lt;h2&gt;模型整体设计&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.7pvprdkcz.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;MM-ACT 在结构上仍然采用 Transformer，但关键变化在于 attention 机制与序列构造方式。模型使用 &lt;strong&gt;双向 attention（bidirectional attention）&lt;/strong&gt;，允许任意 token 之间进行信息交互，而不是像 autoregressive 模型那样采用因果掩码。&lt;/p&gt;
&lt;p&gt;在输入层面，模型将文本、图像以及机器人状态统一编码为离散 token，并拼接为一个共享序列。不同模态采用不同 tokenizer：文本使用 LLaDA tokenizer，图像使用 Show-o 的量化器（8192 token codebook），机器人状态与动作使用 bin tokenizer（2048 token） 。这种设计的关键在于，所有模态在进入 Transformer 后处于同一 token 空间，从而使 cross-modal attention 成为自然的交互机制。&lt;/p&gt;
&lt;p&gt;模型在输入序列前引入一个 modal token，用于指定当前的生成任务；同时在序列后附加一个固定长度的 &lt;code&gt;&amp;lt;mask&amp;gt;&lt;/code&gt; block，作为目标生成区域。在推理时，模型根据 modal token 决定生成 text、image 或 action，对应不同的任务类型（task planning、future prediction、action generation）。&lt;/p&gt;
&lt;h2&gt;上下文共享的多模态学习&lt;/h2&gt;
&lt;p&gt;MM-ACT 的一个核心设计是 Context-Shared Multimodal Learning，其关键在于：三种模态的生成任务共享完全相同的输入上下文，仅通过 modal token 区分任务类型。&lt;/p&gt;
&lt;p&gt;形式上可以表示为：
$$
C_{\text{modal}} = \langle \text{modal} \rangle + \text{sharedinput}
$$&lt;/p&gt;
&lt;p&gt;其中 sharedinput 包含多视角图像、语言指令、文本描述以及机器人状态等信息。对于不同任务，仅在 context 后附加不同类型的 mask block，例如 text block（用于任务规划）、image block（用于未来状态预测）以及 action block（用于动作生成）。&lt;/p&gt;
&lt;p&gt;这一设计的本质含义是：模型不是分别学习三个独立任务，而是在同一条件分布下学习三个 conditional generation problem。这种共享上下文的机制使得不同模态之间可以通过 attention 自动建立关联，从而实现跨模态知识迁移。&lt;/p&gt;
&lt;h2&gt;多模态统一目标&lt;/h2&gt;
&lt;p&gt;在训练目标上，MM-ACT 将三种模态统一为 mask token prediction 问题。具体而言，对于每一种模态的 token 序列 $x_0$，通过随机 mask 操作生成 $x_t$，其中每个位置以概率 $p_{mask}$ 被替换为 &lt;code&gt;&amp;lt;mask&amp;gt;&lt;/code&gt; token。这个过程可以理解为离散 diffusion 中的 forward process：&lt;/p&gt;
&lt;p&gt;$$
q_t(x_t^i | x_0^i) =
(1 - f(t)) \cdot \mathbf{1}[x_t^i = x_0^i] +
f(t) \cdot \mathbf{1}[x_t^i = \text{mask}]
$$&lt;/p&gt;
&lt;p&gt;不同模态采用不同的 mask schedule：文本使用线性 schedule，而图像与动作使用 cosine schedule，以对齐连续 diffusion 的噪声分布 。&lt;/p&gt;
&lt;p&gt;模型的目标是在给定 $C_{\text{modal}}$ 与 $x_t$ 的条件下，同时预测所有被 mask 的 token：&lt;/p&gt;
&lt;p&gt;$$
\mathcal{L}(\theta) = - \mathbb{E}&lt;em&gt;{t, x_0, x_t} \left[
\sum&lt;/em&gt;{\text{modal}} \frac{\lambda_{\text{modal}}}{t}
\sum_{i} \mathbf{1}(x_t^i = M)
\log p_\theta(x_0^i | C_{\text{modal}}, x_t)
\right]
$$&lt;/p&gt;
&lt;p&gt;其中仅对 mask token 计算交叉熵损失。&lt;/p&gt;
&lt;p&gt;一个关键特例是 action 模态：在训练时固定 (t=1)，即所有 action token 都被 mask，这意味着模型需要在单次 forward 中恢复完整的 action 序列。这一设计直接决定了后续的并行解码策略。&lt;/p&gt;
&lt;h2&gt;两阶段训练策略&lt;/h2&gt;
&lt;p&gt;模型采用两阶段训练流程。第一阶段仅训练 text 与 image 模态，将 action loss 权重设为 0，使模型先学习语义理解与视觉预测能力；当这两种模态收敛后，进入第二阶段，重点训练 action 生成，同时将 text 与 image 的权重降低至较小值（约 0.05–0.1）以维持其能力 。&lt;/p&gt;
&lt;p&gt;这一策略的作用可以理解为先构建一个“语义 + 动态”的表示空间，再在该空间上学习控制策略，从而避免 action 学习过程过早干扰 representation learning。&lt;/p&gt;
&lt;h2&gt;并行解码策略&lt;/h2&gt;
&lt;p&gt;在推理阶段，MM-ACT 采用 block-level parallel decoding，而不是传统的 token-by-token autoregressive 生成。具体策略在不同模态之间存在差异。&lt;/p&gt;
&lt;p&gt;对于 text 与 image，模型采用 re-mask 迭代解码策略。初始时输入部分 mask token，模型进行前向传播得到 logits，然后根据置信度选择一部分 token 进行更新，同时对低置信 token 重新 mask，并重复这一过程若干步。这一过程本质上等价于离散 diffusion 的逐步去噪。&lt;/p&gt;
&lt;p&gt;对于 action，模型采用 one-step parallel decoding，即在输入全 mask 的情况下，通过一次 forward 直接生成完整的 action token 序列。这种设计显著降低了推理延迟，使模型能够满足实时控制的需求。&lt;/p&gt;
&lt;p&gt;实验表明，当 action chunk 较小时（如 8），re-mask 策略并不会带来性能提升，反而增加计算开销；而在 chunk 较大时虽然性能有所提高，但推理时间显著增加。因此最终选择 one-step decoding，以实现约 40Hz 的控制频率 。&lt;/p&gt;
&lt;h2&gt;实验结果与分析&lt;/h2&gt;
&lt;p&gt;在 LIBERO 基准测试中，MM-ACT 达到 96.3% 的成功率，超过现有方法；在 RoboTwin2.0 中达到 52.38%，并在真实 Franka 机器人任务中取得 72.0% 的成功率 。&lt;/p&gt;
&lt;p&gt;进一步分析表明，多模态联合训练对 action 生成具有显著促进作用。仅使用 action 训练作为 baseline，引入 text 可提升约 3.37%，引入 image 可提升约 5.62%，同时引入两者则提升约 9.25%。这一结果表明，视觉预测信号对控制的帮助大于语言规划，但两者结合能够提供互补信息。&lt;/p&gt;
&lt;p&gt;在模态质量方面，图像生成在联合训练后持续提升，而文本生成在第二阶段出现性能下降。这一现象与训练过程有关：文本任务较容易收敛并发生过拟合，而图像任务收敛较慢，能够持续从联合训练中获益 。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;MM-ACT 的核心贡献并不在于引入新的模块，而在于将 VLA 问题重新表述为一个统一的多模态离散生成问题。通过将 text、image 与 action 映射到同一 token 空间，并采用一致的 mask prediction 目标，模型避免了 autoregressive 与 diffusion 之间的目标不一致问题。在此基础上，通过共享上下文的多模态训练方式，使不同模态之间形成协同，从而显著提升 action 生成能力。在推理层面，通过区分 one-step 与 re-mask 两种解码策略，实现了效率与生成质量之间的结构性权衡。&lt;/p&gt;
&lt;h1&gt;Paper 2&lt;/h1&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sat, 11 Apr 2026 00:00:00 GMT</pubDate></item><item><title>pi系列论文阅读——pi_0</title><link>https://dannyshi.pages.dev/blog/pi/pi_0/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/pi/pi_0/</guid><description>pi系列论文阅读</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/pi/pi_0/&quot;&gt;https://dannyshi.pages.dev/blog/pi/pi_0/&lt;/a&gt;&lt;/blockquote&gt; &lt;h1&gt;《π0: A Vision-Language-Action Flow Model for General Robot Control》 Paper Reading&lt;/h1&gt;
&lt;h2&gt;基本信息&lt;/h2&gt;
&lt;p&gt;&amp;lt;paper-card
  title=&amp;quot;π0: A Vision-Language-Action Flow Model for General Robot Control&amp;quot;
  description=&amp;quot;Physical Intelligence 提出的通用机器人基础策略：以预训练 VLM 为骨干，结合 flow matching 动作生成，用统一模型跨机器人本体完成高频连续控制。&amp;quot;
  href=&amp;quot;&lt;a href=&quot;https://arxiv.org/abs/2410.24164&quot;&gt;https://arxiv.org/abs/2410.24164&lt;/a&gt;&amp;quot;
  image=&amp;quot;&lt;a href=&quot;https://lnscq.github.io/picx-images-hosting/image.7lkkhbazd2.webp&quot;&gt;https://lnscq.github.io/picx-images-hosting/image.7lkkhbazd2.webp&lt;/a&gt;&amp;quot;
  badge=&amp;quot;Paper&amp;quot;
  meta=&amp;quot;Physical Intelligence · 2024&amp;quot;
  cta=&amp;quot;查看论文&amp;quot;
  accent=&amp;quot;oklch(0.72 0.18 350)&amp;quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;/paper-card&gt;&lt;/blockquote&gt;
&lt;p&gt;$\pi_0$ 系列作为以基于流的VLA模型，已经在领域内成为经典工作。作为刚刚入门的研究者，深入且仔细地阅读相关论文是必要的。因此，本文作为面对刚刚入门Embodied AI的初学者，对其中大多数的专有名词进行了深入浅出的解释。&lt;/p&gt;
&lt;p&gt;这篇工作由Physical Intelligence团队提出，他们解决的问题是：能否构建一种真正具有base model意味的机器人策略，使得其可以像LLM或VLM那样。首先构建一个通过大范围数据进行pre-train的base model，再通过post-train获得面向具体任务的高质量执行能力。论文提出的 $\pi_0$，正是在这个目标下设计的一种 Vision-Language-Action（VLA） 模型：它以预训练视觉语言模型为骨干，把机器人状态与动作接入同一系统，并通过 flow matching 生成连续动作 chunk，从而面向高频、精细、长时程的真实机器人控制。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.7lkkhbazd2.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;研究背景&lt;/h2&gt;
&lt;p&gt;近年来，机器人学习正在明显地受到大模型范式的影响。传统机器人策略大多依赖单任务、单平台、特定环境的数据与训练流程，泛化能力有限；而大语言模型与视觉语言模型则展示了一个相反的方向：通过大规模、多来源、多任务预训练，模型可以在广泛任务上形成统一表征与迁移能力。 论文的出发点正是：机器人领域是否也能复制这种范式，把大量不同机器人、不同任务、不同环境中的数据统一起来，训练出一个广义的机器人基础策略。作者认为，这种路线有机会同时缓解机器人学习中最核心的三类困难：数据稀缺、泛化不足、鲁棒性不足。&lt;/p&gt;
&lt;p&gt;然而，机器人不能简单照搬 LLM 的做法。原因在于机器人控制比文本生成多了一个根本难点：动作不是离散符号，而是连续的、实时的、物理约束下的执行信号。 一个语言模型可以逐 token 生成句子，但机器人如果也用粗粒度离散 token 的方式建模动作，就会在高频控制、精细 manipulation、长时程动作连贯性上遭遇瓶颈。因此，这篇论文提出 $\pi_0$，回答了：如何在保留 VLM 高层语义能力的同时，如何为机器人动作设计一种更适合连续控制的生成机制。&lt;/p&gt;
&lt;h2&gt;关键概念解释&lt;/h2&gt;
&lt;h3&gt;VLA是什么？&lt;/h3&gt;
&lt;p&gt;VLA 即 Vision-Language-Action model。它可以视为 VLM 在机器人控制场景下的自然扩展：输入不再只是图像和语言，输出也不再只是文字，而是机器人动作。π0 的基本结构就是把多路图像、语言指令和本体状态联合编码，然后输出未来的一段动作序列。&lt;/p&gt;
&lt;h3&gt;Cross-embodiment 是什么？&lt;/h3&gt;
&lt;p&gt;论文中的 cross-embodiment training，指的是把不同机器人本体的数据统一放进同一个模型中训练。这里的 embodiment 可以理解为“身体形式”或“机器人构型”。不同机器人有不同的相机配置、关节维度、底盘形式、双臂或单臂结构。$\pi_0$ 在 7 种不同机器人配置和 68 类任务上进行统一训练，包括单臂、双臂、移动双臂等平台。作者的目标不是训练 7 个独立策略，而是训练一个能在多个 embodiment 上共享知识与能力的统一模型。&lt;/p&gt;
&lt;h3&gt;Action chunking 是什么？&lt;/h3&gt;
&lt;p&gt;论文中的动作并不是“每一步预测一个动作”，而是一次性预测未来一小段动作序列。形式化地说，模型输出的是一个动作 chunk&lt;/p&gt;
&lt;p&gt;$$
A_t = [a_t,a_{t+1},...,a_{t+H-1}]
$$&lt;/p&gt;
&lt;p&gt;其中论文中采用 $H = 50$。这意味着模型一次生成未来 50 步动作。这样做的意义有两点：其一，动作会更加连贯，不会每个时刻都重新做全局决策；其二，大模型推理的频率要求下降，更适合高频精细控制。&lt;/p&gt;
&lt;h3&gt;Flow matching 是什么？&lt;/h3&gt;
&lt;p&gt;这是整篇论文最关键的技术点之一。它本质上是一种连续生成方法，与 diffusion 有亲缘关系。直观地说，模型不是直接输出最终动作，而是从噪声出发，逐步把噪声“推”向正确动作分布。 在训练阶段，真实动作会被加噪，模型学习一个向量场 $v_\theta$ 告诉系统如何把带噪动作逐步变回目标动作；在推理阶段，则从高斯噪声初始化，通过若干步积分逐渐生成动作 chunk。论文采用了前向欧拉积分，并在实验中使用 10 步积分。&lt;/p&gt;
&lt;h2&gt;模型结构&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.2yyxgmv7qq.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;总体架构&lt;/h3&gt;
&lt;p&gt;$\pi_0$ 的主体仍然是一个 transformer 式的多模态骨干。图像由图像编码器提取特征，再映射到与语言相同的 embedding 空间；语言作为标准的离散 token 输入； 机器人的本体状态 $q_t$ 也被线性映射到序列中。 与经典的 OpenVLA-like 之类工作不同的是，$\pi_0$ 并不是简单的将动作空间离散化为 token 后用语言模型的自回归式生成。而是引入一个专门 action expert，用来处理机器人状态和带噪动作，并通过 flow matching 生成连续动作分布。&lt;/p&gt;
&lt;h3&gt;Action expert&lt;/h3&gt;
&lt;p&gt;论文的整体采用了类似“大脑小脑协同的双专家结构”，图像和语言 token 由较大的 VLM backbone 处理，而机器人特有的输入输出，即本体状态 $q_t$ 与离散动作 chunk $A_t$ ，由单独的action expert 处理。&lt;/p&gt;
&lt;h3&gt;输入输出形式&lt;/h3&gt;
&lt;p&gt;模型的输入观察可以写成&lt;/p&gt;
&lt;p&gt;$$
o_t = [I_t^1, ..., I_t^n, \ell_t, q_t]
$$&lt;/p&gt;
&lt;p&gt;其中包括多路 RGB 图像、语言指令以及本体状态；输出是未来动作 chunk&lt;/p&gt;
&lt;p&gt;$$
A_t = [a_t, a_{t+1}, ..., a_{t+H-1}]
$$&lt;/p&gt;
&lt;h2&gt;一些问题&lt;/h2&gt;
&lt;p&gt;在阅读完这些后，一个自然的问题出现了。VLM backbone 是如何把监督信息传递给 action expert 进行动作输出的？&lt;/p&gt;
&lt;h3&gt;原始的 Transformer&lt;/h3&gt;
&lt;p&gt;首先，我们从最原始的 transformer 架构开始分析。&lt;/p&gt;
&lt;p&gt;Transformer 最核心的操作是：
&lt;strong&gt;序列里的每个 token，都去读取其他 token 对自己有用的信息。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;假设你有一串 token：
$$
x_1,x_2,...,x_n
$$
每个 token 都会被映射成三个向量：
$$
q_i = W_Qx_i,\quad k_i = W_Kx_i,\quad v_i = W_Vx_i 
$$
读者可以朴素的理解为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Query $q_i$：我现在想找什么信息&lt;/li&gt;
&lt;li&gt;Key $k_j$：我这里有什么信息标签&lt;/li&gt;
&lt;li&gt;Value $v_j$：真正携带的信息
然后第 $i$ 个 token 会拿自己的 query 去和所有的 token 的 key 做相似度计算：
$$
\alpha_{ij} = \text{softmax} \left( \frac{q_i k_j^\top}{\sqrt{d}} \right)
$$
再把所有的 token 的 value 按这个权重加权求和：
$$
z_i = \sum_j \alpha_{ij} v_j
$$
于是 $z_i$ 就是“第 $i$ 个 token 从整段上下文里读取到的信息”&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;回到 $\pi_0$&lt;/h3&gt;
&lt;p&gt;有了原始 Transformer 的直觉之后，我们就可以重新看 $\pi_0$ 里最关键的问题：VLM backbone 到底是如何把图像、语言和当前状态中的信息，传递给 action expert 来生成动作的？&lt;/p&gt;
&lt;p&gt;要回答这个问题，首先需要纠正一个很常见的误解。初学者在第一次接触这类模型时，会下意识地把它想成“前面一个 VLM 编码器先把图像和文字压缩成一个全局特征向量，后面一个动作模块再拿着这个向量去输出动作”。但 $pi_0$ 并不是这样工作的。实际的方法是：先把不同模态都变成统一 token 空间中的序列对象，再让这些 token 通过 self-attention 在同一个 Transformer 中进行信息交互。换句话说，信息并不是以“一个摘要向量”的形式从 backbone 单向传给 action expert，而是以前缀上下文的形式，被动作 token 通过 attention 动态读取出来。 &lt;/p&gt;
&lt;p&gt;从输入形式上看，模型的 observation 为
$$
o_t = [I_t^1, ..., I_t^n, \ell_t, q_t],
$$
其中 $I_t^1, ..., I_t^n$ 是多路图像，$\ell_t$ 是语言命令，$q_t$ 是机器人本体状态。图像会先经过 image encoders，本体状态 $q_t$ 也会经过相应编码器与线性投影，最终都被映射到与语言 token 相同的 embedding space 中。也就是说，在真正进入 Transformer 之后，模型面对的已经不再是“图片”“文本”“状态”这几种彼此割裂的输入，而是一段统一的多模态 token 序列。&lt;/p&gt;
&lt;p&gt;此时，$\pi_0$ 中的 VLM backbone 所做的事情，就可以用最原始的 Transformer 语言来描述：图像 token、语言 token 与状态 token 在多层 self-attention 中彼此读取信息，于是每一个 token 都不再只是“自己原来的那点含义”，而是逐渐变成了一个&lt;strong&gt;带有上下文条件的表示&lt;/strong&gt;。例如，某个视觉 token 在最开始可能只对应“画面中的一块布料边缘”，但在经过与语言命令“fold the shirt”以及本体状态 $q_t$ 的多轮 attention 交互之后，它会逐渐变成“当前任务下需要被关注的衣物局部，并且与当前机械臂姿态存在控制相关性”的一种条件表示。这种从“原始输入”到“上下文化表示”的变化，本质上就是 VLM backbone 在做的事情。&lt;/p&gt;
&lt;p&gt;接下来，action expert 才真正进入问题中心。论文把 $\pi_0$ 描述为一个&lt;strong&gt;single transformer with two sets of weights&lt;/strong&gt;，也就是说，它在整体上仍然是一个统一的 Transformer，但内部存在两套不同的专家权重。图像与语言 prompt $[I_t^1, ..., I_t^n, \ell_t]$ 被路由到较大的 VLM backbone，这部分来自 PaliGemma 的预训练权重；而那些在原始 VLM 预训练中没有出现过的机器人特有输入，也就是 $[q_t, A_t^\tau]$，则被路由到单独的 action expert。更关键的是：这两个 expert 之间并不是彼此完全独立的，它们只通过 Transformer 的 self-attention 层进行交互。&lt;/p&gt;
&lt;p&gt;因此，从机制上讲，VLM backbone 向 action expert 传递信息的方式可以被理解为：前缀中的图像、语言和状态 token 先被编码成一段可被访问的上下文记忆，而后缀中的动作 token 再拿着自己的 query 去读取这段前缀记忆中的 key 和 value。这也是为什么在推理时，论文专门提到可以缓存 prefix $o_t$ 对应的 attention keys and values，而在每一次 flow matching integration step 中，只需要重算 action token 所对应的后缀部分。换句话说，真正被“传递”给 action expert 的，并不是某个单独 pooled feature，而是整个 observation prefix 的 contextualized KV memory。&lt;/p&gt;
&lt;p&gt;理解这一点之后，我们还需要继续追问：action expert 在读取了这些跨模态条件信息之后，究竟输出的是什么？这里就进入了 $\pi_0$ 与 OpenVLA-like 模型最本质的区别。论文并没有让 action expert 像语言模型那样“自回归地预测下一个离散动作 token”，而是让它去建模一个未来动作 chunk 的连续条件分布。具体而言，论文定义
$$
A_t = [a_t, a_{t+1}, ..., a_{t+H-1}],
$$
其中 $H=50$，表示未来的一整段动作序列。训练时，真实动作 chunk $A_t$ 不会被直接送入模型，而是先加上噪声，构造出
$$
A_t^\tau = \tau A_t + (1-\tau)\epsilon,\quad \epsilon \sim \mathcal N(0, I).
$$
然后，模型的任务不是“直接回归 $A_t$”或者“输出下一个动作 token”，而是输出一个向量场
$$
v_\theta(A_t^\tau, o_t),
$$
它表示：在当前 observation 条件下，这个 noisy action chunk 应该往哪个方向被修正。&lt;/p&gt;
&lt;p&gt;当前的 $A_t^\tau$ 只是一个带噪的动作草稿，它并不是真正要执行的动作；action expert 在看完图像、语言和当前状态之后，会告诉你：“在这个场景下，这段动作草稿应该往哪个方向调整，才能逐渐逼近合理的未来轨迹。” 于是，训练过程学到的其实不是一个静态动作，而是一个&lt;strong&gt;去噪向量场&lt;/strong&gt;；推理过程也不是一步生成动作，而是从纯噪声 $A_t^0 \sim \mathcal N(0,I)$ 出发，用 Euler integration 反复迭代：
$$
A_t^{\tau+\delta} = A_t^\tau + \delta v_\theta(A_t^\tau, o_t).
$$
论文中使用了 10 步积分，最终才得到真正执行的动作 chunk。&lt;/p&gt;
&lt;p&gt;这时还有一个非常值得注意的细节：单个 action chunk 内部的动作并不是 causal 的，而是彼此双向可见的。论文中说明，$\pi_0$ 使用的是一种 blockwise causal attention mask：$[I_t^1, ..., I_t^n, \ell_t]$、$[q_t]$、$[a_t^\tau, ..., a_{t+H-1}^\tau]$ 这三个块之间不能看未来块，但块内是 full bidirectional attention，而最后的 noisy action block 可以看到完整输入前缀。这个设计意味着，模型不是把动作 chunk 中的 50 个未来动作当成 50 个彼此隔离、逐个预测的小 token，而是把它们当作一个&lt;strong&gt;整体的连续轨迹片段&lt;/strong&gt;来联合修正。对于机器人控制来说，这一点非常自然，因为未来动作往往不是“第 $t+1$ 步决定完了再想第 $t+2$ 步”，而是应该作为一小段协调的轨迹被整体建模。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate></item><item><title>Robocup视觉赛队员教学文档</title><link>https://dannyshi.pages.dev/blog/robocup/robocup%E6%95%99%E5%AD%A6%E6%96%87%E6%A1%A3/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/robocup/robocup%E6%95%99%E5%AD%A6%E6%96%87%E6%A1%A3/</guid><description>关于使用oriange Pi的教程和一些常用开发命令</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/robocup/robocup%E6%95%99%E5%AD%A6%E6%96%87%E6%A1%A3/&quot;&gt;https://dannyshi.pages.dev/blog/robocup/robocup%E6%95%99%E5%AD%A6%E6%96%87%E6%A1%A3/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;
import Warning from &amp;quot;@/components/mdx/Warning.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这是一篇偏实操导向的入门文档，适合第一次接触 OrangePi 和 RoboCup 视觉赛环境的同学。建议按“联网 -&gt; 查 IP -&gt; SSH -&gt; Linux / Conda 基础”的顺序操作。
&lt;/Info&gt;

&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;RoboCup 3D识别运行在嵌入式计算平台上，而这些平台几乎全部使用 Linux 系统。Linux 的优势在于它提供了稳定的服务器环境、成熟的开发工具链以及完整的网络能力，使得多机器人系统可以在同一套软件框架下运行。&lt;/p&gt;
&lt;p&gt;在我们的 RoboCup3D 项目中，开发板实际上就是一台小型服务器。所有视觉算法、机器人决策程序、深度学习模型推理程序都会运行在这个系统中。因此，成员需要具备基本的 Linux 操作能力，包括远程连接、文件管理、程序编译和调试。&lt;/p&gt;
&lt;p&gt;Linux 与 Windows 的最大区别在于，Linux 更强调命令行操作和远程管理。你并不需要在开发板上接显示器和键盘，而是可以通过自己的电脑远程控制开发板。这也是服务器开发的标准模式。&lt;/p&gt;
&lt;h1&gt;OrangePi&lt;/h1&gt;
&lt;h2&gt;开始之前检查硬件&lt;/h2&gt;
&lt;p&gt;在使用之前确保板子已经正常启动。要确认以下几件事。&lt;/p&gt;
&lt;p&gt;香橙派已经正确接上电源。注意官方手册明确说明，板子上虽然有三个 Type-C 接口，但只有靠近 PWM 风扇接口的那个是 PD 电源口，另外两个不能给开发板供电，接错后会表现为板子不开机或异常启动。&lt;/p&gt;
&lt;h2&gt;连接Wifi&lt;/h2&gt;
&lt;p&gt;在命令行中输入nmtui命令打开wifi连接的界面。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;(base) HwHiAiUser@orangepiaipro-20t:~$ sudo nmtui
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入nmtui命令打开的界面如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/wifi1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;选择&lt;code&gt;Activate a connect&lt;/code&gt;后回车，然后就能看到所有搜索到的WIFI热点&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/wifi2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;选择想要连接的WIFI热点后再使用Tab键将光标定位到&lt;code&gt;Activate&lt;/code&gt;后回车&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/wifi3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后会弹出输入密码的对话框，在Password内输入对应的密码然后回车就会开始连接WIFI&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/wifi4.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;WIFI连接成功后会在已连接的WIFI名称前显示一个“*”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/wifi5.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;使用ping命令可以测试wifi网络的连通性，ping命令可以通过Ctrl+C快捷键
来中断运行&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;(base) HwHiAiUser@orangepiaipro-20t:~$ ping www.orangepi.org -I wlan0
PING www.orangepi.org (123.57.147.237) from 10.31.2.93 wlan0: 56(84) bytes of data.
64 bytes from 123.57.147.237 (123.57.147.237): icmp_seq=1 ttl=53 time=47.1 ms
64 bytes from 123.57.147.237 (123.57.147.237): icmp_seq=2 ttl=53 time=44.3 ms
64 bytes from 123.57.147.237 (123.57.147.237): icmp_seq=3 ttl=53 time=45.0 ms
64 bytes from 123.57.147.237 (123.57.147.237): icmp_seq=4 ttl=53 time=71.0 ms
^C--- www.orangepi.org ping statistics--
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 44.377/51.902/71.082/11.119 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查询ip地址&lt;/h2&gt;
&lt;p&gt;在终端输入如下命令，可以查询当前wifi的ip地址，这条命令的作用是查看当前这台机器所有网络接口的信息。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ip a s wlan 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行结果如下，屏幕会出来很多内容，不需要全部看懂，只需要盯住含有 inet 的那一行。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;(base) HwHiAiUser@orangepiaipro-20t:~$ ip a s wlan0
4: wlan0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq state UP
group default qlen 1000
  link/ether 54:f2:9f:7b:ba:36 brd ff:ff:ff:ff:ff:ff
  inet 10.31.2.93/16 brd 10.31.255.255 scope global dynamic noprefixroute wlan0
    valid_lft 43003sec preferred_lft 43003sec
  inet6 fe80::5297:7036:a33c:bb93/64 scope link noprefixroute
    valid_lft forever preferred_lft forever
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真正重要的是&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;10.31.2.93
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是香橙派当前在局域网中的 IPv4 地址。后面的 &lt;code&gt;/16&lt;/code&gt; 不是地址本体，SSH 的时候不要把 &lt;code&gt;/16&lt;/code&gt; 一起带上。除了 &lt;code&gt;ip a&lt;/code&gt;，也可以在图形界面里看地址&lt;/p&gt;
&lt;p&gt;在 Ubuntu 桌面右上角通常有网络图标。点击后进入网络设置，在有线网络或无线网络的详细信息里，通常能看到 IPv4 地址。这个地址和 &lt;code&gt;ip a&lt;/code&gt; 查到的本质上是同一个东西。&lt;/p&gt;
&lt;h1&gt;安装VSCode&lt;/h1&gt;
&lt;p&gt;通过 Ubuntu 自带的火狐浏览器找到熟悉的 &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt; 的官网，并且进行安装。&lt;/p&gt;
&lt;p&gt;选择&lt;code&gt;.deb&lt;/code&gt; 进行下载，下载完毕之后进入下载文件夹，应该可以看到下载的 deb 包，右键在终端中打开，输入：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo dpkg -i code_your_version.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 &lt;code&gt;code_your_version.deb&lt;/code&gt; 为你的 deb 包的名字，在命令行中可以使用 TAB 进行自动补全，这样你就只需要输入一个 code，之后进行自动补全即可。&lt;/p&gt;
&lt;p&gt;输入密码，其中密码的输入是不可见的，输入之后终端没有反应并非你没有输入，输入之后按下回车即可。&lt;/p&gt;
&lt;p&gt;稍等片刻，等命令行又一次可以输入的时候，在命令行中输入 code，回车，进入 VSCode。&lt;/p&gt;
&lt;h1&gt;SSH&lt;/h1&gt;
&lt;Warning&gt;
  文中提到的默认密码仅适合首次接入或教学场景。实际队伍协作时，建议尽快修改默认密码，并避免把账号口令长期写在公开文档里。
&lt;/Warning&gt;

&lt;p&gt;在这里简短的介绍 SSH 语法，一般来说 SSH 安装在每一个系统中，无需额外的安装，在这里推荐使用 VSCode 的 SSH 插件&lt;/p&gt;
&lt;p&gt;通过在 VSCode 的拓展栏进行搜索，可以很轻易地找到 VSCode 的 SSH 插件：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/ssh1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;启用插件之后，点击左下角的打开远程窗口，选择连接到主机即可：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/ssh2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;输入（下面是示例命令，不要直接照抄）&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh username@192.168.1.XXX
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入香橙派账号默认密码&lt;code&gt;Mind@123&lt;/code&gt;。连接成功后打开远程终端，执行并检查是否连接成功&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意，输入密码的时候，屏幕上是不会显示输入的密码的具体内容的，请不要
以为是有什么故障，输入完后直接回车即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;成功登录系统后的显示如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dannyshi.pages.dev/orange.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;连接成功后建议执行以下命令，确认系统正常。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pwd
whoami
hostname
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pwd&lt;/code&gt;:查看当前路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whoami&lt;/code&gt;:查看当前用户&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hostname&lt;/code&gt;:查看主机名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果这些命令能正常运行，恭喜你，说明 SSH 连接已经成功。&lt;/p&gt;
&lt;h1&gt;Linux&lt;/h1&gt;
&lt;p&gt;使用 SSH 后，我们会进入正式的 Linux 系统中，同时，由于使用 SSH，此时的 Linux 并没有提供图形化界面（这也是 Linux 最原始的形态），因此在本章节中，我们会首先讲解一些基础的 Linux 指令，以便读者可以进行接下来的操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ls&lt;/code&gt;：可以展示当前目录下的文件内容，其中显示隐藏内容需要使用 &lt;code&gt;ls -a&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd&lt;/code&gt;：用法为 &lt;code&gt;cd folder&lt;/code&gt;，可以前往指定的文件夹中，需要注明的是，.. 为上级目录，如想要前往上级，使用 &lt;code&gt;cd ..&lt;/code&gt;，上级的上级，以此类推 &lt;code&gt;cd ../..&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;文档的编辑操作需要使用 vim，这一技巧具备一定的难度，读者请勿尝试指令 &lt;code&gt;vim filename&lt;/code&gt;，若无法退出，请狂点 &lt;code&gt;esc&lt;/code&gt; 之后依次按下 :, &lt;code&gt;w, q, !, Enter&lt;/code&gt; 以保存并退出，若不希望保存，无需按下 &lt;code&gt;w&lt;/code&gt;。&lt;/p&gt;
&lt;h1&gt;Anaconda&lt;/h1&gt;
&lt;p&gt;由于香橙派已经内置了Anaconda环境，因此读者无需自行安装。在这章，我们会讲解一些常用的&lt;code&gt;Conda&lt;/code&gt;命令和包管理技巧。&lt;/p&gt;
&lt;h2&gt;查看已有环境&lt;/h2&gt;
&lt;p&gt;首先可以查看当前系统中已有的 conda 环境。&lt;/p&gt;
&lt;p&gt;在终端输入：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda env list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda info --envs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行结果类似&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# conda environments:
#
base                  *  /home/root/anaconda3
robocup                  /home/root/anaconda3/envs/robocup
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;激活环境&lt;/h2&gt;
&lt;p&gt;如果需要进入某个环境，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda activate 环境名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda activate robocup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入环境后，终端前面通常会显示环境名称，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;(robocup) root@orangepiaipro-20t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这说明当前已经进入 &lt;code&gt;robocup&lt;/code&gt; 环境。&lt;/p&gt;
&lt;p&gt;如果想返回默认环境：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda activate base
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda deactivate
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建新的环境&lt;/h2&gt;
&lt;p&gt;如果需要为某个项目创建独立环境，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda create -n 环境名 python=版本
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda create -n vision python=3.10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建完成后可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda activate vision
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入该环境。&lt;/p&gt;
&lt;p&gt;使用独立环境的好处是：不同项目可以使用不同版本的 Python 并且不同项目之间不会产生依赖冲突，此外，将环境隔离会让环境更容易管理。&lt;/p&gt;
&lt;h2&gt;安装 Python 包&lt;/h2&gt;
&lt;p&gt;在 conda 环境中安装 Python 包通常有两种方式。&lt;/p&gt;
&lt;p&gt;第一种：使用 conda 安装&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda install numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二种：使用 pip 安装&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一般来说：常见科学计算库推荐使用 &lt;code&gt;conda install&lt;/code&gt;，但是一些 Python 库只能通过 &lt;code&gt;pip install&lt;/code&gt; 安装&lt;/p&gt;
&lt;h2&gt;查看已安装的包&lt;/h2&gt;
&lt;p&gt;查看当前环境已经安装的包：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会列出所有 Python 库以及对应版本。&lt;/p&gt;
&lt;h2&gt;更新包&lt;/h2&gt;
&lt;p&gt;更新某个 Python 包：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda update 包名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda update numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;导出环境&lt;/h2&gt;
&lt;p&gt;有时需要把当前环境分享给其他队员，可以导出环境配置。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda env export &amp;gt; environment.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成的 &lt;code&gt;environment.yml&lt;/code&gt; 文件记录了当前环境的所有依赖。&lt;/p&gt;
&lt;p&gt;其他人可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;conda env create -f environment.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;快速创建完全相同的环境。&lt;/p&gt;
&lt;h1&gt;Git&lt;/h1&gt;
&lt;p&gt;在一个大型开发项目中，代码通常需要多人协作开发，因此需要使用 &lt;strong&gt;Git&lt;/strong&gt; 进行代码版本管理。Git 可以帮助我们记录代码历史、协作开发以及避免多人修改同一份代码时产生冲突。&lt;/p&gt;
&lt;p&gt;如果没有 Git，团队开发时很容易出现以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不知道代码是谁修改的  &lt;/li&gt;
&lt;li&gt;不知道某次修改是否引入了 bug  &lt;/li&gt;
&lt;li&gt;多人修改同一文件产生覆盖  &lt;/li&gt;
&lt;li&gt;无法回退到之前的版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，建议所有队员都通过 Git 管理代码，而不要直接通过文件拷贝的方式共享代码。&lt;/p&gt;
&lt;h2&gt;查看 Git 是否安装&lt;/h2&gt;
&lt;p&gt;在终端输入：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果出现类似输出：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git version 2.xx.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明 Git 已经安装成功。&lt;/p&gt;
&lt;p&gt;如果没有安装，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt install git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进行安装。&lt;/p&gt;
&lt;h2&gt;克隆代码仓库&lt;/h2&gt;
&lt;p&gt;在开始开发之前，首先需要从远程仓库下载代码。&lt;/p&gt;
&lt;p&gt;例如从 GitHub 或 GitLab 下载项目：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone 仓库地址
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/xxx/robocup-vision.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行完成后，会在当前目录生成一个项目文件夹。&lt;/p&gt;
&lt;p&gt;进入项目目录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd robocup-vision
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查看当前代码状态&lt;/h2&gt;
&lt;p&gt;在开发过程中，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看当前代码状态。&lt;/p&gt;
&lt;p&gt;该命令可以显示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪些文件被修改&lt;/li&gt;
&lt;li&gt;哪些文件还没有加入版本管理&lt;/li&gt;
&lt;li&gt;当前所在的分支&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是开发过程中最常使用的命令之一。&lt;/p&gt;
&lt;h2&gt;添加文件到版本控制&lt;/h2&gt;
&lt;p&gt;当修改代码后，需要先将修改加入 Git 暂存区。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add 文件名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add main.cpp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果想添加当前目录所有修改，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add .
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;提交代码&lt;/h2&gt;
&lt;p&gt;添加完成后，需要进行提交。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git commit -m &amp;quot;修改说明&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git commit -m &amp;quot;fix vision detection bug&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的引号中是对本次修改的简要说明，建议写清楚修改内容。&lt;/p&gt;
&lt;h2&gt;推送代码到远程仓库&lt;/h2&gt;
&lt;p&gt;提交完成后，需要将代码上传到远程仓库：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样其他队员才能看到你的代码更新。&lt;/p&gt;
&lt;h2&gt;更新远程代码&lt;/h2&gt;
&lt;p&gt;如果其他队员已经更新了代码，可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git pull
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从远程仓库获取最新代码。&lt;/p&gt;
&lt;p&gt;建议每次开发之前先执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git pull
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以确保本地代码是最新版本。&lt;/p&gt;
&lt;h2&gt;查看代码历史&lt;/h2&gt;
&lt;p&gt;可以使用以下命令查看提交历史：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该命令可以查看每一次提交的记录，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提交人&lt;/li&gt;
&lt;li&gt;提交时间&lt;/li&gt;
&lt;li&gt;修改说明&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;常见开发流程&lt;/h2&gt;
&lt;p&gt;在团队开发中，推荐使用以下开发流程：&lt;/p&gt;
&lt;p&gt;首先更新代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git pull
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后进行代码修改。&lt;/p&gt;
&lt;p&gt;修改完成后：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add .
git commit -m &amp;quot;修改说明&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后上传代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git push
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;建议&lt;/h2&gt;
&lt;p&gt;在团队开发中建议遵守以下几点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每次提交前写清楚 commit 信息&lt;/li&gt;
&lt;li&gt;每次开发前先执行 &lt;code&gt;git pull&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;不要直接修改主分支的大量代码&lt;/li&gt;
&lt;li&gt;修改较大功能时建议创建新的分支&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;合理使用 Git 可以大大提高团队开发效率，并减少代码冲突。&lt;/p&gt;
&lt;h1&gt;服务器使用礼貌提示&lt;/h1&gt;
&lt;p&gt;由于 RoboCup 视觉开发板通常是多人共同使用的计算资源，因此在使用过程中需要注意一些基本的服务器使用规范，以避免影响其他队员的正常开发。&lt;/p&gt;
&lt;p&gt;服务器资源包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;内存&lt;/li&gt;
&lt;li&gt;GPU / NPU&lt;/li&gt;
&lt;li&gt;磁盘空间&lt;/li&gt;
&lt;li&gt;网络带宽&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果使用不当，很容易影响其他人的实验或开发工作。因此在使用服务器时需要遵守一些基本的礼貌和规范。&lt;/p&gt;
&lt;h2&gt;不要长时间占用计算资源&lt;/h2&gt;
&lt;p&gt;在运行深度学习模型、训练程序或其他高计算负载任务时，请注意不要长时间占用服务器资源。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大规模训练任务&lt;/li&gt;
&lt;li&gt;长时间推理任务&lt;/li&gt;
&lt;li&gt;无限循环程序&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果需要运行长时间任务，建议提前与队友沟通。&lt;/p&gt;
&lt;p&gt;可以使用以下命令查看当前运行的程序：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;top
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果系统中安装了 &lt;code&gt;htop&lt;/code&gt;，也可以使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;htop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该命令可以更加直观地查看当前 CPU 和内存的使用情况。&lt;/p&gt;
&lt;h2&gt;使用完成后及时关闭程序&lt;/h2&gt;
&lt;p&gt;很多初学者在运行程序后会直接关闭 SSH 窗口，但程序实际上仍然在服务器上运行。&lt;/p&gt;
&lt;p&gt;如果程序已经不再需要运行，应主动结束对应进程。&lt;/p&gt;
&lt;p&gt;可以先查看当前进程：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;top
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到对应程序的 &lt;strong&gt;PID（进程ID）&lt;/strong&gt;，然后使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;kill PID
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;kill 12345
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样可以避免程序长期占用服务器资源。&lt;/p&gt;
&lt;h2&gt;不要随意删除或修改他人的文件&lt;/h2&gt;
&lt;p&gt;服务器通常是多人共同使用的环境，因此不要随意删除或修改他人的代码、环境或数据。&lt;/p&gt;
&lt;p&gt;如果需要清理空间，只删除自己目录下的文件。&lt;/p&gt;
&lt;p&gt;一般来说，每个人应该主要在自己的目录中进行开发，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;/home/username/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不要在系统目录或公共目录下随意删除文件。&lt;/p&gt;
&lt;h2&gt;安装软件前尽量确认&lt;/h2&gt;
&lt;p&gt;在服务器上安装软件或 Python 库之前，建议先确认是否会影响现有环境。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不要随意修改系统 Python&lt;/li&gt;
&lt;li&gt;不要随意删除 conda 环境&lt;/li&gt;
&lt;li&gt;不要覆盖公共环境&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果需要安装新的 Python 库，建议在 &lt;strong&gt;自己的 conda 环境&lt;/strong&gt; 中安装，而不是直接安装到系统环境中。&lt;/p&gt;
&lt;h2&gt;不要占满磁盘空间&lt;/h2&gt;
&lt;p&gt;服务器磁盘空间是共享资源，如果大量存储数据或模型，可能会影响其他人的使用。&lt;/p&gt;
&lt;p&gt;可以使用以下命令查看磁盘空间：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;df -h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果产生大量临时数据（例如日志文件、训练数据、缓存等），建议定期清理。&lt;/p&gt;
&lt;h2&gt;离开服务器前检查程序&lt;/h2&gt;
&lt;p&gt;在关闭 SSH 或 VSCode 连接之前，建议确认自己启动的程序是否仍在运行。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;top
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果程序已经不需要继续运行，请手动结束对应进程。&lt;/p&gt;
&lt;h2&gt;发现异常及时沟通&lt;/h2&gt;
&lt;p&gt;如果发现服务器出现以下情况，应及时通知队友或管理员：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统运行明显变慢&lt;/li&gt;
&lt;li&gt;GPU / NPU 长时间被占用&lt;/li&gt;
&lt;li&gt;无法 SSH 登录&lt;/li&gt;
&lt;li&gt;磁盘空间耗尽&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不要自行进行大规模系统修改，以免影响整个开发环境。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;服务器是团队共享资源，合理使用不仅能提高开发效率，也能避免很多不必要的问题。&lt;/p&gt;
&lt;p&gt;简单来说，可以记住以下三点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不乱删&lt;/li&gt;
&lt;li&gt;不乱装&lt;/li&gt;
&lt;li&gt;不长时间占用资源&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Wed, 11 Mar 2026 00:00:00 GMT</pubDate></item><item><title>pi_RL：基于流式VLA的在线强化学习微调</title><link>https://dannyshi.pages.dev/blog/paper-reading/pi_rl/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/pi_rl/</guid><description>论文阅读：pi_RL 与 VLA 在线强化学习</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/pi_rl/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/pi_rl/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇聚焦 `VLA + Online RL` 的交叉方向，适合把它看成“把语言视觉动作模型继续往可交互、可持续优化方向推进”的代表工作。
&lt;/Info&gt;

&lt;h2&gt;论文信息&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2510.25889&quot;&gt;Arxiv ID&lt;/a&gt;
&lt;a href=&quot;https://hjfy.top/arxiv/2510.25889&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;$\pi_{RL}$：基于流式VLA的在线强化学习微调&lt;/h2&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;目前主流的VLAs的训练方法主要遵循两个步骤：先对VLM进行与预训练与有监督微调（SFT）的范式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;在预训练的VLM基础中，VLA会在大规模，异构的人类演示数据集上进行微调&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;随后在目标任务上进行SFT，使其能力能够与特定的机器人形态与环境对齐。然而SFT面临一些关键的挑战。首先，大规模的专家轨迹获取成本十分昂贵且费力，齐次仅仅通过SFT微调的模型往往会过拟合专家的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此近期的工作开始探索RL扩展到VLA的后训练过程，建立了一个如下图 &lt;strong&gt;预训练-&amp;gt;SFT-&amp;gt;RL&lt;/strong&gt; 的三阶段的训练范式。使 VLA 能够通过主动环境交互和制定更具泛化能力的策略，将其性能提升至超越最初专家示范的水平。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.7pu79m4ds.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;然而，目前主流将RL应用到VLA模型中的模型主要局限在自回归VLA模型的领域，典型代表包括OpenVLA[^openvla]、OpenVLA-OFT[^openvla-oft]。这类模型采用离散动作解码器，以自回归或并行方式生成输出。核心在于让模型直接输出Action token，将动作维度离散化为256个区间，并使用Llama分词器中使用频率最低的256个token表示。这种方式与基于扩散和流的VLA形成对比，例如 $\pi$ 系列的 $\pi_0$[^pi0]、$\pi_{0.5}$[^pi05] 等代表性工作。这类模型通过flow matching中的的迭代过程来生成动作。这类VLA范式相较于Openvla-like的模型，不近动作生成频率更高，动作更加平顺，还能完成高灵巧度的任务。&lt;/p&gt;
&lt;p&gt;然而，由于如何针对执行动作来刻画对数似然这一根本挑战，导致目前VLA-RL算法无法直接兼容于基于流的VLA模型。为了解决上述问题，这篇论文提出了$\pi_{RL}$[^pirl]，这是首个用于微调基于流的VLA模型的开源并行在线强化学习框架。&lt;/p&gt;
&lt;p&gt;在这篇文章中，作者提出了两种解决方案来处理上述问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;Flow-Noise
将可学习的噪声网络集成到去噪流程中，并将该阶段建模为离散时间马尔可夫决策过程（MDP），以实现精确的对数似然估计。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Flow-SDE
将普通微分方程（ODE）去噪流程转化为随机微分方程（SDE），在保证等效边缘分布用于探索的同时，构建了将去噪流程与策略—环境交互耦合的两层 MDP，并配合混合 ODE-SDE 采样技术来加速训练。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Related works&lt;/h3&gt;
&lt;p&gt;VLA 模型最近通过集成多模态输入，在机器人领域取得了显著进展，实现了统一的感知、推理与控制。这一进展催生了一系列架构，包括Octo[^octo]、RT-1[^rt1]、OpenVLA[^openvla]、OpenVLA-OFT[^openvla-oft]、$\pi_0$[^pi0]、$\pi_{0.5}$[^pi05] 和 GR00T[^gr00t]。&lt;/p&gt;
&lt;p&gt;OpenVLA 作为自回归VLA 架构的代表，将动作空间离散化为符号化表示
这使得基于语言条件的控制成为可能，通过将动作作为VLM 词汇表的一部分进行处理，但该方法在本质上限制了实现精细化运动所需的分辨率。&lt;/p&gt;
&lt;p&gt;为了实现更加灵巧且连续的物理行为，$\pi_0、\pi_{0.5}$ 作为基于流的VLA 架构的代表，引入了基于流匹配的动作分块架构。这使VLA 能够建模复杂的连续动作分布，从而实现更为灵巧的物理行为。&lt;/p&gt;
&lt;p&gt;近期的研究越来越多的集中于利用online RL来提升VLA的性能和泛化能力。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;SimpleVLA-RL[^simplevla-rl]基于OpenVLA-OFT和GRPO，展示了在数据稀缺情况下，强化学习能够提升VLA模型的长程规划能力&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;RL4VLA（文中对应的经验研究工作）[^rl4vla]通过阶段性稀疏奖励，实证评估了PPO、GRPO和直接偏好优化（DPO）（Rafailov等，2023），发现PPO表现最佳&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;VLA-RL[^vla-rl]提出了专用的机器人流程奖励模型，并优化了数据处理流程&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;iRe-VLA[^ire-vla]提出了在强化学习探索与SFT更新之间迭代的框架&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;RIPT-VLA[^ript-vla]将REINFORCE leave-one-out（RLOO）（Kool等，2018）算法应用于QueST（Mete等，2024）和OpenVLA-OFT架构&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;RLinf-VLA[^rlinf-vla]为大规模强化学习训练VLA模型提供了统一且高效的框架，支持多样化的VLA——OpenVLA 和 OpenVLA-OFT 等架构，以及 PPO、GRPO 等多种强化学习（RL）算法，还有包括LIBERO 和 ManiSkill 在内的多种模拟器&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上述工作均体现了将online RL应用到VLA的潜力，然而由于上述提及的对数似然的挑战，使得其在基于流的VLA中的应用仍然受限。&lt;/p&gt;
&lt;p&gt;为解决online RL在flow matching模型的应用问题，主要研究集中在这里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;Flow-GRPO[^flow-grpo]（Liu 等，2025a）将确定性常微分方程（ODE）转化为等价的随机微分方程（SDE），以实现随机性探索。在此基础上，后续研究如 Mix-GRPO[^mix-grpo]（Li 等，2025b）和 TempFlow-GRPO[^tempflow-grpo]（He 等，2025）通过混合 ODE-SDE rollout 进一步加速训练&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;ReinFlow[^reinflow]（Zhang 等，2025）在流路径中注入可学习的噪声，并将其转化为具有可计算似然的离散时间马尔可夫过程，从而实现稳定的策略梯度更新&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;流策略优化（FPO）[^fpo]（McAllister 等，2025）将策略优化重构为最大化条件流匹配损失的优势加权比&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;策略无关强化学习（PA-RL）[^pa-rl]（Mark 等，2024）能够通过监督学习将评论家优化后的动作蒸馏到策略中，实现对各类扩散和 Transformer 架构的高效微调&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;通过强化学习引导扩散（DSRL）[^dsrl]（Wagenmaker 等，2025）则在其潜在噪声空间中执行强化学习，从而优化流策略，而无需直接修改策略参数本身&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Method&lt;/h3&gt;
&lt;p&gt;在介绍具体方法之前，作者首先对基于流匹配的 VLA 策略进行形式化描述。
在 $\pi_0$ 与 $\pi_{0.5}$ 等流式 VLA 模型中，动作并不是通过一次前向传播直接生成，而是通过一个逐步去噪的生成过程得到。具体而言，模型首先从一个随机噪声分布中采样初始动作表示 $x_0$，随后通过一个由神经网络参数化的速度场 $v_\theta(x_t,t)$ 逐步对该噪声进行更新。该过程可以表示为如下常微分方程：&lt;/p&gt;
&lt;p&gt;$$
\frac{dx_t}{dt}=v_\theta(x_t,t)
$$&lt;/p&gt;
&lt;p&gt;通过数值积分将时间从 $t=0$ 推进到 $t=1$ 后，最终得到的 $x_1$ 即为生成的动作序列。在实际的 VLA 系统中，该动作通常表示为一段动作块（action chunk），随后在机器人环境中执行。&lt;/p&gt;
&lt;p&gt;然而，在强化学习框架下，策略优化通常依赖于动作在当前策略下的概率密度 $\pi(a|s)$。对于基于流匹配的模型而言，动作是通过连续的去噪轨迹生成的结果，其概率密度并不能像高斯策略或离散策略那样被显式写出。因此，在原始的 flow matching 模型中，执行动作的对数似然难以计算，这使得 PPO 或 GRPO 等策略梯度算法难以直接应用。&lt;/p&gt;
&lt;p&gt;为了解决这一问题，$\pi_{RL}$ 提出了两种不同的建模方式，使得 flow matching 生成过程能够与强化学习框架兼容。&lt;/p&gt;
&lt;p&gt;首先是 &lt;strong&gt;Flow-Noise&lt;/strong&gt; 方法。该方法在原本确定性的去噪更新过程中引入一个可学习的噪声项，使得每一步的状态转移都具有明确的概率分布。具体而言，在离散化的时间步中，原始的更新公式&lt;/p&gt;
&lt;p&gt;$$
x_{k+1}=x_k+\Delta t,v_\theta(x_k,t_k)
$$&lt;/p&gt;
&lt;p&gt;被改写为&lt;/p&gt;
&lt;p&gt;$$
x_{k+1}=x_k+\Delta t,v_\theta(x_k,t_k)+\sigma_k\epsilon
$$&lt;/p&gt;
&lt;p&gt;其中 $\epsilon\sim\mathcal{N}(0,I)$。在这一建模下，去噪过程中的每一步更新都可以被看作一个带噪声的马尔可夫转移，因此整个生成过程可以被建模为一个离散时间的马尔可夫决策过程。由于每一步状态转移都具有明确的高斯概率密度，整条生成轨迹的概率可以表示为各个时间步条件概率的乘积，从而能够计算对应的对数似然并进行策略梯度更新。&lt;/p&gt;
&lt;p&gt;另一种方法是 &lt;strong&gt;Flow-SDE&lt;/strong&gt;。与 Flow-Noise 在离散时间上注入噪声不同，Flow-SDE 从连续时间动力系统的角度出发，将原始的常微分方程改写为随机微分方程：&lt;/p&gt;
&lt;p&gt;$$
dx=v_\theta(x,t)dt+g(t)dW_t
$$&lt;/p&gt;
&lt;p&gt;其中 $dW_t$ 表示布朗运动。通过这种方式，生成过程本身被转化为一个随机动力系统。在离散化之后，每一步更新同样可以写为带噪声的随机转移，因此整个生成过程形成一个随机马尔可夫链。与 Flow-Noise 不同的是，Flow-SDE 保持了原始 ODE 模型的边缘分布一致性，同时引入随机性以支持探索。&lt;/p&gt;
&lt;p&gt;在 Flow-SDE 的框架下，作者进一步指出在 flow-based VLA 中实际上存在两个相互耦合的动态过程。第一个过程是模型内部的去噪生成过程，即从噪声逐渐生成动作轨迹；第二个过程是机器人在真实环境中的交互过程，即由状态、动作与奖励构成的环境 MDP。Flow-SDE 将这两个过程统一到一个两层 MDP 结构中，其中生成过程决定策略输出，而环境交互过程产生奖励信号，并通过强化学习更新策略参数。&lt;/p&gt;
&lt;p&gt;在实际训练过程中，作者还采用了 &lt;strong&gt;混合 ODE-SDE rollout&lt;/strong&gt; 的策略，以在保持探索能力的同时提高采样效率。具体而言，在部分时间步使用随机 SDE 更新，而在其余时间步使用确定性 ODE 更新，从而在探索与计算效率之间取得平衡。&lt;/p&gt;
&lt;h3&gt;Experiments&lt;/h3&gt;
&lt;p&gt;实验部分主要围绕性能提升、分布外泛化与跨架构迁移三个维度展开。作者在统一的 SFT 初始化基础上，分别采用 Flow-SDE 与 Flow-Noise 进行在线强化学习微调，并在多个机器人基准上进行对比评估。[^pirl][^pirl_bench]&lt;/p&gt;
&lt;h4&gt;Benchmark 总览&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benchmark&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;论文中使用方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;LIBERO&lt;/td&gt;
&lt;td&gt;ID 主评测&lt;/td&gt;
&lt;td&gt;四个子集（Spatial/Object/Goal/Long），主表报告平均成功率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ManiSkill&lt;/td&gt;
&lt;td&gt;ID + OOD&lt;/td&gt;
&lt;td&gt;ID 主结果 + 多种 OOD 扰动（语言/视觉/语义/执行）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MetaWorld&lt;/td&gt;
&lt;td&gt;ID + OOD&lt;/td&gt;
&lt;td&gt;ID 用 50 任务评测，OOD 用 ML45 检查任务泛化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CALVIN&lt;/td&gt;
&lt;td&gt;ID + OOD&lt;/td&gt;
&lt;td&gt;长时序任务；OOD 使用 ABC→D 迁移评测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SIMPLER&lt;/td&gt;
&lt;td&gt;单任务验证&lt;/td&gt;
&lt;td&gt;4 个抓放类任务，用于检验单任务增益&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;注：上表是论文实验设置摘要，具体数字见后续表格与附录。[^pirl_bench]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;表 1：四大基准 ID 主结果（success rate, %）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Method&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;LIBERO&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;ManiSkill&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;MetaWorld&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;CALVIN&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Avg.&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;相对 SFT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;$\pi_0$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;SFT&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;57.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;38.4&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;50.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;57.5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;51.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_0$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;Flow-SDE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;96.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;78.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;78.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;61.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;78.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+27.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_0$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;Flow-Noise&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;97.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;77.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;85.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;59.9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;80.3&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+29.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_{0.5}$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;SFT&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;77.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;40.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;43.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;61.3&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;55.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_{0.5}$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;Flow-SDE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;97.9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;90.9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;70.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;87.0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;86.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+31.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_{0.5}$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;Flow-Noise&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;98.3&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;89.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;66.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;84.5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;84.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+29.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;从主结果可以观察到，两种 RL 方案均显著优于 SFT 基线，且在 $\pi_{0.5}$ 上的增益更为稳定。[^pirl_tab1]&lt;/p&gt;
&lt;h4&gt;表 2：ManiSkill OOD 细分结果（$\pi_{0.5}$）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;SFT&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Flow-SDE&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Flow-Noise&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Main-v3-train（ID）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;40.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;90.9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;89.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruct-v1-test（语言变化）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;46.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;77.0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;85.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image-v1-test（视觉变化）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;46.2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;78.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;83.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Texture05-v1-test（强纹理扰动）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;32.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;58.0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;62.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MultiCarrot-v1-test（语义干扰）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;16.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;36.8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;38.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Position-v1-test（执行偏移）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;31.2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;54.5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;55.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;ManiSkill 的细分结果表明，RL 带来的收益可迁移到多类 OOD 扰动；但在涉及任务语义迁移时，提升幅度相对受限。[^pirl_tab7][^pirl_ood_summary]&lt;/p&gt;
&lt;h4&gt;表 3：CALVIN OOD（ABC→D）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Success Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;SFT baseline&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;61.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RL fine-tuned&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;79.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Absolute gain&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+17.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;CALVIN 的 OOD 评测与 ManiSkill 呈现一致趋势，即在视觉和环境变化条件下，RL 微调后的策略具有更高鲁棒性。[^pirl_calvin_ood]&lt;/p&gt;
&lt;h4&gt;表 4：PPO vs GRPO（Flow-SDE, LIBERO）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;SFT Avg.&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;+GRPO Avg.&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;+PPO Avg.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;$\pi_0$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;57.6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;90.0&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;96.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$\pi_{0.5}$&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;77.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;91.5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;97.9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;在该实验配置下，PPO 在最终成功率上优于 GRPO。[^pirl_tab9]&lt;/p&gt;
&lt;h4&gt;表 5：单任务与跨骨干验证&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;任务/模型&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;SFT&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;RL 后&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;提升&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;SIMPLER（$\pi_0$，4 任务平均）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;67.2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;86.7&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+19.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SIMPLER（$\pi_{0.5}$，4 任务平均）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;59.2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;79.1&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+19.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GR00T N1.5（LIBERO Avg.）&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;52.5&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;89.9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;+37.4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;单任务与跨骨干结果进一步说明，该方法并非仅对 $\pi$ 系列有效，在 GR00T 架构上同样能够获得显著提升。[^pirl_tab8][^pirl_tab10]&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;总体而言，$\pi_{RL}$ 提出了一种面向基于流匹配的 VLA 模型的在线强化学习框架，并系统性地解决了 flow matching 模型在强化学习中的对数似然计算问题。通过 Flow-Noise 和 Flow-SDE 两种不同的建模方式，作者成功地将原本难以应用策略梯度算法的流式生成过程转化为可计算概率的随机决策过程，从而使 PPO、GRPO 等强化学习算法能够用于优化 flow-based VLA 策略。&lt;/p&gt;
&lt;p&gt;从更宏观的角度来看，这项工作展示了强化学习在 VLA 后训练阶段的重要潜力。与仅依赖专家示范数据的监督学习相比，通过环境交互获得的强化学习信号能够帮助模型发现更优的策略，并在复杂任务中表现出更强的泛化能力。同时，该工作也表明生成式策略模型（如扩散模型与流匹配模型）与强化学习的结合是一个值得进一步探索的重要方向。&lt;/p&gt;
&lt;p&gt;未来的研究可能会继续探索更高效的采样策略、更稳定的策略优化方法以及更加真实的机器人环境评估，以推动 VLA 模型在真实世界机器人系统中的应用。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;πRL 代码流程导读（对齐 &lt;code&gt;arXiv:2510.25889v3&lt;/code&gt;）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/RLinf/RLinf&quot;&gt;代码仓库&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这份文档按“论文方法 -&amp;gt; 仓库代码 -&amp;gt; 运行时调用链”来梳理&lt;/p&gt;
&lt;h3&gt;核心文件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;入口脚本: &lt;a href=&quot;../examples/embodiment/train_embodied_agent.py&quot;&gt;train_embodied_agent.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Runner 主循环: &lt;a href=&quot;../rlinf/runners/embodied_runner.py&quot;&gt;embodied_runner.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Actor 训练核心: &lt;a href=&quot;../rlinf/workers/actor/fsdp_actor_worker.py&quot;&gt;fsdp_actor_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rollout 采样核心: &lt;a href=&quot;../rlinf/workers/rollout/hf/huggingface_worker.py&quot;&gt;huggingface_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Env 交互核心: &lt;a href=&quot;../rlinf/workers/env/env_worker.py&quot;&gt;env_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;π0/π0.5 模型核心: &lt;a href=&quot;../rlinf/models/embodiment/openpi/openpi_action_model.py&quot;&gt;openpi_action_model.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;算法注册入口: &lt;a href=&quot;../rlinf/algorithms/registry.py&quot;&gt;registry.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;优势函数: &lt;a href=&quot;../rlinf/algorithms/advantages.py&quot;&gt;advantages.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PPO/GRPO Loss: &lt;a href=&quot;../rlinf/algorithms/losses.py&quot;&gt;losses.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;π0.5 示例配置: &lt;a href=&quot;../examples/embodiment/config/maniskill_ppo_openpi_pi05.yaml&quot;&gt;maniskill_ppo_openpi_pi05.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;π0.5 默认模型配置: &lt;a href=&quot;../examples/embodiment/config/model/pi0_5.yaml&quot;&gt;pi0_5.yaml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1. 论文方法与代码模块对齐&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;论文模块&lt;/th&gt;
&lt;th&gt;对应代码&lt;/th&gt;
&lt;th&gt;你要看什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Online RL 框架&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/runners/embodied_runner.py&quot;&gt;embodied_runner.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;每个训练 step 的执行顺序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flow-SDE / Flow-Noise&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/models/embodiment/openpi/openpi_action_model.py&quot;&gt;openpi_action_model.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;noise_method&lt;/code&gt; 分支的数学实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;轨迹采样&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/workers/rollout/hf/huggingface_worker.py&quot;&gt;huggingface_worker.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;如何产出 &lt;code&gt;prev_logprobs/prev_values&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;环境交互&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/workers/env/env_worker.py&quot;&gt;env_worker.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;obs -&amp;gt; action -&amp;gt; obs/reward/done&lt;/code&gt; 管道&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PPO/GRPO 更新&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/workers/actor/fsdp_actor_worker.py&quot;&gt;fsdp_actor_worker.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/losses.py&quot;&gt;losses.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;先算优势，再算策略/价值损失&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GAE/GRPO 优势&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;../rlinf/algorithms/advantages.py&quot;&gt;advantages.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/registry.py&quot;&gt;registry.py&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;adv_type&lt;/code&gt; 如何路由&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;2. 从启动到一次训练 step 的调用链&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;启动入口 &lt;a href=&quot;../examples/embodiment/train_embodied_agent.py&quot;&gt;train_embodied_agent.py&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;validate_cfg(cfg)&lt;/code&gt; 检查配置&lt;/li&gt;
&lt;li&gt;创建 &lt;code&gt;actor/rollout/env&lt;/code&gt; 三个 worker group&lt;/li&gt;
&lt;li&gt;创建并启动 &lt;code&gt;EmbodiedRunner.run()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Runner 主循环 &lt;a href=&quot;../rlinf/runners/embodied_runner.py&quot;&gt;embodied_runner.py&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;update_rollout_weights()&lt;/code&gt;：Actor 权重同步到 Rollout&lt;/li&gt;
&lt;li&gt;&lt;code&gt;env.interact(...)&lt;/code&gt; 与 &lt;code&gt;rollout.generate(...)&lt;/code&gt; 并行执行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actor.recv_rollout_trajectories(...)&lt;/code&gt; 接收轨迹&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actor.compute_advantages_and_returns()&lt;/code&gt; 计算优势&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actor.run_training()&lt;/code&gt; 做参数更新&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;数据在 worker 间流动&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Env 发送观测到 Rollout&lt;/li&gt;
&lt;li&gt;Rollout 预测动作回 Env，并把训练轨迹送 Actor&lt;/li&gt;
&lt;li&gt;Actor 使用旧 logprob/value + 新前向结果计算 PPO/GRPO loss&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. 关键代码&lt;/h3&gt;
&lt;h4&gt;3.1 Runner 主循环（对应论文在线 RL 外层循环）&lt;/h4&gt;
&lt;p&gt;来源: &lt;a href=&quot;../rlinf/runners/embodied_runner.py&quot;&gt;embodied_runner.py&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 中文注释：每个 _step 是一次“收集在线数据 + 更新策略”的完整迭代
for _step in range(start_step, self.max_steps):
    # 中文注释：先把 actor 新权重同步给 rollout，保证采样策略是最新的
    if _step % self.weight_sync_interval == 0:
        self.update_rollout_weights()

    # 中文注释：env 与 rollout 协同，产生本轮轨迹
    env_handle = self.env.interact(...)
    rollout_handle = self.rollout.generate(...)

    # 中文注释：actor 从通道拿到 rollout 轨迹（含 prev_logprobs/prev_values）
    self.actor.recv_rollout_trajectories(...).wait()

    # 中文注释：根据 rewards/dones/values 计算优势和回报（GAE 或 GRPO）
    self.actor.compute_advantages_and_returns().wait()

    # 中文注释：进行 PPO/GRPO 参数更新
    actor_training_handle = self.actor.run_training()
    actor_training_metrics = actor_training_handle.wait()
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.2 Flow-SDE 与 Flow-Noise 分支（对应论文两条技术路线）&lt;/h4&gt;
&lt;p&gt;来源: &lt;a href=&quot;../rlinf/models/embodiment/openpi/openpi_action_model.py&quot;&gt;openpi_action_model.py&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if self.config.noise_method == &amp;quot;flow_sde&amp;quot;:
    # 中文注释：Flow-SDE
    # 1) 由时间步构造 sigma_i（与 t 有关）
    # 2) 用 ODE-&amp;gt;SDE 的形式计算 x_t 的均值 x_t_mean 与方差 x_t_std
    # 3) 采样 x_t = mean + noise * std，实现可探索的去噪更新
    sigmas = noise_level * torch.sqrt(timesteps / (1 - adjusted_timesteps))[:-1]
    sigma_i = sigmas[idx][:, None, None].expand_as(x_t)
    x_t_std = torch.sqrt(delta) * sigma_i

elif self.config.noise_method == &amp;quot;flow_noise&amp;quot;:
    # 中文注释：Flow-Noise
    # 1) 均值项仍来自流匹配去噪动力学
    # 2) 方差项不再手工公式给定，而是由 noise_head 学习得到
    # 3) 因此可对概率密度建模得更灵活，适配联合 logprob 优化
    x_t_std = self.noise_head(suffix_out)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.3 joint_logprob 逻辑（Flow-Noise 常配）&lt;/h4&gt;
&lt;p&gt;来源: &lt;a href=&quot;../rlinf/models/embodiment/openpi/openpi_action_model.py&quot;&gt;openpi_action_model.py&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if self.config.joint_logprob:
    # 中文注释：联合建模整条去噪链每一步的 logprob
    # 通常配 flow_noise 使用，优化目标更“全链路”
    denoise_inds = torch.arange(num_steps)
else:
    # 中文注释：只抽取某一步去噪的 logprob 参与训练
    # 常见于 flow_sde 配置，计算量较小
    denoise_inds = torch.tensor([random_idx] * num_steps)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.4 Actor 优势与损失更新（对应论文 RL 优化）&lt;/h4&gt;
&lt;p&gt;来源: &lt;a href=&quot;../rlinf/workers/actor/fsdp_actor_worker.py&quot;&gt;fsdp_actor_worker.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/registry.py&quot;&gt;registry.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/losses.py&quot;&gt;losses.py&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 中文注释：用统一入口按 adv_type 路由（gae/grpo/...）
advantages_and_returns = calculate_adv_and_returns(
    adv_type=self.cfg.algorithm.adv_type,
    rewards=self.rollout_batch[&amp;quot;rewards&amp;quot;],
    dones=self.rollout_batch[&amp;quot;dones&amp;quot;],
    values=self.rollout_batch.get(&amp;quot;prev_values&amp;quot;, None),
)

# 中文注释：模型前向得到当前策略 logprobs/values
output_dict = self.model(
    forward_inputs=forward_inputs,
    compute_logprobs=True,
    compute_values=compute_values,
)

# 中文注释：按 loss_type 路由到 actor_critic 或 actor
# PPO 核心是 ratio=exp(new_logprob-old_logprob) + clip
loss, metrics_data = policy_loss(
    loss_type=self.cfg.algorithm.loss_type,
    logprobs=output_dict[&amp;quot;logprobs&amp;quot;],
    old_logprobs=prev_logprobs,
    advantages=advantages,
    values=output_dict.get(&amp;quot;values&amp;quot;, None),
    returns=returns,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 配置如何映射到论文设定&lt;/h3&gt;
&lt;p&gt;参考: &lt;a href=&quot;../examples/embodiment/config/maniskill_ppo_openpi_pi05.yaml&quot;&gt;maniskill_ppo_openpi_pi05.yaml&lt;/a&gt;, &lt;a href=&quot;../examples/embodiment/config/model/pi0_5.yaml&quot;&gt;pi0_5.yaml&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;actor.model.openpi.noise_method&lt;/code&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;flow_sde&lt;/code&gt;: 走 SDE 公式分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flow_noise&lt;/code&gt;: 走 learnable noise 分支&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actor.model.openpi.joint_logprob&lt;/code&gt;&lt;ul&gt;
&lt;li&gt;一般 &lt;code&gt;flow_noise=True&lt;/code&gt; 时设为 &lt;code&gt;True&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actor.model.openpi.value_after_vlm&lt;/code&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;True&lt;/code&gt;: critic 接在 VLM 输出后（π0.5 常见）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;False&lt;/code&gt;: critic 接在 action expert 分支（π0 常见）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;algorithm.adv_type&lt;/code&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gae&lt;/code&gt; / &lt;code&gt;grpo&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;algorithm.loss_type&lt;/code&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;actor_critic&lt;/code&gt; / &lt;code&gt;actor&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 建议阅读顺序&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;../examples/embodiment/config/maniskill_ppo_openpi_pi05.yaml&quot;&gt;maniskill_ppo_openpi_pi05.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../examples/embodiment/train_embodied_agent.py&quot;&gt;train_embodied_agent.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/runners/embodied_runner.py&quot;&gt;embodied_runner.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/workers/env/env_worker.py&quot;&gt;env_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/workers/rollout/hf/huggingface_worker.py&quot;&gt;huggingface_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/workers/actor/fsdp_actor_worker.py&quot;&gt;fsdp_actor_worker.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/models/embodiment/openpi/openpi_action_model.py&quot;&gt;openpi_action_model.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../rlinf/algorithms/registry.py&quot;&gt;registry.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/advantages.py&quot;&gt;advantages.py&lt;/a&gt;, &lt;a href=&quot;../rlinf/algorithms/losses.py&quot;&gt;losses.py&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;[^openvla]: Kim et al., &lt;em&gt;OpenVLA: An Open-Source Vision-Language-Action Model&lt;/em&gt;. arXiv:2406.09246. &lt;a href=&quot;https://arxiv.org/abs/2406.09246&quot;&gt;https://arxiv.org/abs/2406.09246&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^openvla-oft]: Kim et al., &lt;em&gt;Fine-Tuning Vision-Language-Action Models: Optimizing Speed and Success&lt;/em&gt; (OpenVLA-OFT). arXiv:2502.19645. &lt;a href=&quot;https://arxiv.org/abs/2502.19645&quot;&gt;https://arxiv.org/abs/2502.19645&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pi0]: Black et al., &lt;em&gt;$\pi_0$: A Vision-Language-Action Flow Model for General Robot Control&lt;/em&gt;. arXiv:2410.24164. &lt;a href=&quot;https://arxiv.org/abs/2410.24164&quot;&gt;https://arxiv.org/abs/2410.24164&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pi05]: Intelligence et al., &lt;em&gt;$\pi&lt;/em&gt;{0.5}$: a Vision-Language-Action Model with Open-World Generalization_. arXiv:2504.16054. &lt;a href=&quot;https://arxiv.org/abs/2504.16054&quot;&gt;https://arxiv.org/abs/2504.16054&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl]: Chen et al., &lt;em&gt;$\pi&lt;/em&gt;\texttt{RL}$: Online RL Fine-tuning for Flow-based Vision-Language-Action Models_. arXiv:2510.25889. &lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^octo]: Octo Model Team et al., &lt;em&gt;Octo: An Open-Source Generalist Robot Policy&lt;/em&gt;. arXiv:2405.12213. &lt;a href=&quot;https://arxiv.org/abs/2405.12213&quot;&gt;https://arxiv.org/abs/2405.12213&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^rt1]: Brohan et al., &lt;em&gt;RT-1: Robotics Transformer for Real-World Control at Scale&lt;/em&gt;. arXiv:2212.06817. &lt;a href=&quot;https://arxiv.org/abs/2212.06817&quot;&gt;https://arxiv.org/abs/2212.06817&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^gr00t]: Bjorck et al., &lt;em&gt;GR00T N1: An Open Foundation Model for Generalist Humanoid Robots&lt;/em&gt;. arXiv:2503.14734. &lt;a href=&quot;https://arxiv.org/abs/2503.14734&quot;&gt;https://arxiv.org/abs/2503.14734&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^simplevla-rl]: Li et al., &lt;em&gt;SimpleVLA-RL: Scaling VLA Training via Reinforcement Learning&lt;/em&gt;. arXiv:2509.09674. &lt;a href=&quot;https://arxiv.org/abs/2509.09674&quot;&gt;https://arxiv.org/abs/2509.09674&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^rl4vla]: Liu et al., &lt;em&gt;What Can RL Bring to VLA Generalization? An Empirical Study&lt;/em&gt;. arXiv:2505.19789. &lt;a href=&quot;https://arxiv.org/abs/2505.19789&quot;&gt;https://arxiv.org/abs/2505.19789&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^vla-rl]: Lu et al., &lt;em&gt;VLA-RL: Towards Masterful and General Robotic Manipulation with Scalable Reinforcement Learning&lt;/em&gt;. arXiv:2505.18719. &lt;a href=&quot;https://arxiv.org/abs/2505.18719&quot;&gt;https://arxiv.org/abs/2505.18719&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^ire-vla]: Guo et al., &lt;em&gt;Improving Vision-Language-Action Model with Online Reinforcement Learning&lt;/em&gt;. arXiv:2501.16664. &lt;a href=&quot;https://arxiv.org/abs/2501.16664&quot;&gt;https://arxiv.org/abs/2501.16664&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^ript-vla]: Tan et al., &lt;em&gt;Interactive Post-Training for Vision-Language-Action Models&lt;/em&gt; (RIPT-VLA). arXiv:2505.17016. &lt;a href=&quot;https://arxiv.org/abs/2505.17016&quot;&gt;https://arxiv.org/abs/2505.17016&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^rlinf-vla]: Zang et al., &lt;em&gt;RLinf-VLA: A Unified and Efficient Framework for Reinforcement Learning of Vision-Language-Action Models&lt;/em&gt;. arXiv:2510.06710. &lt;a href=&quot;https://arxiv.org/abs/2510.06710&quot;&gt;https://arxiv.org/abs/2510.06710&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^flow-grpo]: Liu et al., &lt;em&gt;Flow-GRPO: Training Flow Matching Models via Online RL&lt;/em&gt;. arXiv:2505.05470. &lt;a href=&quot;https://arxiv.org/abs/2505.05470&quot;&gt;https://arxiv.org/abs/2505.05470&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^mix-grpo]: Li et al., &lt;em&gt;MixGRPO: Unlocking Flow-based GRPO Efficiency with Mixed ODE-SDE&lt;/em&gt;. arXiv:2507.21802. &lt;a href=&quot;https://arxiv.org/abs/2507.21802&quot;&gt;https://arxiv.org/abs/2507.21802&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^tempflow-grpo]: He et al., &lt;em&gt;TempFlow-GRPO: When Timing Matters for GRPO in Flow Models&lt;/em&gt;. arXiv:2508.04324. &lt;a href=&quot;https://arxiv.org/abs/2508.04324&quot;&gt;https://arxiv.org/abs/2508.04324&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^reinflow]: Zhang et al., &lt;em&gt;ReinFlow: Fine-tuning Flow Matching Policy with Online Reinforcement Learning&lt;/em&gt;. arXiv:2505.22094. &lt;a href=&quot;https://arxiv.org/abs/2505.22094&quot;&gt;https://arxiv.org/abs/2505.22094&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^fpo]: McAllister et al., &lt;em&gt;Flow Matching Policy Gradients&lt;/em&gt;. arXiv:2507.21053. &lt;a href=&quot;https://arxiv.org/abs/2507.21053&quot;&gt;https://arxiv.org/abs/2507.21053&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pa-rl]: Mark et al., &lt;em&gt;Policy Agnostic RL: Offline RL and Online RL Fine-Tuning of Any Class and Backbone&lt;/em&gt;. arXiv:2412.06685. &lt;a href=&quot;https://arxiv.org/abs/2412.06685&quot;&gt;https://arxiv.org/abs/2412.06685&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^dsrl]: Wagenmaker et al., &lt;em&gt;Steering Your Diffusion Policy with Latent Space Reinforcement Learning&lt;/em&gt;. arXiv:2506.15799. &lt;a href=&quot;https://arxiv.org/abs/2506.15799&quot;&gt;https://arxiv.org/abs/2506.15799&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_bench]: Chen et al., 2026, Sec. 5 与 Appendix C/D/E：实验覆盖 LIBERO、ManiSkill、MetaWorld、CALVIN、SIMPLER，并含 OOD 与单任务设置。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_tab1]: Chen et al., 2026, Table 1（ID 综合对比）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_tab7]: Chen et al., 2026, Appendix Table 7（ManiSkill OOD 细分）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_calvin_ood]: Chen et al., 2026, Appendix Sec. D.2（CALVIN ABC→D：61.3%→79.1%）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_tab8]: Chen et al., 2026, Appendix Table 8（SIMPLER）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_tab9]: Chen et al., 2026, Appendix Table 9（PPO vs GRPO）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_tab10]: Chen et al., 2026, Appendix Table 10（GR00T N1.5）。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^pirl_ood_summary]: Chen et al., 2026, Appendix Sec. D.4：RL 对相近任务和低层扰动有效，但对全新任务目标泛化有限。&lt;a href=&quot;https://arxiv.org/abs/2510.25889&quot;&gt;https://arxiv.org/abs/2510.25889&lt;/a&gt;&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Wed, 04 Mar 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 9: 图像检测、分割、可视化</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture8%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture8%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture8%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture8%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇内容跨度比较大，覆盖检测、分割和可视化。更适合按任务类型分段阅读，而不是一次性从头到尾硬啃。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 9: 检测、分割、可视化与理解&lt;/h2&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;在计算机视觉的宏大版图中，图像分类仅仅是理解视觉世界的第一步。当我们希望模型不仅能识别“这是什么”，还能精确指出“它在哪里”、“它的轮廓如何”甚至“它在做什么”时，我们就进入了目标检测、语义分割和实例分割等更复杂的任务领域。与此同时，随着 Transformer[^3] 架构在视觉领域的成功应用（ViT[^2]），我们也需要重新审视这些传统任务在新架构下的表现形式。此外，理解深度神经网络内部究竟学到了什么，通过可视化手段打开黑盒，也是构建可信赖 AI 系统的关键环节。本次讲座将深入探讨这些核心任务及其背后的技术演进。&lt;/p&gt;
&lt;h3&gt;序列处理的三种范式回顾&lt;/h3&gt;
&lt;p&gt;在深入具体任务之前，我们首先回顾一下处理序列数据的三种主要方式，这有助于理解 Transformer 为何能在视觉任务中占据重要地位。循环神经网络（RNN[^4]）通过时间维度递归更新隐藏状态，理论上适合长序列，计算复杂度为 $O(N)$，但其串行计算的本质导致无法并行化，限制了训练效率。卷积神经网络（CNN[^5]）作用于多维网格，虽然可以通过堆叠层来扩大感受野，但处理长序列时需要极深的网络，且感受野的增长是有限的。&lt;/p&gt;
&lt;p&gt;相比之下，自注意力机制（Self-Attention&lt;a href=&quot;Self-Attention%EF%BC%88%E8%87%AA%E6%B3%A8%E6%84%8F%E5%8A%9B%EF%BC%89%E9%80%9A%E8%BF%87%E5%BA%8F%E5%88%97%E5%86%85%E9%83%A8%E5%85%83%E7%B4%A0%E4%B8%A4%E4%B8%A4%E4%BA%A4%E4%BA%92%E5%BB%BA%E6%A8%A1%E5%85%A8%E5%B1%80%E4%BE%9D%E8%B5%96%E3%80%82&quot;&gt;^6&lt;/a&gt;）将序列视为向量的集合。它的核心优势在于每个输出直接依赖于所有输入，拥有全局感受野，且计算过程高度并行化，仅涉及几次矩阵乘法。尽管其计算复杂度为 $O(N^2)$，在处理极长序列时显得昂贵，但其强大的建模能力和并行效率使其成为现代序列建模的首选。这种特性也被成功迁移到了视觉领域，形成了 Vision Transformer[^1] (ViT)。&lt;/p&gt;
&lt;h3&gt;Vision Transformer (ViT)：将图像视为序列&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.5xb6fwszfg.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Vision Transformer 的核心思想非常直观：将图像视为一系列补丁（patches）的序列。对于一张 $224 \times 224 \times 3$ 的输入图像，我们将其划分为 $N$ 个固定大小的补丁，例如 $16 \times 16 \times 3$。每个补丁随后被展平并通过一个线性投影层映射为 $D$ 维向量。这些向量构成了 Transformer 编码器的输入序列。&lt;/p&gt;
&lt;p&gt;由于 Transformer 本身不具备感知位置信息的能力，我们必须为每个补丁嵌入位置编码。在 ViT 中，这些位置编码通常是可学习的 $D$ 维向量，直接加到补丁嵌入向量上。为了执行分类任务，ViT 引入了一个特殊的可学习分类令牌（classification token, [CLS]），它被添加到序列的开头。经过多层 Transformer 编码器处理后，[CLS] 令牌的输出向量被送入一个线性分类头，生成最终的类别预测分数。另一种变体则是对所有补丁的输出向量进行全局平均池化，再通过线性层进行分类。值得注意的是，在图像任务中，自注意力层不需要掩码机制，因为每个图像补丁都可以关注到其他所有补丁，这与自然语言处理中的自回归生成任务截然不同。&lt;/p&gt;
&lt;h3&gt;Transformer 架构的现代演进&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.5trki8n69z.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;自 2017 年原始 Transformer 提出以来，其核心架构虽未发生根本性变化，但在细节上经历了一系列重要的改进，这些改进显著提升了模型的训练稳定性和性能。&lt;/p&gt;
&lt;p&gt;首先是归一化位置的调整。原始的 Transformer 采用“后归一化”（Post-Norm），即在残差连接之后进行层归一化（Layer Normalization）。然而，这种做法在某些情况下会导致梯度消失，使得模型难以学习恒等映射。现代架构普遍转向“前归一化”（Pre-Norm），将归一化层移至残差分支内部，即在自注意力和前馈网络之前进行归一化。这种改动虽然看似微小，却极大地增强了深层网络的训练稳定性。&lt;/p&gt;
&lt;p&gt;其次是归一化方法的革新。传统的层归一化涉及计算均值和方差，而均方根归一化（RMSNorm[^7]）去除了均值中心化步骤，仅利用均方根进行缩放。公式表达为 $y_i = \frac{x_i}{\text{RMS}(x)} \cdot \gamma_i$，其中 $\text{RMS}(x) = \sqrt{\epsilon + \frac{1}{N}\sum x_i^2}$。实验表明，RMSNorm 在保持性能的同时能略微提升训练速度及稳定性。&lt;/p&gt;
&lt;p&gt;在前馈网络（MLP）结构上，SwiGLU[^8] 激活函数逐渐取代了传统的 ReLU 或 GeLU。经典的 MLP 结构为 $Y = \sigma(XW_1)W_2$，而 SwiGLU 引入了门控机制，形式为 $Y = (\sigma(XW_1) \odot XW_2)W_3$。这种结构通过增加一个并行的线性变换路径并与激活路径相乘，显著提升了模型的表达能力。为了保持参数量不变，通常会将中间层维度调整为原来的 $2/3$ 倍左右。&lt;/p&gt;
&lt;p&gt;最后，混合专家模型（Mixture of Experts, MoE[^9]）成为了扩展模型规模的关键技术。MoE 在每个 Transformer 块中维护 $E$ 个独立的 MLP 专家网络。对于每个输入令牌，通过路由机制仅选择其中活跃的 $A$ 个专家（$A &amp;lt; E$）进行计算。这种稀疏激活策略使得模型参数量可以随专家数量 $E$ 线性增长，而计算成本仅随活跃专家数 $A$ 增加。目前最先进的大语言模型几乎都采用了 MoE 架构，实现了万亿级参数规模下的高效推理。&lt;/p&gt;
&lt;h3&gt;语义分割：像素级的分类&lt;/h3&gt;
&lt;p&gt;语义分割的目标是为图像中的每个像素分配一个语义类别标签，而不区分同一类别的不同实例。早期的尝试采用滑动窗口策略，即提取以每个像素为中心的图像块，利用 CNN 分类中心像素的类别。然而，这种方法存在严重的计算冗余，因为相邻窗口的特征大量重叠且未被共享，导致效率极低。&lt;/p&gt;
&lt;p&gt;全卷积网络（Fully Convolutional Networks, FCN[^10]）提出了更高效的解决方案。其核心思想是设计一个完全由卷积层组成的网络，去除全连接层，从而允许输入任意尺寸的图像并输出相应尺寸的特征图。为了兼顾感受野和空间分辨率，FCN 采用了编码器 - 解码器结构：编码器部分通过池化或步长卷积进行下采样，提取高层语义特征；解码器部分则通过上采样操作恢复空间分辨率。&lt;/p&gt;
&lt;p&gt;上采样操作主要有几种实现方式。最简单的是最近邻插值或“床钉式”（Bed of Nails）填充，但这些方法不可学习。最大反池化（Max Unpooling）利用前向传播时最大池化的位置索引来恢复特征图，保留了部分空间结构信息。更为常用的是转置卷积（Transposed Convolution），也称为反卷积。它可以被视为一种可学习的上采样层，通过将输入元素作为卷积核的权重，在输出特征图上生成重叠的感受野并求和，从而实现从低分辨率到高分辨率的映射。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/AggressiveYu/article/details/151256739&quot;&gt;U-Net[^11]&lt;/a&gt; 是这一领域的经典架构，其特点是跳跃连接（Skip Connections）。它将编码器阶段的高分辨率特征图与解码器阶段的上采样特征图进行拼接。这种设计不仅恢复了丢失的空间细节，还将浅层的定位信息与深层的语义信息有效融合，显著提升了分割边界的准确性。&lt;/p&gt;
&lt;h3&gt;目标检测：定位与分类的结合&lt;/h3&gt;
&lt;p&gt;目标检测任务要求模型不仅识别图像中的物体类别，还要预测其位置，通常用边界框（Bounding Box）表示。对于单目标检测，问题可以转化为多任务学习：一个分支输出类别概率（分类任务），另一个分支输出边界框坐标（回归任务），总损失为两者之和。&lt;/p&gt;
&lt;p&gt;然而，多目标检测面临输出数量不固定的挑战。早期的 R-CNN[^14] 系列算法采用了两阶段策略。第一阶段生成区域提议（Region Proposals），最初使用选择性搜索（Selective Search）等传统算法，后来演变为区域提议网络（RPN[^15]）。R-CNN 对每个提议区域独立运行 CNN 提取特征，效率低下。Fast R-CNN[^13] 对此进行了改进，先将整张图像通过 CNN 提取特征图，然后在特征图上裁剪出对应提议区域的特征（RoI Pooling[^17]），大大减少了计算量。Faster R-CNN[^12] 进一步将区域提议生成过程也神经网络化，通过 RPN 直接从特征图中预测锚框（Anchor Boxes）是否包含物体及其修正量，实现了端到端的训练。&lt;/p&gt;
&lt;p&gt;在两阶段检测器中，RoI Align[^16] 取代了 RoI Pooling 成为主流。RoI Pooling 在进行特征裁剪时会将坐标量化取整，导致特征与原始图像之间的错位，这对像素级任务（如实例分割）尤为不利。RoI Align 通过双线性插值直接采样非整数坐标点的特征值，避免了量化误差，保证了特征的空间对齐。&lt;/p&gt;
&lt;p&gt;单阶段检测器（如 YOLO[^18]、SSD[^19]）则摒弃了区域提议步骤，直接将图像划分为网格，在每个网格单元上直接预测多个边界框及其类别概率。这类方法速度极快，适合实时应用，但在小目标检测和精度上略逊于两阶段方法。近年来，基于 Transformer 的检测器（如 DETR[^20]）崭露头角，它利用 Transformer 的集合预测特性，直接输出一组边界框，通过二分图匹配（Bipartite Matching）与真实框对应，简化了检测流程，无需锚框和非极大值抑制（NMS[^21]）后处理。&lt;/p&gt;
&lt;h3&gt;实例分割：区分个体的精细划分&lt;/h3&gt;
&lt;p&gt;实例分割结合了目标检测和语义分割的特点，不仅要识别每个像素的类别，还要区分同一类别的不同个体。Mask R-CNN[^22] 是这一任务的里程碑式工作。它在 Faster R-CNN 的基础上增加了一个并行的分支，用于预测每个 RoI 的二值掩码（Mask）。具体来说，对于每个候选区域，网络除了输出类别和边界框外，还通过一个小型的全卷积网络预测一个 $28 \times 28$ 的掩码。得益于 RoI Align 的精确特征对齐，Mask R-CNN 能够生成高质量的实例分割结果，并可扩展至人体姿态估计等任务。&lt;/p&gt;
&lt;h3&gt;模型可视化与理解&lt;/h3&gt;
&lt;p&gt;理解深度神经网络的决策依据对于调试模型和建立信任至关重要。可视化技术主要分为两类：一是观察网络学到的特征表示，二是分析输入图像中哪些像素对决策贡献最大。&lt;/p&gt;
&lt;p&gt;对于卷积层滤波器的可视化，可以直接观察第一层卷积核，它们通常呈现出边缘、颜色斑点等基础纹理特征。随着层数加深，特征变得抽象，难以直接解读。此时，可以通过反向传播技术生成显著性图（Saliency Maps）。具体做法是计算类别得分关于输入像素的梯度，梯度的绝对值反映了该像素对分类结果的影响程度。为了获得更清晰的图像，引导反向传播（Guided Backprop）技术仅在反向传播过程中传递正梯度，过滤掉噪声，从而突出显示与目标类别高度相关的图像区域。&lt;/p&gt;
&lt;p&gt;类激活映射（CAM[^24]）及其变体 Grad-CAM[^23] 提供了另一种视角。CAM 利用全局平均池化层后的权重，将最后一层卷积特征图加权求和，生成热力图。然而，CAM 仅适用于特定结构的网络。Grad-CAM 对此进行了推广，它计算类别得分关于任意卷积层特征的梯度，并对梯度进行全局平均池化得到通道权重，再与特征图加权组合。这种方法无需修改网络结构，即可生成高分辨率的定位热力图，直观展示模型“关注”的图像区域。对于 Vision Transformer，类似的可视化方法也被应用于分析注意力图，揭示不同图像补丁之间的关联强度。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;从基础的图像分类到复杂的检测与分割，计算机视觉任务正朝着更精细、更全面的方向发展。Transformer 架构的引入为视觉任务带来了新的范式，而传统卷积网络在检测与分割领域的演进也展示了强大的生命力。无论是两阶段的 Faster R-CNN 还是单阶段的 YOLO，亦或是基于集合预测的 DETR，都在速度与精度之间寻找最佳平衡。同时，可视化工具的进步让我们能够更深入地洞察模型内部机制，为构建更高效、更可靠的视觉系统提供了坚实基础。未来，随着视频理解等时序任务的兴起，这些技术将进一步融合，推动人工智能在动态视觉场景中的应用。&lt;/p&gt;
&lt;p&gt;[^1]: Vision Transformer（ViT）是将图像切分为 patch 序列并用 Transformer 编码的视觉模型。&lt;/p&gt;
&lt;p&gt;[^2]: ViT 是 Vision Transformer 的缩写。&lt;/p&gt;
&lt;p&gt;[^3]: Transformer 是以自注意力机制为核心的深度学习架构，最早发表于 2017 年。&lt;/p&gt;
&lt;p&gt;[^4]: RNN（Recurrent Neural Network）是循环神经网络，适合序列建模。&lt;/p&gt;
&lt;p&gt;[^5]: CNN（Convolutional Neural Network）是卷积神经网络，常用于图像任务。&lt;/p&gt;
&lt;p&gt;[^7]: RMSNorm 是只基于均方根进行归一化的归一化方法。&lt;/p&gt;
&lt;p&gt;[^8]: SwiGLU 是一种带门控结构的激活/前馈模块变体，常用于现代大模型。&lt;/p&gt;
&lt;p&gt;[^9]: MoE（Mixture of Experts）通过稀疏路由激活部分专家网络以扩展模型容量。&lt;/p&gt;
&lt;p&gt;[^10]: FCN（Fully Convolutional Network）是全卷积网络，常用于语义分割。&lt;/p&gt;
&lt;p&gt;[^11]: U-Net 是经典编码器-解码器分割网络，特点是跳跃连接。&lt;/p&gt;
&lt;p&gt;[^12]: Faster R-CNN 是两阶段目标检测器，引入 RPN 生成候选区域。&lt;/p&gt;
&lt;p&gt;[^13]: Fast R-CNN 在共享特征图上做 RoI 特征提取，提升了 R-CNN 效率。&lt;/p&gt;
&lt;p&gt;[^14]: R-CNN 是早期两阶段检测框架，先提候选区域再分类回归。&lt;/p&gt;
&lt;p&gt;[^15]: RPN（Region Proposal Network）是用于生成候选框的区域建议网络。&lt;/p&gt;
&lt;p&gt;[^16]: RoI Align 通过插值采样避免量化误差，提升定位精度。&lt;/p&gt;
&lt;p&gt;[^17]: RoI Pooling 将候选区域映射并池化到固定尺寸特征。&lt;/p&gt;
&lt;p&gt;[^18]: YOLO（You Only Look Once）是代表性的单阶段实时检测系列。&lt;/p&gt;
&lt;p&gt;[^19]: SSD（Single Shot MultiBox Detector）是经典单阶段目标检测方法。&lt;/p&gt;
&lt;p&gt;[^20]: DETR（DEtection TRansformer）将目标检测建模为集合预测问题。&lt;/p&gt;
&lt;p&gt;[^21]: NMS（Non-Maximum Suppression）用于去除重叠冗余检测框。&lt;/p&gt;
&lt;p&gt;[^22]: Mask R-CNN 在 Faster R-CNN 基础上增加实例分割分支。&lt;/p&gt;
&lt;p&gt;[^23]: Grad-CAM 用类别梯度对特征图加权生成可解释热力图。&lt;/p&gt;
&lt;p&gt;[^24]: CAM（Class Activation Mapping）用于可视化模型关注区域。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 01 Mar 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 8: 注意力机制与 Transformer</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture7%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6%E4%B8%8Etransformer/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture7%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6%E4%B8%8Etransformer/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture7%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6%E4%B8%8Etransformer/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture7%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6%E4%B8%8Etransformer/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇是现代深度学习里非常关键的过渡节点。阅读时建议一直围绕一个问题展开：注意力机制究竟替换掉了 RNN 的哪部分限制。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 8: 注意力机制与 Transformer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;在序列建模问题中，我们希望模型能够根据上下文理解当前元素的含义。循环神经网络通过在时间维度上递归更新隐藏状态来实现这一目标，但其内部状态始终是一个固定维度向量。当输入序列很长时，早期信息必须被不断压缩并通过多次非线性变换传递到后续时刻，这使得长距离依赖难以稳定学习。&lt;/p&gt;
&lt;p&gt;一个更直接的思路是：在生成输出的每一步，不再依赖单一的压缩向量，而是直接“查看”整个输入序列，并根据当前需求选择性地聚合信息。注意力机制正是这一想法的数学化表达。它不再假设所有历史信息必须被压缩为单一状态，而是允许模型在任意时刻从整个序列中提取相关部分。&lt;/p&gt;
&lt;p&gt;从抽象角度看，注意力是一种作用在向量集合上的算子：给定一个查询向量，它会在一组数据向量中计算相关性，并据此生成加权组合。Transformer 则是在网络的每一层都使用这种算子。&lt;/p&gt;
&lt;h3&gt;注意力的基本形式&lt;/h3&gt;
&lt;p&gt;设有一个查询向量 $q \in \mathbb{R}^d$，以及一组数据向量 ${x_1, \dots, x_n}$，每个 $x_i \in \mathbb{R}^d$。注意力机制的目标是根据 $q$ 与各个 $x_i$ 的相关程度生成一个新的表示。&lt;/p&gt;
&lt;p&gt;首先计算相似度：&lt;/p&gt;
&lt;p&gt;$$
e_i = q^\top x_i.
$$&lt;/p&gt;
&lt;p&gt;为了避免高维空间中点积数值过大导致 softmax 饱和，通常进行缩放：&lt;/p&gt;
&lt;p&gt;$$
e_i = \frac{q^\top x_i}{\sqrt{d}}.
$$&lt;/p&gt;
&lt;p&gt;然后通过 softmax 将相似度转化为概率分布：&lt;/p&gt;
&lt;p&gt;$$
a_i = \frac{\exp(e_i)}{\sum_j \exp(e_j)}.
$$&lt;/p&gt;
&lt;p&gt;最终输出为加权和：&lt;/p&gt;
&lt;p&gt;$$
y = \sum_i a_i x_i.
$$&lt;/p&gt;
&lt;p&gt;直观理解是：查询向量决定“关注什么”，注意力权重刻画“关注多少”，输出则是基于重要性聚合后的结果。&lt;/p&gt;
&lt;h3&gt;Query、Key 与 Value&lt;/h3&gt;
&lt;p&gt;在实际模型中，我们不会直接在原始向量上计算相似度，而是先通过线性变换生成三种表示：&lt;/p&gt;
&lt;p&gt;$$
q = W_Q x, \quad k = W_K x, \quad v = W_V x.
$$&lt;/p&gt;
&lt;p&gt;这里&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$q$ 表示查询（Query）&lt;/li&gt;
&lt;li&gt;$k$ 表示键（Key）&lt;/li&gt;
&lt;li&gt;$v$ 表示值（Value）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;相似度在 $q$ 与 $k$ 之间计算，而输出是对 $v$ 的加权和。这种分离使模型能够在不同表示空间中分别学习“如何匹配”和“如何聚合”。&lt;/p&gt;
&lt;p&gt;将单个查询扩展到矩阵形式。若输入为矩阵 $X \in \mathbb{R}^{n \times d}$，则有&lt;/p&gt;
&lt;p&gt;$$
Q = XW_Q, \quad K = XW_K, \quad V = XW_V.
$$&lt;/p&gt;
&lt;p&gt;注意力计算变为&lt;/p&gt;
&lt;p&gt;$$
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V.
$$&lt;/p&gt;
&lt;p&gt;其中 $QK^\top$ 得到一个 $n \times n$ 的矩阵，表示每个位置对所有位置的关注程度。softmax 在行方向归一化，使每个位置形成一个对全序列的概率分布。&lt;/p&gt;
&lt;h3&gt;自注意力&lt;/h3&gt;
&lt;p&gt;当 $Q, K, V$ 都来自同一输入序列时，称为自注意力。此时，每个元素都会根据自身状态与其他所有元素的关系来更新表示：&lt;/p&gt;
&lt;p&gt;$$
Q = XW_Q, \quad K = XW_K, \quad V = XW_V.
$$&lt;/p&gt;
&lt;p&gt;新的表示为&lt;/p&gt;
&lt;p&gt;$$
Y = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V.
$$&lt;/p&gt;
&lt;p&gt;每个输出向量 $y_i$ 都是所有输入向量的加权组合，因此其表示包含全局上下文信息。&lt;/p&gt;
&lt;p&gt;自注意力具有一个重要性质：若对输入序列进行相同的排列，输出也会按相同方式排列。这意味着自注意力本质上作用在“集合”而非“有序序列”上，因此本身不包含顺序信息。&lt;/p&gt;
&lt;h3&gt;位置编码&lt;/h3&gt;
&lt;p&gt;由于自注意力无法感知顺序，必须人为注入位置信息。常见做法是为每个位置添加一个位置向量 $p_i$：&lt;/p&gt;
&lt;p&gt;$$
\tilde{x}_i = x_i + p_i.
$$&lt;/p&gt;
&lt;p&gt;位置编码可以是固定函数（如正弦余弦），也可以是可学习参数。它为模型提供关于“第几个元素”的信号，使其能够区分不同位置。&lt;/p&gt;
&lt;h3&gt;掩码机制&lt;/h3&gt;
&lt;p&gt;在自回归生成任务中，模型在预测第 $t$ 个位置时不能看到未来信息。可以在相似度矩阵中将未来位置的值替换为 $-\infty$，使 softmax 后对应权重为零。这种机制称为 masked self-attention。&lt;/p&gt;
&lt;h3&gt;多头注意力&lt;/h3&gt;
&lt;p&gt;单个注意力层在一个表示子空间中建模关系，但序列中的依赖可能具有多种类型。多头注意力通过并行运行多个注意力层，使模型在不同子空间中学习不同关系。&lt;/p&gt;
&lt;p&gt;设有 $H$ 个头，每个头维度为 $d_h = d / H$。第 $i$ 个头计算：&lt;/p&gt;
&lt;p&gt;$$
\text{head}_i =\text{Attention}(QW_i^Q, KW_i^K, VW_i^V).
$$&lt;/p&gt;
&lt;p&gt;然后将所有头的输出拼接并线性映射：&lt;/p&gt;
&lt;p&gt;$$
\text{MultiHead}(Q, K, V) =
\text{Concat}(\text{head}_1, \dots, \text{head}_H) W_O.
$$&lt;/p&gt;
&lt;p&gt;这种结构使模型能够同时捕获不同类型的依赖关系。&lt;/p&gt;
&lt;h3&gt;Transformer 的基本结构&lt;/h3&gt;
&lt;p&gt;Transformer 完全基于注意力机制构建。一个标准的 Transformer 块包含两部分：多头自注意力层和前馈网络层，每一部分都带有残差连接与归一化：&lt;/p&gt;
&lt;p&gt;$$
z_1 = \text{LayerNorm}(x + \text{MultiHead}(x)),
$$&lt;/p&gt;
&lt;p&gt;$$
z_2 = \text{LayerNorm}(z_1 + \text{FFN}(z_1)).
$$&lt;/p&gt;
&lt;p&gt;前馈网络通常为两层线性变换与非线性激活：&lt;/p&gt;
&lt;p&gt;$$
\text{FFN}(x)=\max(0, xW_1 + b_1)W_2 + b_2.
$$&lt;/p&gt;
&lt;p&gt;通过多层堆叠，模型逐渐将局部表示转化为高层语义表示。&lt;/p&gt;
&lt;h3&gt;编码器与解码器&lt;/h3&gt;
&lt;p&gt;编码器由若干自注意力与前馈层堆叠而成，负责生成上下文表示。解码器结构类似，但在自注意力中加入掩码以防止看到未来信息，并包含一个交叉注意力层，用于从编码器输出中提取相关信息。&lt;/p&gt;
&lt;p&gt;交叉注意力的形式为：&lt;/p&gt;
&lt;p&gt;$$
\text{Attention}(Q_{\text{dec}}, K_{\text{enc}}, V_{\text{enc}}).
$$&lt;/p&gt;
&lt;p&gt;这种结构使模型在生成序列时既能利用已生成内容，又能动态访问输入。&lt;/p&gt;
&lt;h3&gt;复杂度与优势&lt;/h3&gt;
&lt;p&gt;自注意力的时间复杂度为 $O(n^2)$，因为需要计算所有位置对之间的关系。尽管复杂度较高，但其优势在于完全并行计算和全局感受野。与 RNN 相比，它不再依赖顺序递归传播信息，因此训练更加高效，长距离依赖也更容易建模。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;注意力机制提供了一种新的序列建模方式：通过查询与加权求和在整个序列中动态选择相关信息。自注意力使每个元素都能与其他所有元素交互，从而获得全局上下文。Transformer 在此基础上构建，通过多层堆叠的注意力与前馈网络实现强大的表示能力。&lt;/p&gt;
&lt;p&gt;理解注意力作为“在向量集合上执行加权聚合”的本质，是理解现代序列模型的关键一步。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 22 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 7: 循环神经网络（RNN）</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture6rnn-%E6%9E%B6%E6%9E%84/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture6rnn-%E6%9E%B6%E6%9E%84/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture6rnn-%E6%9E%B6%E6%9E%84/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture6rnn-%E6%9E%B6%E6%9E%84/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇从视觉课程切到序列建模，适合把它看成“为注意力机制和 Transformer 铺路”的一讲。重点关注 RNN 为什么能处理变长输入，以及它为什么又会遇到长期依赖问题。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 7: 循环神经网络（RNN）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;卷积神经网络擅长处理具有固定空间结构的数据，如图像，但许多重要任务涉及&lt;strong&gt;变长序列&lt;/strong&gt;——视频帧、语音信号或文本词串。这些数据的本质在于其&lt;strong&gt;时间或顺序依赖性&lt;/strong&gt;：当前元素的意义往往由其上下文决定。循环神经网络（Recurrent Neural Network, RNN）为此类问题提供了一个自然的建模范式，其核心是通过一个&lt;strong&gt;内部状态&lt;/strong&gt;在时间步之间传递信息，从而将历史“记忆”融入对当前输入的理解。&lt;/p&gt;
&lt;h3&gt;RNN 的基本结构与计算&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.3rbr6d6903.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;RNN 的设计哲学源于一个朴素而强大的想法：用一个固定的计算单元，在每个时间步重复作用于新的输入和累积的历史。具体而言，给定一个长度为 $T$ 的输入序列 $(\mathbf{x}_1, \dots, \mathbf{x}_T)$，RNN 维护一个隐藏状态 $\mathbf{h}_t$，该状态在时间步 $t$ 被更新为：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{h}&lt;em&gt;t = \tanh\left( \mathbf{W}&lt;/em&gt;{hh} \mathbf{h}&lt;em&gt;{t-1} + \mathbf{W}&lt;/em&gt;{xh} \mathbf{x}_t + \mathbf{b}_h \right).
$$&lt;/p&gt;
&lt;p&gt;这里，$\mathbf{h}&lt;em&gt;{t-1}$ 编码了前 $t-1$ 个输入的信息，$\mathbf{x}&lt;em&gt;t$ 是当前时刻的观测，二者通过可学习的权重矩阵 $\mathbf{W}&lt;/em&gt;{hh}$ 和 $\mathbf{W}&lt;/em&gt;{xh}$ 投影到同一空间后相加，再经非线性激活函数 $\tanh$ 输出新的状态 $\mathbf{h}_t$。&lt;/p&gt;
&lt;p&gt;这一公式的精妙之处在于&lt;strong&gt;参数共享&lt;/strong&gt;：无论序列多长，所有时间步都使用同一组参数 ${\mathbf{W}&lt;em&gt;{hh}, \mathbf{W}&lt;/em&gt;{xh}, \mathbf{b}_h}$。这使得模型能够泛化到任意长度的序列，并极大地提升了参数效率。可以将 RNN 视作一个带有内部记忆的处理器：它在每个时刻读取新数据，并根据当前记忆和新数据共同更新其内部状态，就像人类在阅读句子时不断整合新词以形成对整体语义的理解。若需在每个时间步产生输出（如预测下一个词），只需在隐藏状态上附加一个线性层：$\mathbf{y}&lt;em&gt;t = \mathbf{W}&lt;/em&gt;{hy} \mathbf{h}_t + \mathbf{b}_y$。&lt;/p&gt;
&lt;h3&gt;训练与梯度流：BPTT 及其挑战&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.5trjuf68q0.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;训练 RNN 的标准方法是&lt;strong&gt;随时间反向传播（Backpropagation Through Time, BPTT）&lt;/strong&gt;。该算法首先将 RNN 沿时间维度展开为一个深度为 $T$ 的前馈网络，然后在此展开图上执行标准的反向传播。然而，这种展开也揭示了 Vanilla RNN 的根本缺陷：&lt;strong&gt;梯度消失与爆炸问题&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在反向传播中，从时间步 $t$ 到 $t-k$ 的梯度需要连续乘以权重矩阵 $\mathbf{W}&lt;em&gt;{hh}^\top$ 共 $k$ 次。如果 $\mathbf{W}&lt;/em&gt;{hh}$ 的特征值普遍小于 1，梯度会以指数速度衰减至零；反之则会爆炸。这导致模型难以学习跨越较长时间步的依赖关系——早期输入对后期输出的影响在梯度信号中几乎无法体现。实践中，梯度裁剪（Gradient Clipping）可缓解爆炸问题，但对于更普遍的梯度消失，必须从架构层面寻求解决方案。&lt;/p&gt;
&lt;h3&gt;LSTM：通过门控机制解决长期依赖&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.39lphs7lot.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;长短期记忆网络（LSTM）通过引入一套精巧的&lt;strong&gt;门控机制&lt;/strong&gt;，从根本上改善了信息在长时间尺度上的流动。其核心创新是分离了两个状态：一个用于快速传递信息的&lt;strong&gt;细胞状态（cell state）&lt;/strong&gt; $\mathbf{c}_t$，和一个用于与外界交互的&lt;strong&gt;隐藏状态&lt;/strong&gt; $\mathbf{h}_t$。&lt;/p&gt;
&lt;p&gt;在每个时间步，LSTM 首先计算三个门：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;遗忘门&lt;/strong&gt; $\mathbf{f}_t = \sigma(\mathbf{W}&lt;em&gt;f [\mathbf{h}&lt;/em&gt;{t-1}, \mathbf{x}_t])$ 决定从细胞状态中丢弃哪些旧信息；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输入门&lt;/strong&gt; $\mathbf{i}_t = \sigma(\mathbf{W}&lt;em&gt;i [\mathbf{h}&lt;/em&gt;{t-1}, \mathbf{x}_t])$ 控制哪些新信息被写入；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;候选细胞状态&lt;/strong&gt; $\tilde{\mathbf{c}}_t = \tanh(\mathbf{W}&lt;em&gt;c [\mathbf{h}&lt;/em&gt;{t-1}, \mathbf{x}_t])$ 提供待写入的新内容。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;细胞状态的更新公式为：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{c}_t = \mathbf{f}&lt;em&gt;t \odot \mathbf{c}&lt;/em&gt;{t-1} + \mathbf{i}_t \odot \tilde{\mathbf{c}}_t,
$$&lt;/p&gt;
&lt;p&gt;其中 $\odot$ 表示逐元素相乘。由于此操作主要是元素级的加法与乘法，而非矩阵乘法，梯度在 $\mathbf{c}&lt;em&gt;t$ 到 $\mathbf{c}&lt;/em&gt;{t-1}$ 的路径上得以近乎无损地回传，形成了一个稳定的“信息高速公路”。最后，&lt;strong&gt;输出门&lt;/strong&gt; $\mathbf{o}_t = \sigma(\mathbf{W}&lt;em&gt;o [\mathbf{h}&lt;/em&gt;{t-1}, \mathbf{x}_t])$ 决定基于当前细胞状态输出多少信息作为隐藏状态：$\mathbf{h}_t = \mathbf{o}_t \odot \tanh(\mathbf{c}_t)$。通过这种方式，LSTM 能够自主地选择记住或遗忘信息，从而有效捕获长期依赖。&lt;/p&gt;
&lt;h3&gt;RNN 的应用、权衡与现代发展&lt;/h3&gt;
&lt;p&gt;RNN 及其变体曾是序列建模的主导力量，在机器翻译、语音识别和图像描述生成等任务中取得了里程碑式的成果。其优势在于能优雅地处理变长输入，且模型复杂度与序列长度无关。然而，其固有的&lt;strong&gt;顺序计算&lt;/strong&gt;特性使其难以并行化，训练速度慢；即使有 LSTM，极长距离的依赖在实践中依然难以可靠建模。&lt;/p&gt;
&lt;p&gt;这些局限性催生了&lt;strong&gt;Transformer&lt;/strong&gt;架构，后者完全摒弃循环结构，转而依赖自注意力机制，实现了高度并行化和更强的全局建模能力。近年来，&lt;strong&gt;状态空间模型（SSMs）&lt;/strong&gt; 如 Mamba 试图融合 RNN 的线性扩展效率（$O(N)$）与 Transformer 的全局感受野，代表了序列建模范式的新探索方向。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;RNN 通过其循环连接和共享参数，为序列数据建模提供了一个概念清晰且功能强大的框架。Vanilla RNN 虽然简洁，但受困于梯度流问题；LSTM 通过门控和细胞状态的设计，巧妙地解决了长期依赖学习的难题，成为深度学习发展史上的关键一环。尽管其地位已被 Transformer 等架构部分取代，但 RNN 所蕴含的“状态演化”思想及其对序列动态的直观刻画，依然是理解现代序列模型不可或缺的基础。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sat, 14 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 6: CNN 架构、训练技巧与迁移学习</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture5cnn-%E6%9E%B6%E6%9E%84/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture5cnn-%E6%9E%B6%E6%9E%84/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture5cnn-%E6%9E%B6%E6%9E%84/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture5cnn-%E6%9E%B6%E6%9E%84/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇偏工程实践，适合在掌握 CNN 基础后回来看。阅读时可以把内容分成三块：架构演进、训练技巧、迁移学习。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 6: CNN 架构、训练技巧与迁移学习&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;构建一个成功的卷积神经网络不仅需要理解其基本构件，还需掌握一系列工程实践与设计哲学。本讲系统性地探讨了如何&lt;strong&gt;构建&lt;/strong&gt;和&lt;strong&gt;训练&lt;/strong&gt;CNN，涵盖了从权重初始化、激活函数选择到经典架构（如 VGG 和 ResNet）的演进，并深入分析了数据预处理、正则化、超参数调优以及迁移学习等关键训练策略。&lt;/p&gt;
&lt;h3&gt;激活函数：非线性的引擎&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.86u69uoo0l.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;激活函数为网络引入非线性，是其具备强大表示能力的根本。Sigmoid 函数 $\sigma(x) = 1/(1+e^{-x})$ 因其在饱和区梯度趋近于零，导致深层网络训练困难。&lt;strong&gt;ReLU（Rectified Linear Unit）&lt;/strong&gt; $f(x) = \max(0, x)$ 因其计算简单、在正区梯度恒为1，成为事实标准，显著加速了训练收敛。尽管存在“神经元死亡”的风险，但其在实践中的优越性使其被广泛采用。更平滑的变体如 &lt;strong&gt;GELU（Gaussian Error Linear Unit）&lt;/strong&gt; $f(x) = x \Phi(x)$（$\Phi$ 为标准正态累积分布函数）在某些场景下表现更佳，但计算成本更高。&lt;/p&gt;
&lt;h3&gt;经典 CNN 架构的演进&lt;/h3&gt;
&lt;p&gt;CNN 架构的发展史是一部对深度、效率与表示能力的探索史。&lt;/p&gt;
&lt;h4&gt;VGGNet&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.4jommbubsm.webp&quot; alt=&quot;&quot;&gt;
VGGNet 的核心洞见是：&lt;strong&gt;使用小尺寸卷积核（$3\times3$）堆叠可以替代大尺寸卷积核，同时获得更深的网络和更强的非线性&lt;/strong&gt;。三个连续的 $3\times3$ 卷积层具有与单个 $7\times7$ 卷积层相同的感受野（receptive field），但前者拥有更多的非线性激活（三次 ReLU vs. 一次），且参数量更少（$3 \times (3^2 C^2) = 27C^2$ vs. $7^2 C^2 = 49C^2$）。这一设计使得 VGGNet 能够构建 16 或 19 层的深度模型，在 ImageNet 上取得了显著成功。&lt;/p&gt;
&lt;p&gt;然而，简单地堆叠更多层会导致&lt;strong&gt;退化问题（Degradation Problem）&lt;/strong&gt;：更深的“普通”网络（plain network）反而比浅层网络具有更高的训练误差。这并非由过拟合引起，而是优化困难所致——随着层数增加，梯度在反向传播中逐渐消失或爆炸，使得深层难以有效训练。&lt;/p&gt;
&lt;h4&gt;ResNet（残差网络）&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.8hh0306f0j.webp&quot; alt=&quot;&quot;&gt;
ResNet 通过引入&lt;strong&gt;残差连接（skip connection）&lt;/strong&gt; 巧妙地解决了这一问题。其核心思想是让网络学习一个&lt;strong&gt;残差映射&lt;/strong&gt; $F(\mathbf{x})$，而非直接学习所需的底层映射 $H(\mathbf{x})$。一个残差块的输出定义为：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{y} = F(\mathbf{x}) + \mathbf{x},
$$&lt;/p&gt;
&lt;p&gt;其中 $F(\mathbf{x})$ 是由若干卷积层组成的子网络。这种结构使得网络在理想情况下只需将 $F(\mathbf{x})$ 学习为零，即可实现恒等映射（identity mapping），从而保证深层网络至少不会比其浅层版本表现更差。这一设计极大地缓解了梯度消失问题，使得训练上百甚至上千层的网络成为可能，引领了“深度革命”。&lt;/p&gt;
&lt;h3&gt;权重初始化：稳定训练的起点&lt;/h3&gt;
&lt;p&gt;不恰当的权重初始化会破坏信号在网络中的流动。若初始权重过小，前向传播的激活值会逐层衰减至零；若过大，则激活值会迅速爆炸。&lt;strong&gt;Kaiming/MSRA 初始化&lt;/strong&gt;为此提供了理论指导。对于使用 ReLU 激活的网络，它建议从均值为0、标准差为 $\sqrt{2 / D_{\text{in}}}$ 的高斯分布中采样权重，其中 $D_{\text{in}}$ 是输入维度。该方案能有效维持各层激活值的方差大致恒定，为稳定、高效的训练奠定了基础。&lt;/p&gt;
&lt;h3&gt;数据预处理与增强：提升泛化能力&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;数据预处理&lt;/strong&gt;是标准化输入的关键步骤。标准做法是对每个颜色通道分别计算训练集的均值 $\mu_c$ 和标准差 $\sigma_c$，然后对所有图像执行：&lt;/p&gt;
&lt;p&gt;$$
X_{:, c, :, :} \leftarrow \frac{X_{:, c, :, :} - \mu_c}{\sigma_c}.
$$&lt;/p&gt;
&lt;p&gt;这使得输入数据以零为中心并具有单位方差，有利于优化器工作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据增强（Data Augmentation）&lt;/strong&gt; 是一种强大的正则化技术，通过对训练图像施加随机变换来人为扩充数据集。常用方法包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;水平翻转&lt;/strong&gt;：适用于大多数物体类别。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;随机裁剪与缩放&lt;/strong&gt;：如 ResNet 中采用的多尺度训练策略，在 $[256, 480]$ 像素间随机选择短边长度，再裁剪出固定大小（如 $224\times224$）的区域。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;色彩抖动&lt;/strong&gt;：随机调整亮度、对比度、饱和度等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些变换在训练时引入了随机性，在测试时则通过平均多个增强版本的预测结果（如 10-crop averaging）来消除随机性，从而提升模型鲁棒性。&lt;/p&gt;
&lt;h3&gt;正则化与迁移学习&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.7axoueiuu0.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dropout&lt;/strong&gt; 是另一种重要的正则化手段。在训练时，它以概率 $p$（通常为 0.5）随机将神经元的输出置零，迫使网络学习冗余的特征表示，防止神经元间的共适应。在测试时，所有神经元都参与计算，但其输出需乘以 $p$ 以保持期望一致。&lt;/p&gt;
&lt;p&gt;当目标任务数据稀缺时，&lt;strong&gt;迁移学习（Transfer Learning）&lt;/strong&gt; 提供了高效解决方案。其标准流程分为两步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;预训练&lt;/strong&gt;：在一个大型源数据集（如 ImageNet）上训练一个通用 CNN。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;微调（Fine-tuning）&lt;/strong&gt;：将预训练模型作为起点，在目标数据集上进行进一步训练。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体策略取决于目标数据集的规模与相似度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于&lt;strong&gt;小而相似&lt;/strong&gt;的数据集，通常冻结预训练的卷积主干（backbone），仅重新训练顶部的全连接分类层。&lt;/li&gt;
&lt;li&gt;对于&lt;strong&gt;大而不同&lt;/strong&gt;的数据集，则可使用预训练权重作为良好的初始化，对整个网络进行端到端微调。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现代深度学习框架提供的“模型动物园”（Model Zoo）极大简化了这一过程，使研究者能快速利用在海量数据上预训练的强大特征提取器。&lt;/p&gt;
&lt;h3&gt;超参数调优的实用指南&lt;/h3&gt;
&lt;p&gt;高效的超参数搜索遵循一套系统化流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;验证初始损失&lt;/strong&gt;：确保损失值在合理范围内。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;过拟合小样本&lt;/strong&gt;：用极小数据集（如 10 张图）验证模型容量和实现正确性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;寻找有效学习率&lt;/strong&gt;：在完整数据集上尝试不同学习率（如 $10^{-1}$ 到 $10^{-5}$），选择能使损失在百次迭代内显著下降的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;粗粒度网格搜索&lt;/strong&gt;：在选定的学习率附近，对其他超参数（如 batch size, weight decay）进行粗略搜索。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精炼与监控&lt;/strong&gt;：基于粗搜结果进行精细搜索，并通过观察训练/验证损失与准确率曲线判断模型状态（欠拟合、过拟合或正在收敛）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;值得注意的是，&lt;strong&gt;随机搜索&lt;/strong&gt;通常比网格搜索更高效，因为它能更充分地探索重要超参数的取值空间。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;本讲全面覆盖了构建和训练现代 CNN 所需的核心知识。从 VGG 的小卷积核堆叠到 ResNet 的残差学习，架构设计不断突破深度的极限；从 Kaiming 初始化到数据增强，训练技巧确保了模型的稳定与泛化；而迁移学习则将大规模预训练的知识迁移到下游任务，成为小数据场景下的利器。这些原则与实践共同构成了深度视觉系统开发的坚实基础。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Thu, 12 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 5: 卷积神经网络（CNN）基础</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-leture4%E5%9F%BA%E4%BA%8Ecnn%E7%9A%84%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-leture4%E5%9F%BA%E4%BA%8Ecnn%E7%9A%84%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-leture4%E5%9F%BA%E4%BA%8Ecnn%E7%9A%84%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-leture4%E5%9F%BA%E4%BA%8Ecnn%E7%9A%84%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇重点回答一个很实际的问题：为什么图像任务不能简单用全连接层硬做。理解卷积层保留空间结构的动机，比死记公式更重要。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 5: 卷积神经网络（CNN）基础&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;全连接神经网络（MLP）在处理图像时存在一个根本性缺陷：它将输入图像展平为一维向量，完全&lt;strong&gt;破坏了图像固有的二维空间结构&lt;/strong&gt;。这种做法不仅忽略了像素间的局部相关性，还导致参数数量爆炸（例如，$32\times32\times3$ 的图像连接到 100 个神经元需要近百万个参数）。为解决此问题，&lt;strong&gt;卷积神经网络（Convolutional Neural Networks, CNNs）&lt;/strong&gt; 应运而生，它通过引入&lt;strong&gt;卷积层&lt;/strong&gt;和&lt;strong&gt;池化层&lt;/strong&gt;等图像专用算子，在保留空间结构的同时实现高效的局部特征提取。&lt;/p&gt;
&lt;h3&gt;从全连接到卷积：保留空间结构&lt;/h3&gt;
&lt;p&gt;全连接层对每个输出神经元都与所有输入像素相连，其权重矩阵 $\mathbf{W}$ 的尺寸为 $[\text{output_dim}, \text{input_dim}]$。对于图像，这意味着每个神经元都在学习一个覆盖整张图像的“模板”。然而，自然图像具有强烈的&lt;strong&gt;局部性&lt;/strong&gt;——一个像素的值与其邻近像素高度相关，而与远处像素关系较弱。&lt;/p&gt;
&lt;p&gt;卷积层的核心思想是&lt;strong&gt;局部连接&lt;/strong&gt;和&lt;strong&gt;权值共享&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;局部连接&lt;/strong&gt;：每个输出神经元只与输入的一个局部区域（称为&lt;strong&gt;感受野&lt;/strong&gt;）相连。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权值共享&lt;/strong&gt;：用于计算不同空间位置输出的滤波器（filter）是同一个。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这使得卷积层能够高效地检测在整个图像中任意位置出现的特定局部模式（如边缘、角点）。&lt;/p&gt;
&lt;h3&gt;卷积层详解&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.7ehas4g8iy.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4&gt;基本运算&lt;/h4&gt;
&lt;p&gt;给定一个三维输入张量 $\mathbf{X} \in \mathbb{R}^{C_{\text{in}} \times H \times W}$ 和一个三维卷积核（或滤波器）$\mathbf{K} \in \mathbb{R}^{C_{\text{in}} \times K_H \times K_W}$，卷积操作通过在输入的空间维度上滑动卷积核，并在每个位置计算&lt;strong&gt;逐元素相乘再求和&lt;/strong&gt;（即点积）来生成一个标量输出。堆叠所有输出位置，形成一个二维的&lt;strong&gt;激活图（activation map）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;若使用 $C_{\text{out}}$ 个不同的滤波器，则会得到 $C_{\text{out}}$ 个激活图，它们被堆叠成一个三维输出张量 $\mathbf{Y} \in \mathbb{R}^{C_{\text{out}} \times H&amp;#39; \times W&amp;#39;}$。&lt;/p&gt;
&lt;h4&gt;超参数与输出尺寸&lt;/h4&gt;
&lt;p&gt;卷积层的行为由以下超参数控制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;滤波器数量（$C_{\text{out}}$）&lt;/strong&gt;：决定输出的通道数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;滤波器大小（$K_H, K_W$）&lt;/strong&gt;：通常取奇数（如 3x3, 5x5），以便有明确的中心。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步幅（Stride, $S$）&lt;/strong&gt;：滤波器每次滑动的像素数。$S&amp;gt;1$ 可用于下采样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零填充（Padding, $P$）&lt;/strong&gt;：在输入边界周围添加零值，以控制输出尺寸。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;输出的空间尺寸 $H&amp;#39;$ 和 $W&amp;#39;$ 由下式精确给出：&lt;/p&gt;
&lt;p&gt;$$
H&amp;#39; = \frac{H - K_H + 2P}{S} + 1, \quad W&amp;#39; = \frac{W - K_W + 2P}{S} + 1.
$$&lt;/p&gt;
&lt;p&gt;一个常见设置是“相同填充”（Same Padding）：$P = (K - 1)/2$（当 $K$ 为奇数时），此时若 $S=1$，则输出尺寸与输入尺寸相同。&lt;/p&gt;
&lt;h4&gt;参数效率&lt;/h4&gt;
&lt;p&gt;卷积层的参数数量为 $(K_H \times K_W \times C_{\text{in}} + 1) \times C_{\text{out}}$（+1 为偏置项）。与全连接层相比，这是一个巨大的缩减。例如，一个 $3\times3$ 卷积核作用于 $32\times32\times3$ 输入并产生 64 个输出通道，仅需 $(3\times3\times3+1)\times64 = 1792$ 个参数，而全连接层则需要 $3072 \times (32\times32\times64) \approx 190M$ 个参数。&lt;/p&gt;
&lt;h3&gt;池化层：平移不变性与降维&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.7axoueodq5.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;池化层（Pooling Layer）是另一种关键的图像专用算子，主要用于&lt;strong&gt;降低特征图的空间维度&lt;/strong&gt;，从而减少计算量和参数数量，并提供一定程度的&lt;strong&gt;平移不变性（Translation Invariance）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;最常见的池化操作是&lt;strong&gt;最大池化（Max Pooling）&lt;/strong&gt;。它在一个局部窗口（如 $2\times2$）内选取最大值作为输出。例如，对一个 $4\times4$ 的单通道输入进行 $2\times2$、步幅为 2 的最大池化，会得到一个 $2\times2$ 的输出。&lt;/p&gt;
&lt;p&gt;池化操作没有可学习参数，其超参数包括池化窗口大小和步幅。一个标准配置是 $2\times2$ 窗口、步幅为 2，这能将空间尺寸减半，面积减少为原来的四分之一。&lt;/p&gt;
&lt;p&gt;平移不变性的直观解释是：只要一个特征（如一个角点）出现在池化窗口内的任意位置，它都会被保留下来，因此模型对小的平移扰动不敏感。&lt;/p&gt;
&lt;h3&gt;卷积的平移等变性&lt;/h3&gt;
&lt;p&gt;卷积操作具有&lt;strong&gt;平移等变性（Translation Equivariance）&lt;/strong&gt;。形式化地，令 $T$ 为一个平移操作，则有：&lt;/p&gt;
&lt;p&gt;$$
\text{Conv}(T(\mathbf{X})) = T(\text{Conv}(\mathbf{X})).
$$&lt;/p&gt;
&lt;p&gt;这意味着，如果我们将输入图像平移，其对应的特征图也会发生相同的平移。这一性质保证了卷积网络能够一致地响应图像中的模式，无论其出现在何处。池化操作也具有同样的性质。&lt;/p&gt;
&lt;h3&gt;CNN 架构与历史演进&lt;/h3&gt;
&lt;p&gt;一个典型的早期 CNN 架构遵循 &lt;strong&gt;&lt;code&gt;[CONV -&amp;gt; ReLU -&amp;gt; POOL]? -&amp;gt; FC&lt;/code&gt;&lt;/strong&gt; 的模式，即交替堆叠若干卷积-激活-池化块，最后接一个或多个全连接层进行分类。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LeNet (1998)&lt;/strong&gt;：首个成功应用的 CNN，用于手写数字识别。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AlexNet (2012)&lt;/strong&gt;：在 ImageNet 竞赛中取得突破性胜利，标志着深度学习时代的开启。其关键创新包括使用 ReLU 激活函数、Dropout 正则化和 GPU 加速训练。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自 AlexNet 起至约 2020 年，CNN 主导了几乎所有计算机视觉任务。然而，近年来，&lt;strong&gt;Vision Transformer (ViT)&lt;/strong&gt; 等基于注意力机制的架构开始挑战 CNN 的地位，但 CNN 的基本构件（卷积、池化）及其蕴含的归纳偏置（局部性、平移等变性）仍然是理解现代视觉模型的重要基石。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;卷积神经网络通过引入卷积层和池化层，巧妙地利用了图像数据的二维结构特性。卷积层通过局部连接和权值共享，高效地提取局部空间特征；池化层则通过降维和平移不变性增强了模型的鲁棒性。二者共同构成了一个强大的特征提取前端，为后续的分类或检测任务提供了高质量的表示。尽管架构在不断演进，CNN 的核心思想依然是计算机视觉领域不可或缺的基础知识。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Wed, 11 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 2: 图像分类与线性分类器</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture1%E7%BA%BF%E6%80%A7%E5%88%86%E7%B1%BB%E5%99%A8/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture1%E7%BA%BF%E6%80%A7%E5%88%86%E7%B1%BB%E5%99%A8/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture1%E7%BA%BF%E6%80%A7%E5%88%86%E7%B1%BB%E5%99%A8/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture1%E7%BA%BF%E6%80%A7%E5%88%86%E7%B1%BB%E5%99%A8/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇适合当作 `CS231n` 的真正起点来读，核心是理解“从像素到类别”的第一层建模方式，以及线性分类器为什么既重要又不够。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 2: 图像分类与线性分类器&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;图像分类是计算机视觉的基础任务，其目标是为输入图像分配一个预定义的语义类别标签。尽管对人类而言该任务近乎直觉，但对计算机而言却极具挑战：图像在底层仅表示为高维像素张量（如 $800 \times 600 \times 3$ 的 RGB 值），而语义信息需从中抽象得出。这一从原始像素到高层语义的映射困难，被称为“语义鸿沟”。&lt;/p&gt;
&lt;h3&gt;图像分类的挑战&lt;/h3&gt;
&lt;p&gt;实际场景中，同一类别的视觉表现存在巨大变异。典型因素包括视角变化、光照条件、背景杂乱、遮挡、非刚性形变、类内差异以及上下文依赖。这些因素导致相同语义内容在像素空间中可能相距甚远，使得基于手工规则或像素级相似性的方法难以奏效。&lt;/p&gt;
&lt;h3&gt;数据驱动范式&lt;/h3&gt;
&lt;p&gt;为应对上述挑战，现代方法采用数据驱动的学习范式：给定一个带标签的数据集 $\mathcal{D} = {(\mathbf{x}^{(i)}, y^{(i)})}_{i=1}^N$，算法从数据中自动学习映射函数 $f: \mathbf{x} \mapsto y$。该范式摒弃了硬编码规则，转而依赖大量标注样本以归纳泛化能力。&lt;/p&gt;
&lt;h3&gt;K近邻分类器&lt;/h3&gt;
&lt;p&gt;K近邻（k-Nearest Neighbors, kNN）是最简单的非参数分类器。其训练阶段仅存储全部训练样本；预测时，对测试样本 $\mathbf{x}$，计算其与所有训练样本的距离，选取最近的 $K$ 个邻居，并通过多数投票决定类别。&lt;/p&gt;
&lt;p&gt;常用距离度量包括 L1 距离：&lt;/p&gt;
&lt;p&gt;$$
d_1(\mathbf{x}, \mathbf{x}&amp;#39;) = \sum_i |x_i - x&amp;#39;_i|,
$$&lt;/p&gt;
&lt;p&gt;和 L2 距离：&lt;/p&gt;
&lt;p&gt;$$
d_2(\mathbf{x}, \mathbf{x}&amp;#39;) = \sqrt{\sum_i (x_i - x&amp;#39;_i)^2}.
$$&lt;/p&gt;
&lt;p&gt;尽管概念直观，kNN 存在显著缺陷：推理复杂度为 $O(N)$，难以扩展；在高维空间（如 CIFAR-10 的 3072 维）中受“维度灾难”影响，距离度量失去判别性；更重要的是，像素级距离对语义无关的扰动（如平移、微小形变）极为敏感，无法反映真实语义相似性。因此，kNN 主要用于教学目的，而非实际系统。&lt;/p&gt;
&lt;h3&gt;超参数选择与验证集&lt;/h3&gt;
&lt;p&gt;kNN 的性能依赖超参数 $K$ 和距离度量的选择。为避免在训练集上过拟合（如 $K=1$ 时训练准确率恒为 100%）或污染测试集，标准做法是将原始训练集划分为训练子集与验证子集。超参数在验证集上进行调优，最终模型在独立测试集上评估。对于小规模数据，可采用交叉验证以获得更稳健的估计。&lt;/p&gt;
&lt;h3&gt;线性分类器&lt;/h3&gt;
&lt;p&gt;为克服 kNN 的局限，参数化模型被引入。线性分类器通过可学习参数实现高效泛化。设输入图像 $\mathbf{x} \in \mathbb{R}^D$（通常展平为向量），权重矩阵 $\mathbf{W} \in \mathbb{R}^{C \times D}$，偏置 $\mathbf{b} \in \mathbb{R}^C$，则分类得分由下式给出：&lt;/p&gt;
&lt;p&gt;$$
f(\mathbf{x}; \mathbf{W}, \mathbf{b}) = \mathbf{W} \mathbf{x} + \mathbf{b}.
$$&lt;/p&gt;
&lt;p&gt;每一行 $\mathbf{w}_j^\top$ 可视为类别 $j$ 的模板，分类即计算输入与各模板的点积相似度，并选择得分最高的类别。&lt;/p&gt;
&lt;p&gt;该模型将整个训练集的知识压缩至 $C \times D$ 个参数中，推理仅需一次矩阵乘法，效率极高。然而，其决策边界为线性超平面，无法处理线性不可分问题（如异或分布），限制了表达能力。尽管如此，线性分类器构成了后续非线性模型（如神经网络）的基础模块。&lt;/p&gt;
&lt;h3&gt;损失函数与优化目标&lt;/h3&gt;
&lt;p&gt;为学习参数 $\mathbf{W}$ 和 $\mathbf{b}$，需定义损失函数以量化预测误差。常见选择包括支持向量机（SVM）的合页损失与 Softmax 分类器的交叉熵损失。学习过程转化为如下优化问题：&lt;/p&gt;
&lt;p&gt;$$
\min_{\mathbf{W}, \mathbf{b}} \frac{1}{N} \sum_{i=1}^N \mathcal{L}(f(\mathbf{x}^{(i)}; \mathbf{W}, \mathbf{b}), y^{(i)}) + \lambda R(\mathbf{W}),
$$&lt;/p&gt;
&lt;p&gt;其中 $R(\cdot)$ 为正则项，$\lambda$ 控制正则强度。该优化框架是深度学习的核心机制。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 08 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 3: 正则化与优化</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture2%E6%AD%A3%E5%88%99%E5%8C%96%E4%B8%8E%E4%BC%98%E5%8C%96%E5%99%A8/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture2%E6%AD%A3%E5%88%99%E5%8C%96%E4%B8%8E%E4%BC%98%E5%8C%96%E5%99%A8/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture2%E6%AD%A3%E5%88%99%E5%8C%96%E4%B8%8E%E4%BC%98%E5%8C%96%E5%99%A8/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture2%E6%AD%A3%E5%88%99%E5%8C%96%E4%B8%8E%E4%BC%98%E5%8C%96%E5%99%A8/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇可以和损失函数、梯度下降一起看。阅读时建议重点区分“防过拟合”的正则化思路和“怎么更新参数”的优化器思路。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 3: 正则化与优化&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;训练一个深度视觉模型本质上是在高维非凸损失景观中寻找一个泛化良好的低谷。这一过程由两个关键机制驱动：&lt;strong&gt;正则化&lt;/strong&gt;控制模型复杂度以避免过拟合，&lt;strong&gt;优化器&lt;/strong&gt;则决定如何高效、稳定地穿越参数空间。本讲深入剖析 L1/L2 正则化的几何直觉，并系统梳理主流优化器的设计动机与行为特性。&lt;/p&gt;
&lt;h3&gt;损失函数的结构&lt;/h3&gt;
&lt;p&gt;完整的训练目标由数据损失与正则化项共同构成：&lt;/p&gt;
&lt;p&gt;$$
\mathcal{L}(\mathbf{W}) = \frac{1}{N} \sum_{i=1}^N \mathcal{L}_i(f(\mathbf{x}^{(i)}; \mathbf{W}), y^{(i)}) + \lambda R(\mathbf{W}),
$$&lt;/p&gt;
&lt;p&gt;其中第一项驱使模型拟合观测数据，第二项 $R(\mathbf{W})$ 对参数 $\mathbf{W}$ 施加先验约束，超参数 $\lambda$ 平衡拟合能力与泛化能力。&lt;/p&gt;
&lt;h3&gt;L1 与 L2 正则化的几何直觉&lt;/h3&gt;
&lt;p&gt;正则化可视为在参数空间中引入偏好区域。L1 和 L2 正则化对应不同的几何形状，从而引导优化走向不同类型的解。&lt;/p&gt;
&lt;p&gt;L2 正则化（权重衰减）定义为 $R(\mathbf{W}) = |\mathbf{W}|_2^2$。其等高线是围绕原点的超球面。当优化器在数据损失的等高线与 L2 球面之间寻找首次接触点时，该点通常位于所有坐标轴方向上均有非零分量的位置。因此，L2 正则化倾向于产生&lt;strong&gt;小而分散&lt;/strong&gt;的权重，避免任何单个参数主导预测。这种“平滑”解在图像任务中表现优异，因为它抑制了对特定像素或特征的过度依赖，提升了鲁棒性。&lt;/p&gt;
&lt;p&gt;L1 正则化定义为 $R(\mathbf{W}) = |\mathbf{W}|_1$，其等高线是尖角的超立方体（如二维中的菱形）。由于尖角位于坐标轴上，优化过程更容易在这些顶点处与数据损失等高线相切，从而导致部分权重被精确压缩至零。这种&lt;strong&gt;稀疏性&lt;/strong&gt;在特征选择场景中非常有用，但在卷积神经网络等密集连接的视觉模型中，参数稀疏性并非主要目标，且可能损害表示能力，故 L1 在实践中较少使用。&lt;/p&gt;
&lt;p&gt;值得注意的是，L2 正则化不仅提升泛化，还能改善优化动态：通过限制权重增长，它使损失曲面更加平滑，梯度变化更稳定。&lt;/p&gt;
&lt;h3&gt;优化器的演进：从基础到自适应&lt;/h3&gt;
&lt;h4&gt;随机梯度下降（SGD）&lt;/h4&gt;
&lt;p&gt;SGD 是优化的基石。它通过小批量数据估计梯度：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{g}&lt;em&gt;t = \nabla&lt;/em&gt;{\mathbf{W}} \mathcal{L}(\mathcal{B}&lt;em&gt;t), \quad \mathbf{W}&lt;/em&gt;{t+1} = \mathbf{W}_t - \alpha \mathbf{g}_t,
$$&lt;/p&gt;
&lt;p&gt;其中 $\alpha$ 为学习率。SGD 的更新方向是局部梯度的无偏估计，但高方差使其路径充满噪声，在病态曲率区域（如“峡谷”地形）会剧烈振荡，收敛缓慢。&lt;/p&gt;
&lt;h4&gt;动量法（Momentum）&lt;/h4&gt;
&lt;p&gt;动量法借鉴物理学中的惯性概念，引入速度变量 $\mathbf{v}_t$ 累积历史梯度：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{v}&lt;em&gt;t = \rho \mathbf{v}&lt;/em&gt;{t-1} + \mathbf{g}&lt;em&gt;t, \quad \mathbf{W}&lt;/em&gt;{t+1} = \mathbf{W}_t - \alpha \mathbf{v}_t.
$$&lt;/p&gt;
&lt;p&gt;其中 $\rho \in [0,1)$ 是动量系数（常取 0.9）。这相当于给参数更新增加了“惯性”：在一致方向上加速前进，在振荡方向上相互抵消。直观上，动量帮助优化器“滚下山坡”而非“来回弹跳”，显著加速收敛并提升稳定性。&lt;/p&gt;
&lt;h4&gt;RMSProp：自适应学习率&lt;/h4&gt;
&lt;p&gt;不同参数的梯度尺度可能差异巨大（如某些滤波器权重更新频繁，另一些则几乎静止）。固定学习率难以兼顾。RMSProp 为每个参数维护独立的学习率，通过缩放梯度来平衡更新幅度：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{r}&lt;em&gt;t = \gamma \mathbf{r}&lt;/em&gt;{t-1} + (1 - \gamma) \mathbf{g}&lt;em&gt;t^2, \quad \mathbf{W}&lt;/em&gt;{t+1} = \mathbf{W}_t - \frac{\alpha}{\sqrt{\mathbf{r}_t} + \epsilon} \mathbf{g}_t.
$$&lt;/p&gt;
&lt;p&gt;这里 $\mathbf{r}_t$ 是梯度平方的指数移动平均（EMA），$\gamma$ 常取 0.99。若某参数近期梯度较大，则 $\mathbf{r}_t$ 增大，其有效学习率自动减小；反之则增大。这使得优化器能自适应地处理不同尺度的参数。&lt;/p&gt;
&lt;h4&gt;Adam：融合动量与自适应&lt;/h4&gt;
&lt;p&gt;Adam（Adaptive Moment Estimation）结合了动量与 RMSProp 的思想。它同时维护梯度的一阶矩（均值）$\mathbf{m}_t$ 和二阶矩（未中心化方差）$\mathbf{r}_t$：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\mathbf{m}&lt;em&gt;t &amp;amp;= \beta_1 \mathbf{m}&lt;/em&gt;{t-1} + (1 - \beta_1) \mathbf{g}_t, \
\mathbf{r}&lt;em&gt;t &amp;amp;= \beta_2 \mathbf{r}&lt;/em&gt;{t-1} + (1 - \beta_2) \mathbf{g}_t^2.
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;由于 $\mathbf{m}_t$ 和 $\mathbf{r}_t$ 初始为零，早期估计存在偏差。Adam 通过偏差校正得到无偏估计：&lt;/p&gt;
&lt;p&gt;$$
\hat{\mathbf{m}}_t = \frac{\mathbf{m}_t}{1 - \beta_1^t}, \quad \hat{\mathbf{r}}_t = \frac{\mathbf{r}_t}{1 - \beta_2^t}.
$$&lt;/p&gt;
&lt;p&gt;最终更新为：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{W}_{t+1} = \mathbf{W}_t - \frac{\alpha}{\sqrt{\hat{\mathbf{r}}_t} + \epsilon} \hat{\mathbf{m}}_t.
$$&lt;/p&gt;
&lt;p&gt;Adam 的直觉是：既利用动量平滑方向，又根据历史梯度大小自适应调整步长。其默认超参数（$\beta_1=0.9, \beta_2=0.999$）在大量任务上表现稳健，使其成为深度学习的事实标准。&lt;/p&gt;
&lt;h4&gt;AdamW：正确的权重衰减&lt;/h4&gt;
&lt;p&gt;一个关键但常被忽视的细节是：标准 Adam 实现通常将 L2 正则化项 $\lambda \mathbf{W}$ 直接加入梯度 $\mathbf{g}_t$ 中。然而，在自适应学习率的框架下，这并不等价于在原始参数空间中执行权重衰减。具体而言，自适应缩放会扭曲正则化强度，导致不同参数受到不一致的惩罚。&lt;/p&gt;
&lt;p&gt;AdamW 修正了这一问题，将权重衰减操作与梯度更新解耦：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{W}_{t+1} = \mathbf{W}_t - \alpha \left( \frac{\hat{\mathbf{m}}_t}{\sqrt{\hat{\mathbf{r}}_t} + \epsilon} + \lambda \mathbf{W}_t \right).
$$&lt;/p&gt;
&lt;p&gt;等价地写作：&lt;/p&gt;
&lt;p&gt;$$
\mathbf{W}_{t+1} = (1 - \alpha \lambda) \mathbf{W}_t - \alpha \frac{\hat{\mathbf{m}}_t}{\sqrt{\hat{\mathbf{r}}_t} + \epsilon}.
$$&lt;/p&gt;
&lt;p&gt;这确保了权重衰减以统一的方式作用于所有参数，无论其梯度历史如何。大量实验表明，AdamW 不仅在理论上更干净，在实践中也 consistently 提升泛化性能，尤其在大规模训练中。&lt;/p&gt;
&lt;h3&gt;学习率调度策略&lt;/h3&gt;
&lt;p&gt;学习率 $\alpha$ 控制每次更新的步长，是影响训练成败的最关键超参数。固定学习率往往无法兼顾初期快速下降与后期精细收敛的需求，因此常采用调度策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步进衰减（Step Decay）&lt;/strong&gt;：在预设轮次（如每30 epoch）将学习率乘以衰减因子（如0.1）。简单有效，但需手动设定衰减点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;余弦退火（Cosine Annealing）&lt;/strong&gt;：学习率按余弦函数从初始值平滑降至零：
$$
\alpha_t = \frac{\alpha_0}{2} \left(1 + \cos\left(\pi \frac{t}{T}\right)\right),
$$
其中 $T$ 为总训练步数。该策略提供平滑的退火过程，常与重启（restart）结合使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;线性预热（Linear Warmup）&lt;/strong&gt;：在训练初期（如前5%的迭代），将学习率从零线性增加至目标值。这有助于稳定大批次训练的初始阶段，避免因梯度估计不准导致的发散。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;正则化与优化是深度学习训练的双引擎。L2 正则化通过鼓励小而均匀的权重提升泛化能力，其几何直觉源于超球面约束；L1 虽诱导稀疏性，但在视觉任务中应用有限。在优化器方面，从 SGD 到 AdamW 的演进反映了对损失景观复杂性的逐步应对：动量处理方向噪声，RMSProp 处理尺度差异，Adam 融合二者，而 AdamW 则修正了正则化实现的理论缺陷。对于大多数现代视觉任务，&lt;strong&gt;AdamW 配合余弦退火学习率调度&lt;/strong&gt;已成为强健且高效的默认选择。理解这些工具背后的直觉，是进行有效模型调优的前提。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 08 Feb 2026 00:00:00 GMT</pubDate></item><item><title>CS231n Lecture 4: 神经网络与反向传播</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture3%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E4%B8%8E%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture3%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E4%B8%8E%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture3%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E4%B8%8E%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n-lecture3%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E4%B8%8E%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇是从线性模型跨到深度学习的关键一讲。建议优先抓住“非线性表达能力”和“链式法则如何支持训练”这两条主线。
&lt;/Info&gt;

&lt;h2&gt;CS231n Lecture 4: 神经网络与反向传播&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs231n.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;引言&lt;/h3&gt;
&lt;p&gt;线性分类器虽然简洁高效，但其固有的局限性——只能学习线性决策边界——使其无法应对现实世界中普遍存在的复杂、非线性模式。为突破这一限制，我们引入&lt;strong&gt;神经网络&lt;/strong&gt;，一种通过堆叠多个线性变换与非线性激活函数构成的通用函数逼近器。本讲将阐述神经网络的基本架构，并重点剖析其训练的核心：&lt;strong&gt;反向传播（Backpropagation）&lt;/strong&gt; 算法。&lt;/p&gt;
&lt;h3&gt;从线性分类器到神经网络&lt;/h3&gt;
&lt;p&gt;一个标准的线性分类器可表示为 $f(\mathbf{x}) = \mathbf{W} \mathbf{x} + \mathbf{b}$。为了增加模型的表达能力，我们可以在其前插入一个或多个中间计算层。一个两层神经网络（或称单隐藏层网络）的形式如下：&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\mathbf{h} &amp;amp;= \text{ReLU}(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1), \
\mathbf{s} &amp;amp;= \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2,
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\mathbf{h}$ 是隐藏层的激活值，$\text{ReLU}(z) = \max(0, z)$ 是&lt;strong&gt;激活函数&lt;/strong&gt;。这种结构被称为&lt;strong&gt;全连接网络（Fully-Connected Network）&lt;/strong&gt; 或&lt;strong&gt;多层感知机（MLP）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;关键在于，若没有非线性激活函数（即 $\mathbf{h} = \mathbf{W}_1 \mathbf{x} + \mathbf{b}_1$），整个网络将退化为一个简单的线性映射：$\mathbf{s} = \mathbf{W}_2 (\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) + \mathbf{b}_2 = (\mathbf{W}_2 \mathbf{W}_1) \mathbf{x} + (\mathbf{W}_2 \mathbf{b}_1 + \mathbf{b}_2)$。无论堆叠多少层，其表达能力都等同于单层线性分类器。因此，&lt;strong&gt;非线性激活函数是神经网络具备强大表示能力的根本原因&lt;/strong&gt;，它使得网络能够学习复杂的特征层次和决策边界。&lt;/p&gt;
&lt;h3&gt;激活函数的选择&lt;/h3&gt;
&lt;p&gt;激活函数负责在网络中引入非线性。历史上曾使用 Sigmoid ($\sigma(z) = 1/(1+e^{-z})$) 和 Tanh 函数，但它们在深度网络中易导致梯度消失问题。现代神经网络几乎普遍采用 &lt;strong&gt;ReLU（Rectified Linear Unit）&lt;/strong&gt; 作为默认激活函数：&lt;/p&gt;
&lt;p&gt;$$
\text{ReLU}(z) = \max(0, z).
$$&lt;/p&gt;
&lt;p&gt;ReLU 计算简单，且在正区间的梯度恒为 1，有效缓解了梯度消失问题，极大地促进了深度网络的训练。尽管存在“神经元死亡”（输出恒为零）的潜在风险，但其在实践中的优异表现使其成为首选。&lt;/p&gt;
&lt;h3&gt;网络架构与容量&lt;/h3&gt;
&lt;p&gt;神经网络的架构由其层数和每层的神经元数量（即宽度）决定。增加层数（深度）或每层的神经元数（宽度）会提升模型的&lt;strong&gt;容量（Capacity）&lt;/strong&gt;，即拟合复杂函数的能力。然而，更大的容量也意味着更高的过拟合风险。因此，网络规模不应作为主要的正则化手段；应优先使用如 L2 正则化、Dropout 等显式正则化技术来控制泛化误差。&lt;/p&gt;
&lt;h3&gt;反向传播：高效梯度计算&lt;/h3&gt;
&lt;p&gt;训练神经网络需要计算损失函数 $\mathcal{L}$ 关于所有参数（如 $\mathbf{W}_1, \mathbf{W}_2$）的梯度。对于包含成千上万个参数的复杂网络，手动推导解析梯度不切实际。&lt;strong&gt;反向传播&lt;/strong&gt;提供了一种高效、系统化的解决方案。&lt;/p&gt;
&lt;p&gt;反向传播的本质是&lt;strong&gt;链式法则（Chain Rule）&lt;/strong&gt; 在计算图上的递归应用。任何复杂的函数都可以分解为一系列基本运算（如加法、乘法、函数应用），这些运算构成一个&lt;strong&gt;计算图（Computational Graph）&lt;/strong&gt;。反向传播通过一次从输出到输入的反向遍历，高效地计算出损失对所有中间变量和参数的梯度。&lt;/p&gt;
&lt;p&gt;考虑一个简单函数 $f(x, y, z) = (x + y) z$。其计算图包含两个节点：$q = x + y$ 和 $f = q z$。假设我们已知上游梯度 $\partial \mathcal{L} / \partial f$，反向传播首先计算局部梯度 $\partial f / \partial q = z$ 和 $\partial f / \partial z = q$，然后利用链式法则得到：&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial \mathcal{L}}{\partial q} = \frac{\partial \ \mathcal{L}}{\partial f} \frac{\partial f}{\partial q}, \quad \frac{\partial \mathcal{L}}{\partial z} = \frac{\partial \mathcal{L}}{\partial f} \frac{\partial f}{\partial z}.
$$&lt;/p&gt;
&lt;p&gt;接着，将 $\partial \mathcal{L} / \partial q$ 作为上游梯度传递给 $q = x + y$ 节点，计算 $\partial \mathcal{L} / \partial x$ 和 $\partial \mathcal{L} / \partial y$。这个过程可以推广到任意复杂的计算图。&lt;/p&gt;
&lt;h3&gt;向量与矩阵的反向传播&lt;/h3&gt;
&lt;p&gt;在神经网络中，变量通常是向量或矩阵。例如，对于矩阵乘法 $\mathbf{Y} = \mathbf{X} \mathbf{W}$，我们需要计算 $\partial \mathcal{L} / \partial \mathbf{X}$ 和 $\partial \mathcal{L} / \partial \mathbf{W}$。直接构造雅可比矩阵（Jacobian）在高维下内存消耗巨大（例如，对于 $64 \times 4096$ 的矩阵，雅可比矩阵可能占用数百GB内存）。反向传播的精妙之处在于，它通过&lt;strong&gt;隐式&lt;/strong&gt;的矩阵运算直接计算梯度，而无需显式构造雅可比矩阵。&lt;/p&gt;
&lt;p&gt;对于 $\mathbf{Y} = \mathbf{X} \mathbf{W}$，给定上游梯度 $\partial \mathcal{L} / \partial \mathbf{Y}$，其梯度公式为：&lt;/p&gt;
&lt;p&gt;$$
\frac{\partial \mathcal{L}}{\partial \mathbf{X}} = \frac{\partial \mathcal{L}}{\partial \mathbf{Y}} \mathbf{W}^\top, \quad \frac{\partial \mathcal{L}}{\partial \mathbf{W}} = \mathbf{X}^\top \frac{\partial \mathcal{L}}{\partial \mathbf{Y}}.
$$&lt;/p&gt;
&lt;p&gt;这些公式的正确性可以通过维度匹配直观验证，它们是深度学习框架（如 PyTorch、TensorFlow）自动微分系统的核心。&lt;/p&gt;
&lt;h3&gt;实现模式：模块化与自动微分&lt;/h3&gt;
&lt;p&gt;现代深度学习库采用&lt;strong&gt;模块化&lt;/strong&gt;设计。每个基本操作（如线性层、ReLU、Sigmoid）都被实现为一个具有 &lt;code&gt;forward&lt;/code&gt; 和 &lt;code&gt;backward&lt;/code&gt; 方法的模块。&lt;code&gt;forward&lt;/code&gt; 方法执行前向计算并缓存必要的中间变量；&lt;code&gt;backward&lt;/code&gt; 方法接收上游梯度，并利用缓存的变量计算并返回下游梯度。通过组合这些模块，可以构建任意复杂的网络，并由框架自动完成整个反向传播过程。这种设计将复杂的全局梯度计算分解为一系列简单的局部梯度计算，极大地简化了模型开发。&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;神经网络通过堆叠线性层与非线性激活函数，构建了强大的非线性函数逼近能力。ReLU 激活函数因其简单性和有效性成为标准选择。而反向传播算法，则是训练这些复杂模型的基石，它通过在计算图上高效地应用链式法则，使得计算数百万甚至数十亿参数的梯度成为可能。理解反向传播不仅是掌握深度学习的关键，也为后续学习卷积神经网络等更高级架构奠定了坚实基础。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 08 Feb 2026 00:00:00 GMT</pubDate></item><item><title>cs224R-Lecture 3 Policy Gradients</title><link>https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture2%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture2%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6/</guid><description>cs224R</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture2%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6/&quot;&gt;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture2%E7%AD%96%E7%95%A5%E6%A2%AF%E5%BA%A6/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇开始真正进入在线强化学习。阅读时建议重点抓住“为什么需要策略梯度”以及“它和模仿学习在数据来源上有什么根本区别”。
&lt;/Info&gt;

&lt;h2&gt;Lecture 3: Policy Gradients&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs224r.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;0. 从模仿学习到强化学习：为什么需要在线学习？&lt;/h3&gt;
&lt;p&gt;在上一讲中，我们看到模仿学习（Imitation Learning）能够利用专家示范数据快速获得一个不错的策略。但它有两个根本限制：第一，它无法超越专家的表现；第二，它不能通过与环境的交互进行自我改进。&lt;/p&gt;
&lt;p&gt;如果我们没有专家数据，或者希望策略比专家更强，就必须回到强化学习的核心范式：&lt;strong&gt;让智能体通过试错，直接优化累计奖励&lt;/strong&gt;。这就引出了本讲的主题——策略梯度（Policy Gradient）方法。&lt;/p&gt;
&lt;p&gt;策略梯度是第一类真正意义上的&lt;strong&gt;在线强化学习算法&lt;/strong&gt;：它不需要专家示范，而是通过不断与环境交互、收集自己的经验，并据此更新策略，以最大化期望总回报。&lt;/p&gt;
&lt;h3&gt;1. 问题设定与目标函数&lt;/h3&gt;
&lt;p&gt;我们考虑一个马尔可夫决策过程（MDP），其轨迹（trajectory）定义为状态和动作的交替序列：&lt;/p&gt;
&lt;p&gt;$$
\tau = (s_1, a_1, s_2, a_2, \dots, s_T, a_T)
$$&lt;/p&gt;
&lt;p&gt;策略 $\pi_\theta(a|s)$ 是一个由参数 $\theta$ 决定的概率分布。轨迹 $\tau$ 在策略 $\pi_\theta$ 下出现的概率为：&lt;/p&gt;
&lt;p&gt;$$
p_\theta(\tau) = p(s_1) \prod_{t=1}^{T} \pi_\theta(a_t | s_t) p(s_{t+1} | s_t, a_t)
$$&lt;/p&gt;
&lt;p&gt;我们的目标是找到一组参数 $\theta$，使得期望总回报最大：&lt;/p&gt;
&lt;p&gt;$$
J(\theta) = \mathbb{E}&lt;em&gt;{\tau \sim p&lt;/em&gt;\theta(\tau)} \left[ \sum_{t=1}^T r(s_t, a_t) \right]
$$&lt;/p&gt;
&lt;p&gt;这是一个关于 $\theta$ 的函数，我们需要计算它的梯度 $\nabla_\theta J(\theta)$，并用梯度上升法更新 $\theta$。&lt;/p&gt;
&lt;h3&gt;2. 策略梯度的推导：对数导数技巧&lt;/h3&gt;
&lt;p&gt;直接对 $J(\theta)$ 求导很困难，因为期望的分布 $p_\theta(\tau)$ 本身依赖于 $\theta$。这里的关键技巧是“&lt;strong&gt;对数导数恒等式&lt;/strong&gt;”（log-derivative trick）：&lt;/p&gt;
&lt;p&gt;对于任意概率密度函数 $p_\theta(x)$，有：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta p_\theta(x) = p_\theta(x) \nabla_\theta \log p_\theta(x)
$$&lt;/p&gt;
&lt;p&gt;利用这个恒等式，我们可以将梯度改写为：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta J(\theta) = \nabla_\theta \int p_\theta(\tau) R(\tau) d\tau = \int \nabla_\theta p_\theta(\tau) R(\tau) d\tau \
= \int p_\theta(\tau) \nabla_\theta \log p_\theta(\tau) R(\tau) d\tau = \mathbb{E}&lt;em&gt;{\tau \sim p&lt;/em&gt;\theta(\tau)} \left[ \nabla_\theta \log p_\theta(\tau) R(\tau) \right]
$$&lt;/p&gt;
&lt;p&gt;其中 $R(\tau) = \sum_{t=1}^T r(s_t, a_t)$ 是整条轨迹的总回报。&lt;/p&gt;
&lt;p&gt;接下来，我们将 $\log p_\theta(\tau)$ 展开：&lt;/p&gt;
&lt;p&gt;$$
\log p_\theta(\tau) = \log p(s_1) + \sum_{t=1}^T \left( \log \pi_\theta(a_t | s_t) + \log p(s_{t+1}|s_t, a_t) \right)
$$&lt;/p&gt;
&lt;p&gt;注意到 $\log p(s_1)$ 和 $\log p(s_{t+1}|s_t, a_t)$ 都与 $\theta$ 无关，因此它们的梯度为零。于是：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta \log p_\theta(\tau) = \sum_{t=1}^T \nabla_\theta \log \pi_\theta(a_t | s_t)
$$&lt;/p&gt;
&lt;p&gt;将其代回梯度表达式，得到最终的&lt;strong&gt;策略梯度公式&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta J(\theta) = \mathbb{E}&lt;em&gt;{\tau \sim p&lt;/em&gt;\theta(\tau)} \left[ \left( \sum_{t=1}^T \nabla_\theta \log \pi_\theta(a_t | s_t) \right) \left( \sum_{t&amp;#39;=1}^T r(s_{t&amp;#39;}, a_{t&amp;#39;}) \right) \right]
$$&lt;/p&gt;
&lt;h3&gt;3. 直观理解：加权的监督学习&lt;/h3&gt;
&lt;p&gt;这个公式可以这样理解：策略梯度是在做一种&lt;strong&gt;加权的监督学习&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;回忆行为克隆的目标是 $\min_\theta \mathbb{E}[-\log \pi_\theta(a|s)]$，其梯度为 $-\nabla_\theta \log \pi_\theta(a|s)$，目的是增加专家动作的似然。&lt;/p&gt;
&lt;p&gt;而策略梯度的梯度项是 $\nabla_\theta \log \pi_\theta(a_t|s_t) \times R(\tau)$。这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果一条轨迹的总回报 $R(\tau)$ 很高，我们就&lt;strong&gt;增加&lt;/strong&gt;这条轨迹上所有 $(s_t, a_t)$ 对的似然。&lt;/li&gt;
&lt;li&gt;如果 $R(\tau)$ 很低（甚至是负的），我们就&lt;strong&gt;减少&lt;/strong&gt;这些 $(s_t, a_t)$ 对的似然。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是“试错学习”的数学形式化：多做带来好结果的事，少做带来坏结果的事。&lt;/p&gt;
&lt;h3&gt;4. 算法实现：REINFORCE&lt;/h3&gt;
&lt;p&gt;基于上述梯度，我们可以写出最简单的策略梯度算法——REINFORCE：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化策略参数 $\theta$。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;收集数据&lt;/strong&gt;：运行策略 $\pi_\theta$，得到 $N$ 条完整轨迹 ${\tau^i}_{i=1}^N$。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;估计梯度&lt;/strong&gt;：用蒙特卡洛采样近似期望：
$$
\nabla_\theta J(\theta) \approx \frac{1}{N} \sum_{i=1}^N \left( \sum_{t=1}^T \nabla_\theta \log \pi_\theta(a_{i,t} | s_{i,t}) \right) R(\tau^i)
$$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新策略&lt;/strong&gt;：$\theta \leftarrow \theta + \alpha \nabla_\theta J(\theta)$。&lt;/li&gt;
&lt;li&gt;重复步骤 2-4。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个算法完全在线，只需要智能体与环境交互产生的数据。&lt;/p&gt;
&lt;h3&gt;5. 问题一：高方差&lt;/h3&gt;
&lt;p&gt;策略梯度的一个致命弱点是&lt;strong&gt;方差极高&lt;/strong&gt;。原因在于，整条轨迹的回报 $R(\tau)$ 被用来更新轨迹上的每一个时间步。即使某个早期动作与最终的高回报毫无关系，它也会被错误地加强。&lt;/p&gt;
&lt;p&gt;更糟的是，如果回报的绝对值很大，梯度的尺度会变得极不稳定。&lt;/p&gt;
&lt;h3&gt;6. 改进一：因果性（Causality）&lt;/h3&gt;
&lt;p&gt;一个基本的物理事实是：&lt;strong&gt;当前的动作不能影响过去已经发生的奖励&lt;/strong&gt;。因此，在计算时间步 $t$ 的贡献时，我们只应考虑从 $t$ 开始的未来回报，即&lt;strong&gt;回报到-go&lt;/strong&gt;（return-to-go）：&lt;/p&gt;
&lt;p&gt;$$
\hat{R}&lt;em&gt;t = \sum&lt;/em&gt;{t&amp;#39;=t}^T r(s_{t&amp;#39;}, a_{t&amp;#39;})
$$&lt;/p&gt;
&lt;p&gt;于是梯度更新变为：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta J(\theta) \approx \frac{1}{N} \sum_{i=1}^N \sum_{t=1}^T \nabla_\theta \log \pi_\theta(a_{i,t} | s_{i,t}) \hat{R}_{i,t}
$$&lt;/p&gt;
&lt;p&gt;这显著降低了方差，因为我们剔除了与当前决策无关的历史噪声。&lt;/p&gt;
&lt;h3&gt;7. 改进二：引入基线（Baseline）&lt;/h3&gt;
&lt;p&gt;即使使用了回报到-go，梯度仍然可能因回报的绝对值过大而波动。我们可以减去一个与动作无关的&lt;strong&gt;基线&lt;/strong&gt; $b$，来进一步降低方差。&lt;/p&gt;
&lt;p&gt;关键性质是：对于任意与动作 $a_t$ 无关的基线 $b(s_t)$，以下等式成立：&lt;/p&gt;
&lt;p&gt;$$
\mathbb{E}&lt;em&gt;{a_t \sim \pi&lt;/em&gt;\theta} \left[ \nabla_\theta \log \pi_\theta(a_t|s_t) b(s_t) \right] = b(s_t) \nabla_\theta \mathbb{E}_{a_t} [1] = 0
$$&lt;/p&gt;
&lt;p&gt;因此，减去基线不会改变梯度的期望（无偏），但能有效降低方差。&lt;/p&gt;
&lt;p&gt;一个常用且有效的选择是&lt;strong&gt;状态价值函数&lt;/strong&gt; $V^{\pi}(s_t)$，即在状态 $s_t$ 下遵循当前策略的期望未来回报。实践中，常使用一个简单的启发式：&lt;strong&gt;整个批次的平均回报&lt;/strong&gt;作为全局基线。&lt;/p&gt;
&lt;h3&gt;8. 从 on-policy 到 off-policy&lt;/h3&gt;
&lt;p&gt;REINFORCE 是一个 &lt;strong&gt;on-policy&lt;/strong&gt; 算法：每次更新后，策略 $\pi_\theta$ 发生了变化，旧的数据就不再反映新策略的行为，必须重新收集数据。这导致样本效率极低。&lt;/p&gt;
&lt;p&gt;为了提高效率，我们希望实现 &lt;strong&gt;off-policy&lt;/strong&gt; 学习：用旧策略 $\pi_{\theta_{\text{old}}}$ 采集的数据，来更新新策略 $\pi_{\theta_{\text{new}}}$。&lt;/p&gt;
&lt;p&gt;这可以通过&lt;strong&gt;重要性采样&lt;/strong&gt;（Importance Sampling）实现。轨迹层面的重要性权重为：&lt;/p&gt;
&lt;p&gt;$$
\frac{p_{\theta_{\text{new}}}(\tau)}{p_{\theta_{\text{old}}}(\tau)} = \prod_{t=1}^T \frac{\pi_{\theta_{\text{new}}}(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)}
$$&lt;/p&gt;
&lt;p&gt;然而，这个乘积会随着轨迹长度 $T$ 指数级地爆炸或消失，导致估计极不稳定。&lt;/p&gt;
&lt;p&gt;一个更实用的做法是在&lt;strong&gt;单个时间步&lt;/strong&gt;层面进行重要性采样，得到 off-policy 策略梯度：&lt;/p&gt;
&lt;p&gt;$$
\nabla_\theta J(\theta) \approx \frac{1}{N} \sum_{i=1}^N \sum_{t=1}^T \frac{\pi_\theta(a_{i,t}|s_{i,t})}{\pi_{\theta_{\text{old}}}(a_{i,t}|s_{i,t})} \nabla_\theta \log \pi_\theta(a_{i,t}|s_{i,t}) \hat{R}_{i,t}
$$&lt;/p&gt;
&lt;p&gt;这允许我们在同一批数据上进行多次梯度更新，大大提高了样本效率。&lt;/p&gt;
&lt;h3&gt;9. 约束策略更新幅度&lt;/h3&gt;
&lt;p&gt;然而，off-policy 更新有一个风险：如果新旧策略相差太远，重要性权重会失真，导致梯度估计完全错误。&lt;/p&gt;
&lt;p&gt;因此，我们需要约束策略在一次更新中不能偏离太远。一种常见的方法是加入一个&lt;strong&gt;KL散度约束&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;$$
\mathbb{E}&lt;em&gt;{s \sim \pi&lt;/em&gt;{\theta_{\text{old}}}} \left[ D_{\text{KL}} ( \pi_{\theta_{\text{new}}}(\cdot|s) | \pi_{\theta_{\text{old}}}(\cdot|s) ) \right] \leq \delta
$$&lt;/p&gt;
&lt;p&gt;这个约束保证了新策略的行为分布不会与旧策略相差太远，从而维持了 off-policy 估计的有效性。这也是后续 PPO 等算法的核心思想之一。&lt;/p&gt;
&lt;h3&gt;10. 总结&lt;/h3&gt;
&lt;p&gt;策略梯度为我们提供了一个优雅而通用的框架，将强化学习问题转化为一个可微的优化问题。尽管其原始形式（REINFORCE）存在高方差和低样本效率的问题，但通过引入&lt;strong&gt;因果性&lt;/strong&gt;、&lt;strong&gt;基线&lt;/strong&gt;、&lt;strong&gt;重要性采样&lt;/strong&gt;和&lt;strong&gt;KL约束&lt;/strong&gt;等一系列技巧，我们可以逐步构建出强大而实用的在线强化学习算法。这些思想构成了现代深度强化学习，如 PPO、TRPO 等算法的基石。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sat, 07 Feb 2026 00:00:00 GMT</pubDate></item><item><title>cs224R-Lecture 2 Imitation Learning</title><link>https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture1%E6%A8%A1%E4%BB%BF%E5%AD%A6%E4%B9%A0/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture1%E6%A8%A1%E4%BB%BF%E5%AD%A6%E4%B9%A0/</guid><description>cs224R</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture1%E6%A8%A1%E4%BB%BF%E5%AD%A6%E4%B9%A0/&quot;&gt;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture1%E6%A8%A1%E4%BB%BF%E5%AD%A6%E4%B9%A0/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇适合和导论连着看。它回答的是：当奖励难定义、交互代价又高时，我们能不能直接从专家示范里学策略。
&lt;/Info&gt;

&lt;h2&gt;Lecture 2 Imitation Learning&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs224r.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;0.引言&lt;/h3&gt;
&lt;p&gt;在上一讲中，我们将强化学习形式化为一个清晰的优化问题：通过与环境的交互，学习一个策略，使其在期望意义下最大化累计奖励。从理论角度看，这一表述是完备且优雅的。然而，在真实系统中，这一范式往往直接遭遇实践层面的困难。&lt;/p&gt;
&lt;p&gt;首先，环境交互的成本在许多任务中是不可忽略的。真实机器人、自动驾驶系统或面向用户的在线系统，都无法承受大规模、无约束的试错过程。其次，奖励函数在许多任务中并不容易被精确定义。人类通常能够判断“一个行为是否合理”，但将这种判断转化为稳定、可优化的标量信号本身就是一个困难的问题。&lt;/p&gt;
&lt;p&gt;更进一步，在不少场景中，人类专家已经能够完成任务，并且已经积累了大量可供记录的行为数据。这自然引出了一个核心问题：在不显式构造奖励函数、也不依赖大规模环境交互的前提下，是否可以直接从专家行为中学习策略？&lt;/p&gt;
&lt;p&gt;因此，我们引入了模仿学习（Imitation Learning）。&lt;/p&gt;
&lt;h3&gt;1.基本问题设定&lt;/h3&gt;
&lt;p&gt;模仿学习假设我们可以访问一组由专家策略生成的示范数据。这些数据通常以轨迹的形式给出，每条轨迹由状态序列及其对应的专家动作构成。形式化地，可以将数据集表示为&lt;/p&gt;
&lt;p&gt;$$
\mathcal{D} = {(s_1, a_1, \dots, s_T, a_T)}
$$&lt;/p&gt;
&lt;p&gt;其中数据由某个未知但性能良好的专家策略 $\pi_{\text{expert}}$ 采样得到。&lt;/p&gt;
&lt;p&gt;模仿学习的目标并不是推断环境动力学或奖励函数，而是直接学习一个参数化策略 $\pi_\theta$，使其在状态分布上尽可能复现专家的决策行为。从这一角度看，模仿学习的关注点不在于“什么是好的状态”，而在于“专家在这些状态下采取了什么样的行动”。&lt;/p&gt;
&lt;p&gt;这一设定在形式上与监督学习高度相似，但其后果却截然不同。&lt;/p&gt;
&lt;h3&gt;2.模仿学习 Version 0：行为克隆&lt;/h3&gt;
&lt;p&gt;行为克隆（Behavior Cloning, BC）的最常见形式，是用监督学习拟合专家动作。若采用确定性策略，典型目标为平方损失回归：&lt;/p&gt;
&lt;p&gt;$$
\min_\theta \mathbb{E}&lt;em&gt;{(s,a) \sim D} \left[ |a - \hat a|^2 \right], \hat a = \pi&lt;/em&gt;\theta (s)
$$&lt;/p&gt;
&lt;p&gt;这一写法在形式上简洁，但它隐含了一个非常强的建模偏置：在给定状态 $s$ 时，模型被鼓励输出一个“单值”动作 $\hat a$ 。当专家行为在同一状态下近似唯一时，这种偏置并不明显；然而在实际数据中，专家往往并非单一来源，或存在等价可行的多种决策模式，于是问题就会显现。&lt;/p&gt;
&lt;h3&gt;3.为什么 $L_2$ 回归会学到“均值”？&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.9gx355jie0.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果示范数据在某些状态上呈现多模态（例如一部分专家选择“并入左侧车道”，另一部分选择“保持/并入右侧”），那么用 $L_2$ 损失训练的确定性政策会倾向输出&lt;strong&gt;条件均值&lt;/strong&gt;。更具体的说，在固定 $s$ 的条件下，最小化 $\mathbb{E} |a - \hat a|^2$ 的最优解满足：&lt;/p&gt;
&lt;p&gt;$$
\hat a^*(s) = \mathbb{E}[a \mid s]
$$&lt;/p&gt;
&lt;p&gt;这意味着：当数据分布在动作空间有两个峰时，均值往往落在“两个峰之间”的低概率区域。在驾驶这样的安全敏感任务里，这种折中动作会是灾难性的。&lt;/p&gt;
&lt;p&gt;因此，我们可以认识到：模仿学习的挑战不一定来自网络不够大，而可能来自输出分布的表达能力不足。换句话说，“函数逼近能力”与“分布表达能力”是两件不同的事。&lt;/p&gt;
&lt;h3&gt;4.如何用神经网络表示动作分布&lt;/h3&gt;
&lt;p&gt;对于离散动作，举个例子，超级马里奥的上下左右操作。神经网路可以直接输出一个categorical分布的参数：&lt;/p&gt;
&lt;p&gt;$$
\pi_\theta(a \mid s) = \text{Cat}(p_1(s), \ldots, p_K(s)),
$$&lt;/p&gt;
&lt;p&gt;对于连续的动作，例如机器人每个关节的旋转角度、位姿估计，最常见的做法是让网络输出一组高斯分布参数。&lt;/p&gt;
&lt;p&gt;$$
\pi_\theta(a \mid s) = \mathcal{N}(\mu_\theta(s), \sigma_\theta(s))
$$&lt;/p&gt;
&lt;p&gt;这种单峰高斯分布参数化计算便利，但表达能力明显受限。因为即使网络参数再大，$\pi_\theta(\cdot \mid s)$ 仍然只是单峰型状态，很难在多模态的示范模型中对应复杂的条件分布。&lt;/p&gt;
&lt;h3&gt;5.生成模型视角&lt;/h3&gt;
&lt;p&gt;我们可以将模仿学习同生成模型的目标相联系。举个例子图像diffusion模型学习的目标是$p(\text{image} \mid \text{text})$、 自回归的语言模型学习的目标是 $p(\text{next word} \mid \text{context})$，而模仿学习的本质是在学习&lt;/p&gt;
&lt;p&gt;$$
p(\text{action} \mid \text{observatons})
$$&lt;/p&gt;
&lt;p&gt;我们将策略选择类比为“条件生成模型”，那么需要生成模型的建模工具就可以直接迁移到策略分布建模中，从而解决了“只能输出均值/单峰”的结构限制问题。&lt;/p&gt;
&lt;h3&gt;6.三类“表达性策略分布”&lt;/h3&gt;
&lt;p&gt;正如我在上文所提及的，&lt;strong&gt;网络表达能力&lt;/strong&gt;和&lt;strong&gt;分布表达能力&lt;/strong&gt;不同，为了解决这个问题，我们类比了生成模型的建模工具，这一章我会介绍三种方法来让输出分布能表达多峰/复杂结构。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;高斯混合（Mixture of Gaussians, MoG）
用多个高斯分布的加权和表示策略分布：
$$
\pi_\theta(a \mid s) = \sum_{k=1}^{K} w_k(s) , \mathcal{N}(a; \mu_k(s), \sigma_k(s))
$$
网络输出的是 ${w_k, \mu_k, \sigma_k}_{k=1}^K$。MoG能显式表达多模态，是对单峰高斯的直接扩展；但在高维动作空间中，$K$ 很大或者方差结构复杂会导致网络参数爆炸、训练困难。并且推理时需要采样整个混合分布，计算成本较高。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;离散化 + 自回归（Discretize + Autoregressive）&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将连续动作按维度或按区间离散化，随后用自回归分解：&lt;/p&gt;
&lt;p&gt;$$
p(a) = \prod_{d=1}^{D} p(a_d \mid a_{&amp;lt;d}, s),
$$&lt;/p&gt;
&lt;p&gt;网络输出的一系列条件分布。自回归的优势在于可以表达复杂的依赖结构。然而缺点也是显而易见的，由于推理需要逐维生成，导致推理速度较慢。此外，离散化还会损失精度。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;扩散策略（Diffusion Policy）&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将行为动作生成写成逐步去噪过程：从噪声动作出发，通过 $N$ 步迭代预测噪声或残差，最终得到动作样本。&lt;/p&gt;
&lt;h3&gt;7.模仿学习 Version 1：最大化对数似然&lt;/h3&gt;
&lt;p&gt;在引入表达性策略分布后，模仿学习的训练目标也随之发生变化。相比于Version 0中的$L_2$ 回归，Version 1将策略视为条件概率分布，并通过最大化专家动作在该分布下的对数概率进行训练：&lt;/p&gt;
&lt;p&gt;$$
\max_\theta \mathbb{E}&lt;em&gt;{(s,a) \sim D} [\log \pi&lt;/em&gt;\theta(a \mid s)]
$$&lt;/p&gt;
&lt;p&gt;这一目标允许策略在同一状态下为多种合理动作分配概率质量，而不是被迫输出一个折中的平均动作。从统计角度看，模型不再试图拟合条件期望，而是拟合完整的条件分布。&lt;/p&gt;
&lt;h3&gt;8. 表达性策略并不能解决所有问题&lt;/h3&gt;
&lt;p&gt;到目前为止，我们已经解决了模仿学习的&lt;strong&gt;第一个根本问题&lt;/strong&gt;：
行为克隆中“学到均值动作”的失败，来源于对动作分布的错误建模假设，而非网络容量不足。通过引入更具表达能力的策略分布，并采用最大化对数似然的训练目标，Version 1 的模仿学习能够在离线示范数据上更忠实地复现专家行为。&lt;/p&gt;
&lt;p&gt;然而，一个关键事实仍然没有改变：&lt;strong&gt;模仿学习依然是一个闭环决策问题&lt;/strong&gt;。即便策略在示范数据上拟合得再好，其预测动作一旦被用于控制系统，仍然会影响后续状态的分布。这一点使得模仿学习与标准监督学习在结构上存在本质差异。&lt;/p&gt;
&lt;h3&gt;9. 模仿学习与监督学习的结构性差异&lt;/h3&gt;
&lt;p&gt;在标准监督学习中，输入变量的分布独立于模型的预测结果。模型输出不会反过来影响未来样本，因此逐点预测误差不会在时间维度上累积。&lt;/p&gt;
&lt;p&gt;而在模仿学习中，情况完全不同。策略在时间步 $t$ 的预测动作 $\hat a_t$ 会直接决定下一个状态 $s_{t+1}$，并进一步影响之后所有的输入分布。这意味着，即便在单步预测意义下误差很小，也可能通过系统动力学被不断放大。&lt;/p&gt;
&lt;p&gt;因此，模仿学习的失败并非单纯来自“预测不准”，而是源于&lt;strong&gt;预测结果本身参与了数据生成过程&lt;/strong&gt;。这是一个闭环系统特有的问题。&lt;/p&gt;
&lt;h3&gt;10. 分布不一致与误差累积&lt;/h3&gt;
&lt;p&gt;更形式化地看，模仿学习训练时所见到的状态分布来自专家轨迹，记为&lt;/p&gt;
&lt;p&gt;$$
p_{\text{expert}}(s).
$$&lt;/p&gt;
&lt;p&gt;而在部署时，系统实际访问到的状态分布由当前策略 (\pi) 所诱导，记为&lt;/p&gt;
&lt;p&gt;$$
p_\pi(s).
$$&lt;/p&gt;
&lt;p&gt;只要策略存在任何预测误差，这两个分布就不可能完全一致。一旦策略偏离专家轨迹，系统就可能进入专家从未访问过的状态区域，而模型在这些区域缺乏监督信号，预测误差随时间不断放大。&lt;/p&gt;
&lt;p&gt;这种现象通常被称为 &lt;strong&gt;covariate shift&lt;/strong&gt;，在序列决策问题中则具体表现为 &lt;strong&gt;compounding errors（误差累积）&lt;/strong&gt;。重要的是，这一问题即便在示范数据无限、模型表达能力足够强的理想条件下也无法完全避免。&lt;/p&gt;
&lt;h3&gt;11. 为什么“多收集示范数据”并不能根本解决问题&lt;/h3&gt;
&lt;p&gt;一个直觉性的想法是：如果误差来自于分布不一致，那么是否可以通过收集大量示范数据来覆盖更多状态？&lt;/p&gt;
&lt;p&gt;课件明确指出，这一思路并不能从根本上解决问题。原因在于，失败往往发生在&lt;strong&gt;由模型自身错误诱导出的状态区域&lt;/strong&gt;，而这些区域在专家示范中原本并不存在。即便示范数据规模极大，只要训练分布与执行分布存在系统性差异，误差累积就不可避免。&lt;/p&gt;
&lt;p&gt;这表明：纯离线模仿学习在闭环系统中存在结构性风险。&lt;/p&gt;
&lt;h3&gt;12. DAgger：在策略访问的状态上引入监督&lt;/h3&gt;
&lt;p&gt;为缓解上述问题，DAgger（Dataset Aggregation）方法被提出。其核心思想可以概括为：
&lt;strong&gt;如果问题在于训练分布与执行分布不一致，那么就应当让训练分布逐步向执行分布靠拢。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;DAgger 的做法是反复执行当前策略 $\pi_\theta$，并在策略实际访问到的状态 $s&amp;#39;$ 上查询专家动作 $a^*$，将这些新样本不断加入训练集，再重新训练策略。通过这一过程，训练数据的状态分布逐渐对齐 $p_\pi(s)$，从而显著缓解误差累积问题。&lt;/p&gt;
&lt;p&gt;从分布角度看，DAgger 并不是简单地“纠正错误动作”，而是在持续重塑训练数据的状态空间覆盖范围。&lt;/p&gt;
&lt;h3&gt;13. 在线干预的现实约束&lt;/h3&gt;
&lt;p&gt;尽管 DAgger 在理论上具有良好的性质，其实践应用仍然面临显著挑战。持续查询专家意味着算法必须在线运行，并且需要一个可以在任意状态下提供正确动作的专家接口。&lt;/p&gt;
&lt;p&gt;在许多真实系统中，这样的专家并不总是可用，或者查询成本极高。因此，原始 DAgger 在工程上并不总是可行。&lt;/p&gt;
&lt;h3&gt;14. Human-Gated DAgger：更可行的干预范式&lt;/h3&gt;
&lt;p&gt;为降低专家干预成本，介绍了一种更贴近现实的变体，通常称为 &lt;strong&gt;Human-Gated DAgger&lt;/strong&gt;。在这种设置下，策略默认自行控制系统；只有当专家判断策略即将发生严重错误时，才介入并提供纠正示范。&lt;/p&gt;
&lt;p&gt;这种方法并未消除分布偏移问题，而是通过在高风险状态附近提供稀疏但关键的监督信号，对策略进行局部修正。实践表明，这种干预范式在机器人等复杂系统中更具可操作性。&lt;/p&gt;
&lt;h3&gt;15. 模仿学习在强化学习体系中的定位&lt;/h3&gt;
&lt;p&gt;综合来看，模仿学习提供了一种在低风险、低交互成本条件下获得可行策略的方式，尤其适合作为复杂强化学习系统的初始化手段。然而，它本身并不提供通过环境反馈持续改进策略的机制，也无法保证策略性能超越专家。&lt;/p&gt;
&lt;p&gt;因此，在现代系统中，模仿学习通常被视为强化学习流程中的一个阶段，而非最终解决方案。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Fri, 06 Feb 2026 00:00:00 GMT</pubDate></item><item><title>cs224R-Lecture 1 Introduction</title><link>https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture0%E5%AF%BC%E8%AE%BA/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture0%E5%AF%BC%E8%AE%BA/</guid><description>cs224R</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture0%E5%AF%BC%E8%AE%BA/&quot;&gt;https://dannyshi.pages.dev/blog/cs224r/cs224r-lecture0%E5%AF%BC%E8%AE%BA/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇是整套强化学习笔记的入口，重点不是记算法，而是先建立“监督学习为什么不足以描述连续决策问题”的问题意识。
&lt;/Info&gt;

&lt;h2&gt;Lecture 1 Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cs224r.stanford.edu/&quot;&gt;课程链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;0.引言&lt;/h3&gt;
&lt;p&gt;在传统的机器学习中，我们习惯于这样的设定&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一组输入$x$，以及对应的正确答案$y$
让模型学习到一个函数$f(x)=y$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然而现实世界中，大量问题无法被这样简单建模。例如：机器人的连续决策或者语言模型的连续上下文对话。这些目标并没有&lt;strong&gt;标准答案&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;因此强化学习解决的核心问题是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当一个模型需要在时间序列中不断做决定、且当前状态的做的动作会影响未来的观察与结果时，我们怎么解决这个问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.强化学习与监督学习的区别&lt;/h3&gt;
&lt;p&gt;监督学习的假设非常强：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据是给定的&lt;/li&gt;
&lt;li&gt;每一个样本都有正确的标签&lt;/li&gt;
&lt;li&gt;模型只负责预测
$$
(x_i,y_i) \Rightarrow f(x) \approx y
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;强化学习不同于监督学习，强化学习不是仅仅学习给定数据的映射关系，而是通过交互获得奖励信号来调整决策，简而言之，强化学习是在学习行为。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型需要自行做决定&lt;/li&gt;
&lt;li&gt;决策的优劣由奖励模型评估&lt;/li&gt;
&lt;li&gt;当前状态的决策会影响后续的数据分布&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;强化学习学习到的是一个&lt;strong&gt;策略&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;$$
\pi(a\mid s )
$$&lt;/p&gt;
&lt;p&gt;上面这个式子的意思是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在状态$s$下，以某种概率决定动作$a$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里的行为可以是机器人控制关节，LLM进行的回复或者是agent进行的网页交互等等动作。&lt;/p&gt;
&lt;h3&gt;2.为什么要学习强化学习&lt;/h3&gt;
&lt;p&gt;由于现实世界的很多问题并没有足够的数据标签来支持传统的监督学习，正如刚才列举的机器人交互决策、大语言模型等。强化学习因此应运而生，机器人的行走、抓取和LLM的后训练等都是强化学习的广泛应用。&lt;/p&gt;
&lt;p&gt;强化学习的一个关键直觉是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;智能体能否在通过反复尝试和反馈中，逐渐学会更好的行为。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.如何将行为表示成数据？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;四个基本要素&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;状态（State）
$$
s_t = t时刻世界的真实状态
$$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;动作（Action）
$$
a_t = t时刻智能体采取的决策
$$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;观测（Observation）
$$
o_t = 智能体在t时刻观测到的信息
$$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;奖励（Reward）
$$
r(s_t,a_t) = 这个状态和动作有多好？
$$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;轨迹（Trajectory）&lt;/strong&gt;
一个完整的交互过程被记录为一条轨迹:&lt;/p&gt;
&lt;p&gt;$$
\tau = (s_1,a_1,s_2,a_2,...,s_T,a_T)
$$&lt;/p&gt;
&lt;p&gt;也被称为rollout，长度可以是1，也可以很长。&lt;/p&gt;
&lt;h3&gt;4.State vs Observation:为什么要区分？&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.2h8tn2k48e.png&quot; alt=&quot;&quot;&gt;
&lt;strong&gt;Markov假设&lt;/strong&gt;：
如果$t$时刻使用的是&lt;strong&gt;状态$s_t$&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;$$
p(s_{t+1} \mid s_t,a_t)
$$&lt;/p&gt;
&lt;p&gt;意思是：下一个状态仅仅依赖当前的状态和动作，与更早的历史无关。&lt;/p&gt;
&lt;p&gt;这就是&lt;strong&gt;Markov Decision Process（MDP）&lt;/strong&gt;。
然而现实系统中经常无法获取到完整状态，这时只能使用observation（$o_t$），需要给策略&lt;strong&gt;记忆能力&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;$$
\pi(a_t \mid o_{t-m},...,o_t)
$$&lt;/p&gt;
&lt;h3&gt;5.如何用神经网络表示“行为”？&lt;/h3&gt;
&lt;p&gt;策略可以用神经网络表示:&lt;/p&gt;
&lt;p&gt;$$
\pi_\theta (a \mid s)
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入：状态（$s_t$）或观测（$o_t$）&lt;/li&gt;
&lt;li&gt;输出：动作分布&lt;/li&gt;
&lt;li&gt;参数：神经网络权重$\theta$
一次交互流程：&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;观察当前状态$s_t$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;从策略（$\pi_\theta$）输出的动作分布中采样动作$a_t$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;环境转移到$s_{t+1}$&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;重复上述操作$\rightarrow$ 得到一条轨迹&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6.强化学习真正的优化目标&lt;/h3&gt;
&lt;p&gt;表面上看，我们的优化目标是下面这个函数&lt;/p&gt;
&lt;p&gt;$$
\max \sum_{t=1}^{T} r(s_t, a_t)
$$&lt;/p&gt;
&lt;p&gt;$r(s_t,a_t)$是在状态$s_t$下采取动作$a_t$得到的即时奖励。&lt;/p&gt;
&lt;p&gt;直观上看，这个式子的含义是希望从时间步$t = 1$ 到 $T$ 内，获得的总奖励尽可能大。&lt;/p&gt;
&lt;p&gt;然而一个重要的问题是，这个奖励总和并不是一个确定值。由于&lt;strong&gt;环境是随机的&lt;/strong&gt;，即使你采取了某个动作 $ a&lt;em&gt;t $，下一个状态 $ s&lt;/em&gt;{t+1} $ 可能不确定，由环境动态 $ p(s*{t+1} \mid s_t, a_t) $ 决定。此外，&lt;strong&gt;策略本身也是随机的&lt;/strong&gt;，策略 $ \pi*\theta(a_t \mid s_t) $ 是一个概率分布，表示在状态 $ s_t $ 下选择不同动作的概率。所以即使策略固定，每次运行也可能选不同的动作。&lt;/p&gt;
&lt;p&gt;因此，每条轨迹的总奖励都是&lt;strong&gt;随机变量&lt;/strong&gt;，不能直接最大化一个随机值。&lt;/p&gt;
&lt;p&gt;所以真正优化的是：&lt;strong&gt;期望回报&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
\max_\theta \mathbb{E}&lt;em&gt;{\tau \sim p&lt;/em&gt;\theta(\tau)} \left[ \sum_{t=1}^T r(s_t, a_t) \right]
$$&lt;/p&gt;
&lt;p&gt;我们不再追求某一次跑出来的总奖励最大，而是希望&lt;strong&gt;所有可能轨迹的平均回报最大&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$ \tau $：一条完整的轨迹，即 $ (s_1, a_1, r_1, s_2, a_2, r_2, \dots, s_T) $&lt;/li&gt;
&lt;li&gt;$ p_\theta(\tau) $：在参数为 $ \theta $ 的策略下，生成这条轨迹的概率。&lt;/li&gt;
&lt;li&gt;$ \mathbb{E}&lt;em&gt;{\tau \sim p&lt;/em&gt;\theta(\tau)}[\cdot] $：对所有可能轨迹按其概率加权求期望。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是强化学习的&lt;strong&gt;核心优化目标&lt;/strong&gt;：最大化期望回报。&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;p&gt;$$
p_\theta(\tau) = p(s_1) \prod_{t=1}^{T} \pi_\theta(a_t \mid s_t) p(s_{t+1} \mid s_t, a_t)
$$&lt;/p&gt;
&lt;p&gt;这个公式描述了一条完整轨迹的概率是如何构成的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$ p(s_1) $：初始状态的概率&lt;/li&gt;
&lt;li&gt;$ \pi_\theta(a_t \mid s_t) $：在状态 $ s_t $ 下选择动作 $ a_t $ 的概率&lt;/li&gt;
&lt;li&gt;$ p(s_{t+1} \mid s_t, a_t) $：环境转移概率&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个乘积表示：&lt;strong&gt;从初始状态开始，依次按照策略选动作，并根据环境动态转移状态，最终形成整条轨迹的概率&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;因此我们得到了一个关键结论：在强化学习中，&lt;strong&gt;我们要优化的不是单次的累计奖励，而是策略产生的轨迹的期望累计奖励&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;7.Value Function：衡量策略好不好&lt;/h3&gt;
&lt;p&gt;为了评估和改进策略，引入两个重要概念。&lt;/p&gt;
&lt;p&gt;Value Function（值函数）&lt;/p&gt;
&lt;p&gt;$$
V^\pi(s)
$$&lt;/p&gt;
&lt;p&gt;含义：从状态$s$开始，按策略$\pi$行动，未来能获得的期望总奖励。&lt;/p&gt;
&lt;p&gt;Q Function（动作值函数）&lt;/p&gt;
&lt;p&gt;$$
Q^\pi(s,a)
$$&lt;/p&gt;
&lt;p&gt;含义：在状态$s$下先执行动作$a$，然后继续按策略$\pi$，能获得的期望总奖励。&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Wed, 04 Feb 2026 00:00:00 GMT</pubDate></item><item><title>cs231n笔记</title><link>https://dannyshi.pages.dev/blog/cs231n/cs231n%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/cs231n/cs231n%E7%AC%94%E8%AE%B0/</guid><description>cs231n</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/cs231n/cs231n%E7%AC%94%E8%AE%B0/&quot;&gt;https://dannyshi.pages.dev/blog/cs231n/cs231n%E7%AC%94%E8%AE%B0/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇更像课程总目录和学习记录入口，适合作为 `CS231n` 系列笔记的导航页来用。
&lt;/Info&gt;

&lt;p&gt;其实看这个课已经有几个月了，然而由于各种事情的干扰一直没能系统完整的学习全部内容，所以在这里开一个博客以此来记录学习内容等等。&lt;/p&gt;
&lt;details&gt;
  &lt;summary&gt;推荐阅读顺序&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;先看线性分类器、正则化与优化，再进入神经网络与反向传播。&lt;/li&gt;
    &lt;li&gt;接着读 CNN 基础和 CNN 架构，建立视觉模型主线。&lt;/li&gt;
    &lt;li&gt;最后读 RNN、注意力机制、检测与分割，补齐序列与高阶视觉任务。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h2&gt;Lecture 1 导论&lt;/h2&gt;
&lt;h2&gt;Lecture 2 线性分类器进行图像分类&lt;/h2&gt;
&lt;h2&gt;Lecture 3 正则化与优化&lt;/h2&gt;
&lt;h2&gt;Lecture 4 神经网络与反向传播&lt;/h2&gt;
&lt;h2&gt;Lecture 5 基于CNN的图像分类&lt;/h2&gt;
&lt;h2&gt;Lecture 6 CNN架构&lt;/h2&gt;
&lt;h2&gt;Lecture 7 循环神经网络&lt;/h2&gt;
&lt;h2&gt;Lecture 8 注意力机制与Transformers&lt;/h2&gt;
&lt;h2&gt;Lecture 9 目标检测、图像分割与可视化&lt;/h2&gt;
&lt;h2&gt;Lecture 10 视频理解&lt;/h2&gt;
&lt;h2&gt;Lecture 11 大规模分布式训练&lt;/h2&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Mon, 26 Jan 2026 00:00:00 GMT</pubDate></item><item><title>线性代数第四章复习笔记</title><link>https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E7%AC%AC%E5%9B%9B%E7%AB%A0%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E7%AC%AC%E5%9B%9B%E7%AB%A0%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid><description>linear algebra</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E7%AC%AC%E5%9B%9B%E7%AB%A0%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/&quot;&gt;https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E7%AC%AC%E5%9B%9B%E7%AB%A0%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇内容偏定理和判定条件，适合考前快速对照“有无解、唯一解、基础解系、秩”等常见题型。
&lt;/Info&gt;

&lt;h1&gt;向量与线性方程组&lt;/h1&gt;
&lt;details&gt;
  &lt;summary&gt;复习时优先看什么&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;先看线性方程组解的判定，再看秩和基础解系之间的关系。&lt;/li&gt;
    &lt;li&gt;做题时优先把“条件”翻译成矩阵秩的语言，通常会更直接。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h2&gt;1. 线性方程组有解判定定理&lt;/h2&gt;
&lt;h3&gt;1.1 非齐次线性方程组 $ A\mathbf{x} = \mathbf{0} $&lt;/h3&gt;
&lt;p&gt;设 $ A \in \mathbb{R}^{m \times n} $，增广矩阵为 $ \tilde{A} = [A \mid \mathbf{b}] $，则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;无解&lt;/strong&gt;&lt;br&gt;$$ \text{rank}(A) \ne \text{rank}(\tilde{A}) $$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;有唯一解&lt;/strong&gt;&lt;br&gt;$$ \text{rank}(A) = \text{rank}(\tilde{A}) = n $$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;有无穷多解&lt;/strong&gt;&lt;br&gt;$$ \text{rank}(A) = \text{rank}(\tilde{A}) &amp;lt; n $$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.2 齐次线性方程组 $ A\mathbf{x} = \mathbf{b} $&lt;/h3&gt;
&lt;p&gt;设 $ A \in \mathbb{R}^{m \times n} $，则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;只有零解&lt;/strong&gt;（列向量线性无关）&lt;br&gt;$$ \text{rank}(A) = n \quad \Leftrightarrow \quad \text{列满秩} $$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;有非零解&lt;/strong&gt;（列向量线性相关）&lt;br&gt;$$ \text{rank}(A) &amp;lt; n \quad \Leftrightarrow \quad \text{列降秩} $$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. 线性方程组解的结构&lt;/h2&gt;
&lt;h3&gt;2.1 齐次方程组 $ A\mathbf{x} = \mathbf{0} $&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;通解（结构解）&lt;/strong&gt;&lt;br&gt;$$
\mathbf{x} = k_1\boldsymbol{\xi}&lt;em&gt;1 + k_2\boldsymbol{\xi}&lt;em&gt;2 + \cdots + k&lt;/em&gt;{n-r}\boldsymbol{\xi}&lt;/em&gt;{n-r}
$$
其中  &lt;ul&gt;
&lt;li&gt;$ \boldsymbol{\xi}_1, \boldsymbol{\xi}&lt;em&gt;2, \dots, \boldsymbol{\xi}&lt;/em&gt;{n-r} $ 是 $ A\mathbf{x} = \mathbf{0} $ 的一个&lt;strong&gt;基础解系&lt;/strong&gt;；  &lt;/li&gt;
&lt;li&gt;$ r = \text{rank}(A) $，且 $ r &amp;lt; n $。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 非齐次方程组 $ A\mathbf{x} = \mathbf{b} $&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;通解（结构解）&lt;/strong&gt;&lt;br&gt;$$
\mathbf{x} = \underbrace{k_1\boldsymbol{\xi}&lt;em&gt;1 + k_2\boldsymbol{\xi}&lt;em&gt;2 + \cdots + k&lt;/em&gt;{n-r}\boldsymbol{\xi}&lt;/em&gt;{n-r}}_{\text{导出组通解}} + \boldsymbol{\eta}^*
$$
其中  &lt;ul&gt;
&lt;li&gt;$ \boldsymbol{\eta}^* $ 是 $ A\mathbf{x} = \mathbf{b} $ 的&lt;strong&gt;任意一个特解&lt;/strong&gt;；  &lt;/li&gt;
&lt;li&gt;其余符号含义同上。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;2.3 基础解系存在性&lt;/h3&gt;
&lt;p&gt;若&lt;br&gt;$$
\text{rank}(A_{m \times n}) = r &amp;lt; n
$$&lt;br&gt;则齐次方程组 $ A\mathbf{x} = \mathbf{0} $ 必存在基础解系，且&lt;strong&gt;任意 $ n-r $ 个线性无关的解向量&lt;/strong&gt;即构成一个基础解系。&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;3. 向量组的线性相关性&lt;/h3&gt;
&lt;p&gt;设向量组 $ \boldsymbol{\alpha}_1, \boldsymbol{\alpha}_2, \dots, \boldsymbol{\alpha}_s \in \mathbb{R}^n $，记矩阵&lt;br&gt;$$
A = [\boldsymbol{\alpha}_1\ \boldsymbol{\alpha}_2\ \dots\ \boldsymbol{\alpha}_s] \in \mathbb{R}^{n \times s}.
$$&lt;/p&gt;
&lt;h4&gt;3.1 线性相关与线性无关的等价刻画&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;线性相关&lt;/th&gt;
&lt;th&gt;线性无关&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;存在不全为零的常数 $ k_1, k_2, \dots, k_s $ 使得&lt;br /&gt;$ k_1\boldsymbol{\alpha}_1 + k_2\boldsymbol{\alpha}_2 + \dots + k_s\boldsymbol{\alpha}_s = \mathbf{0} $&lt;/td&gt;
&lt;td&gt;若 $ k_1\boldsymbol{\alpha}_1 + \dots + k_s\boldsymbol{\alpha}_s = \mathbf{0} $，则必有 $ k_1 = k_2 = \dots = k_s = 0 $&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;齐次方程组 $ A\mathbf{x} = \mathbf{0} $ 有非零解&lt;/td&gt;
&lt;td&gt;齐次方程组 $ A\mathbf{x} = \mathbf{0} $ 只有零解&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$ \text{rank}(A) &amp;lt; s $（列降秩）&lt;/td&gt;
&lt;td&gt;$ \text{rank}(A) = s $（列满秩）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向量组中&lt;strong&gt;至少有一个向量&lt;/strong&gt;可由其余向量线性表示&lt;/td&gt;
&lt;td&gt;向量组中&lt;strong&gt;任何向量&lt;/strong&gt;都不能由其余向量线性表示&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h4&gt;3.2 方阵情形（$ n = s $）&lt;/h4&gt;
&lt;p&gt;若 $ A \in \mathbb{R}^{s \times s} $ 为方阵，则&lt;br&gt;$$
\boxed{
\begin{aligned}
\boldsymbol{\alpha}_1, \dots, \boldsymbol{\alpha}_s \text{ 线性相关} &amp;amp;\iff \det A = 0, \
\boldsymbol{\alpha}_1, \dots, \boldsymbol{\alpha}_s \text{ 线性无关} &amp;amp;\iff \det A \ne 0.
\end{aligned}
}
$$&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;4. 向量组的线性表示&lt;/h3&gt;
&lt;h4&gt;4.1 单个向量的线性表示&lt;/h4&gt;
&lt;p&gt;向量 $ \boldsymbol{\beta} $ 可由向量组 $ {\boldsymbol{\alpha}_1, \boldsymbol{\alpha}_2, \dots, \boldsymbol{\alpha}_s} $ &lt;strong&gt;线性表出&lt;/strong&gt;（简称“线表”）&lt;br&gt;$$
\iff \text{方程组 } k_1\boldsymbol{\alpha}_1 + k_2\boldsymbol{\alpha}_2 + \dots + k_s\boldsymbol{\alpha}_s = \boldsymbol{\beta} \text{ 有解}
$$ 
$$
\iff \text{rank}[\boldsymbol{\alpha}_1\ \dots\ \boldsymbol{\alpha}_s] = \text{rank}[\boldsymbol{\alpha}_1\ \dots\ \boldsymbol{\alpha}_s\ \boldsymbol{\beta}]
$$&lt;/p&gt;
&lt;h4&gt;4.2 向量组之间的线性表示&lt;/h4&gt;
&lt;p&gt;设  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;向量组 (I)：$ \boldsymbol{\alpha}_1, \dots, \boldsymbol{\alpha}_r $  &lt;/li&gt;
&lt;li&gt;向量组 (II)：$ \boldsymbol{\beta}_1, \dots, \boldsymbol{\beta}_s $&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;关系&lt;/th&gt;
&lt;th&gt;等价条件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;(I) 可由 (II) 线表&lt;/td&gt;
&lt;td&gt;$ \text{rank}(\text{II}) = \text{rank}(\text{II}, \text{I}) $&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(II) 可由 (I) 线表&lt;/td&gt;
&lt;td&gt;$ \text{rank}(\text{I}) = \text{rank}(\text{I}, \text{II}) $&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(I) 与 (II) &lt;strong&gt;等价&lt;/strong&gt;（互相线表）&lt;/td&gt;
&lt;td&gt;$ \text{rank}(\text{I}) = \text{rank}(\text{II}) = \text{rank}(\text{I}, \text{II}) $&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h3&gt;5. 向量组的极大无关组与向量组的秩&lt;/h3&gt;
&lt;h4&gt;5.1 极大无关组定义&lt;/h4&gt;
&lt;p&gt;设向量组 $ U \subseteq \mathbb{R}^n $。&lt;br&gt;$ U $ 的一个&lt;strong&gt;极大线性无关组&lt;/strong&gt;（极大无关组）是满足以下条件的子集&lt;br&gt;$$
{\boldsymbol{\alpha}_1, \boldsymbol{\alpha}_2, \dots, \boldsymbol{\alpha}_r} \subseteq U:
$$&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;线性无关&lt;/strong&gt;：&lt;br&gt;$$
\boldsymbol{\alpha}_1, \boldsymbol{\alpha}_2, \dots, \boldsymbol{\alpha}_r \text{ 线性无关}.
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;极大性&lt;/strong&gt;：&lt;br&gt;$$
\forall \boldsymbol{\alpha} \in U,\ \boldsymbol{\alpha} \text{ 可由 } \boldsymbol{\alpha}_1, \dots, \boldsymbol{\alpha}_r \text{ 线性表示}.
$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;5.2 向量组的秩&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;若 $ U = {\mathbf{0}} $，规定&lt;br&gt;$$
r(U) = 0.
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;否则，定义&lt;br&gt;$$
r(U) = \text{极大无关组所含向量的个数}.
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;若 $ r(U) = r $，则&lt;br&gt;$$
\text{U 中任意 } r \text{ 个线性无关的向量都构成一个极大无关组}.
$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5.3 与矩阵秩的关系&lt;/h4&gt;
&lt;p&gt;对任意矩阵 $ A \in \mathbb{R}^{m \times n} $，有&lt;br&gt;$$
\boxed{r(A) = \text{列秩}(A) = \text{行秩}(A)}.
$$&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;6. 几个重要定理&lt;/h3&gt;
&lt;h4&gt;定理 1（唯一表示定理）&lt;/h4&gt;
&lt;p&gt;若向量组&lt;br&gt;$$
A={\boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2,\dots,\boldsymbol{\alpha}_r}
$$ 
线性无关，而&lt;br&gt;$$
B={\boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2,\dots,\boldsymbol{\alpha}_r,\boldsymbol{\beta}}
$$ 
线性相关，则&lt;br&gt;$$
\boldsymbol{\beta}\text{ 可由 }A\text{ 唯一线性表示}.
$$&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;定理 2（表示与个数）&lt;/h4&gt;
&lt;p&gt;设&lt;br&gt;$$
(\text{I})\ \boldsymbol{\alpha}_1,\dots,\boldsymbol{\alpha}_s;\qquad (\text{II})\ \boldsymbol{\beta}_1,\dots,\boldsymbol{\beta}_r,
$$ 
且 (I) 可由 (II) 线性表示，则&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;若 $ s&amp;gt;r $，则 (I) 必线性相关；  &lt;/li&gt;
&lt;li&gt;若 (I) 线性无关，则必有 $ s\le r $.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h4&gt;定理 3（秩的单调性）&lt;/h4&gt;
&lt;p&gt;若向量组 (I) 可由 (II) 线性表示，则&lt;br&gt;$$
r(\text{I})\le r(\text{II}).
$$ 
特别地，若 (I) 与 (II) 等价，则&lt;br&gt;$$
r(\text{I})=r(\text{II})\quad(\text{反之不成立}).
$$&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;定理 4（矩阵秩的不等式）&lt;/h4&gt;
&lt;p&gt;对任意适维矩阵&lt;br&gt;$$
A_{m\times n},; B_{n\times p},
$$ 
有&lt;br&gt;$$
r(AB)\le\min{r(A),,r(B)}.
$$ 
对同型矩阵&lt;br&gt;$$
A_{m\times n},; B_{m\times n},
$$ 
有&lt;br&gt;$$
r(A+B)\le r(A)+r(B).
$$&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;定理 5（Sylvester 秩不等式）&lt;/h4&gt;
&lt;p&gt;若&lt;br&gt;$$
A_{m\times n}B_{n\times p}=O,
$$ 
则&lt;br&gt;$$
r(A)+r(B)\le n.
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注：记 $ B=[\boldsymbol{b}_1,\dots,\boldsymbol{b}_p] $，则&lt;br&gt;$$
AB=O\Longrightarrow A\boldsymbol{b}_j=\mathbf{0},\ j=1,\dots,p,
$$ 
即 $ \boldsymbol{b}_j $ 均为齐次方程组 $ A\mathbf{x}=\mathbf{0} $ 的解。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Thu, 18 Dec 2025 00:00:00 GMT</pubDate></item><item><title>程序设计基础期末复习手册</title><link>https://dannyshi.pages.dev/blog/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E6%9C%9F%E6%9C%AB%E5%A4%8D%E4%B9%A0%E6%89%8B%E5%86%8C/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E6%9C%9F%E6%9C%AB%E5%A4%8D%E4%B9%A0%E6%89%8B%E5%86%8C/</guid><description>程序设计基础</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E6%9C%9F%E6%9C%AB%E5%A4%8D%E4%B9%A0%E6%89%8B%E5%86%8C/&quot;&gt;https://dannyshi.pages.dev/blog/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E6%9C%9F%E6%9C%AB%E5%A4%8D%E4%B9%A0%E6%89%8B%E5%86%8C/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇更适合作为考试前快速翻阅的手册，而不是系统教程。建议按“输入输出 -&gt; 字符串 -&gt; 指针/数组 -&gt; 常见陷阱”的思路查阅。
&lt;/Info&gt;

&lt;h1&gt;C语言期末考试速查手册&lt;/h1&gt;
&lt;h2&gt;一、输入输出技巧&lt;/h2&gt;
&lt;h3&gt;1. 多种输入方式&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 1. 基础输入
int n;
scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);

// 2. 字符串输入（无空格）
char str[20];
scanf(&amp;quot;%s&amp;quot;, str);  // 遇到空格停止

// 3. 字符串输入（含空格）
char str[100];
fgets(str, sizeof(str), stdin);
str[strcspn(str, &amp;quot;\n&amp;quot;)] = &amp;#39;\0&amp;#39;;  // 去掉换行符

// 4. 读取整行直到换行符
char line[100];
scanf(&amp;quot;%[^\n]&amp;quot;, line);  // 读取直到换行符
getchar();  // 吃掉换行符
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 格式化输出&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 控制宽度和对齐
printf(&amp;quot;%-10s %5d\n&amp;quot;, &amp;quot;Name&amp;quot;, 100);  // 左对齐，宽度10
printf(&amp;quot;%10s %5d\n&amp;quot;, &amp;quot;Name&amp;quot;, 100);   // 右对齐，宽度10
printf(&amp;quot;%.2f\n&amp;quot;, 3.14159);           // 保留2位小数
printf(&amp;quot;%05d\n&amp;quot;, 42);                // 补零到5位：00042
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、字符串处理&lt;/h2&gt;
&lt;h3&gt;1. 常用函数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;string.h&amp;gt;

// 长度
int len = strlen(str);

// 复制
strcpy(dest, src);        // 不安全，可能溢出
strncpy(dest, src, n);    // 安全，最多复制n个字符

// 连接
strcat(dest, src);        // 不安全
strncat(dest, src, n);    // 安全

// 比较
int cmp = strcmp(s1, s2);  // 相等返回0，s1&amp;gt;s2返回正数
int cmp = strncmp(s1, s2, n);  // 比较前n个字符

// 查找
char *p = strchr(str, &amp;#39;a&amp;#39;);     // 查找字符第一次出现
char *p = strrchr(str, &amp;#39;a&amp;#39;);    // 查找字符最后一次出现
char *p = strstr(str, &amp;quot;abc&amp;quot;);   // 查找子串
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 字符串分割&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 方法1：strtok
char str[] = &amp;quot;apple,banana,orange&amp;quot;;
char *token = strtok(str, &amp;quot;,&amp;quot;);
while (token != NULL) {
    printf(&amp;quot;%s\n&amp;quot;, token);
    token = strtok(NULL, &amp;quot;,&amp;quot;);
}

// 方法2：sscanf
char data[] = &amp;quot;John 25 85.5&amp;quot;;
char name[20];
int age;
float score;
sscanf(data, &amp;quot;%s %d %f&amp;quot;, name, &amp;amp;age, &amp;amp;score);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 字符串转换&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;

// 字符串转数字
int num = atoi(&amp;quot;123&amp;quot;);          // ASCII to integer
long lnum = atol(&amp;quot;123456&amp;quot;);     // ASCII to long
float fnum = atof(&amp;quot;3.14&amp;quot;);      // ASCII to float

// 更安全的转换
int num = strtol(str, NULL, 10);     // 10表示十进制
float fnum = strtof(str, NULL);

// 数字转字符串
char buffer[20];
sprintf(buffer, &amp;quot;%d&amp;quot;, 123);          // 整数转字符串
sprintf(buffer, &amp;quot;%.2f&amp;quot;, 3.14159);    // 浮点数转字符串
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、数组操作&lt;/h2&gt;
&lt;h3&gt;1. 一维数组&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 遍历
int arr[10];
for (int i = 0; i &amp;lt; 10; i++) {
    arr[i] = i * 2;
}

// 逆序
void reverse(int arr[], int n) {
    for (int i = 0; i &amp;lt; n / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[n-1-i];
        arr[n-1-i] = temp;
    }
}

// 查找最大最小值
void find_min_max(int arr[], int n, int *min, int *max) {
    *min = *max = arr[0];
    for (int i = 1; i &amp;lt; n; i++) {
        if (arr[i] &amp;lt; *min) *min = arr[i];
        if (arr[i] &amp;gt; *max) *max = arr[i];
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 二维数组&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 遍历
int matrix[3][4];
for (int i = 0; i &amp;lt; 3; i++) {
    for (int j = 0; j &amp;lt; 4; j++) {
        matrix[i][j] = i * 4 + j;
    }
}

// 矩阵转置
void transpose(int src[][N], int dest[][M], int m, int n) {
    for (int i = 0; i &amp;lt; m; i++) {
        for (int j = 0; j &amp;lt; n; j++) {
            dest[j][i] = src[i][j];
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、结构体与指针&lt;/h2&gt;
&lt;h3&gt;1. 结构体定义与使用&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 定义
typedef struct {
    char name[20];
    int age;
    float score;
} Student;

// 初始化
Student s1 = {&amp;quot;Alice&amp;quot;, 20, 85.5};
Student s2;
strcpy(s2.name, &amp;quot;Bob&amp;quot;);
s2.age = 21;
s2.score = 90.0;

// 结构体数组
Student class[30];
for (int i = 0; i &amp;lt; 30; i++) {
    scanf(&amp;quot;%s %d %f&amp;quot;, class[i].name, &amp;amp;class[i].age, &amp;amp;class[i].score);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 指针操作&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 基本指针
int a = 10;
int *p = &amp;amp;a;
printf(&amp;quot;%d\n&amp;quot;, *p);  // 输出10

// 指针与数组
int arr[5] = {1,2,3,4,5};
int *ptr = arr;  // ptr指向arr[0]
printf(&amp;quot;%d\n&amp;quot;, *(ptr+2));  // 输出arr[2]=3

// 结构体指针
Student s;
Student *sp = &amp;amp;s;
sp-&amp;gt;age = 20;      // 等价于 (*sp).age = 20
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、动态内存管理&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;

// 一维数组
int *arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
    printf(&amp;quot;内存分配失败\n&amp;quot;);
    exit(1);
}
// 使用...
free(arr);

// 二维数组
int **matrix = (int**)malloc(rows * sizeof(int*));
for (int i = 0; i &amp;lt; rows; i++) {
    matrix[i] = (int*)malloc(cols * sizeof(int));
}
// 使用...
for (int i = 0; i &amp;lt; rows; i++) {
    free(matrix[i]);
}
free(matrix);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、常用算法模板&lt;/h2&gt;
&lt;h3&gt;1. 排序算法&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 冒泡排序
void bubble_sort(int arr[], int n) {
    for (int i = 0; i &amp;lt; n-1; i++) {
        for (int j = 0; j &amp;lt; n-1-i; j++) {
            if (arr[j] &amp;gt; arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

// 选择排序
void selection_sort(int arr[], int n) {
    for (int i = 0; i &amp;lt; n-1; i++) {
        int min_idx = i;
        for (int j = i+1; j &amp;lt; n; j++) {
            if (arr[j] &amp;lt; arr[min_idx]) {
                min_idx = j;
            }
        }
        int temp = arr[i];
        arr[i] = arr[min_idx];
        arr[min_idx] = temp;
    }
}

// 插入排序
void insertion_sort(int arr[], int n) {
    for (int i = 1; i &amp;lt; n; i++) {
        int key = arr[i];
        int j = i-1;
        while (j &amp;gt;= 0 &amp;amp;&amp;amp; arr[j] &amp;gt; key) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 查找算法&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 顺序查找
int linear_search(int arr[], int n, int target) {
    for (int i = 0; i &amp;lt; n; i++) {
        if (arr[i] == target) {
            return i;
        }
    }
    return -1;
}

// 二分查找（要求数组有序）
int binary_search(int arr[], int n, int target) {
    int left = 0, right = n-1;
    while (left &amp;lt;= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] &amp;lt; target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、数学计算&lt;/h2&gt;
&lt;h3&gt;1. 常用数学函数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;math.h&amp;gt;

// 绝对值
int a = abs(-10);          // 整数绝对值
double b = fabs(-3.14);    // 浮点数绝对值

// 幂运算
double result = pow(2, 3);     // 2³ = 8
double sqrt_val = sqrt(16);    // √16 = 4

// 三角函数（参数为弧度）
double sin_val = sin(3.14159/2);   // sin(90°) = 1
double cos_val = cos(0);           // cos(0°) = 1

// 对数
double log_e = log(2.71828);       // 自然对数ln
double log_10 = log10(100);        // 以10为底

// 取整
double ceil_val = ceil(3.14);      // 向上取整 = 4
double floor_val = floor(3.14);    // 向下取整 = 3
double round_val = round(3.5);     // 四舍五入 = 4
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 最大公约数与最小公倍数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 辗转相除法求最大公约数
int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// 最小公倍数
int lcm(int a, int b) {
    return a / gcd(a, b) * b;  // 先除后乘防止溢出
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 素数判断&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;math.h&amp;gt;

int is_prime(int n) {
    if (n &amp;lt;= 1) return 0;
    if (n == 2) return 1;
    if (n % 2 == 0) return 0;
    
    for (int i = 3; i &amp;lt;= sqrt(n); i += 2) {
        if (n % i == 0) return 0;
    }
    return 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、文件操作&lt;/h2&gt;
&lt;h3&gt;1. 基本文件操作&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;stdio.h&amp;gt;

// 打开文件
FILE *fp = fopen(&amp;quot;data.txt&amp;quot;, &amp;quot;r&amp;quot;);  // 模式：r(读), w(写), a(追加)

if (fp == NULL) {
    printf(&amp;quot;打开文件失败\n&amp;quot;);
    return 1;
}

// 读写操作
fprintf(fp, &amp;quot;Hello %d\n&amp;quot;, 123);      // 写入格式化数据
fscanf(fp, &amp;quot;%s %d&amp;quot;, str, &amp;amp;num);      // 读取格式化数据

fputs(&amp;quot;Hello\n&amp;quot;, fp);                // 写入字符串
fgets(buffer, sizeof(buffer), fp);   // 读取一行

char ch = fgetc(fp);                 // 读取一个字符
fputc(&amp;#39;A&amp;#39;, fp);                      // 写入一个字符

// 关闭文件
fclose(fp);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 常用文件操作模式&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&amp;quot;r&amp;quot;&lt;/td&gt;
&lt;td&gt;只读，文件必须存在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;quot;w&amp;quot;&lt;/td&gt;
&lt;td&gt;只写，创建新文件/清空原有文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;quot;a&amp;quot;&lt;/td&gt;
&lt;td&gt;追加，在文件末尾添加&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;quot;r+&amp;quot;&lt;/td&gt;
&lt;td&gt;读写，文件必须存在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;quot;w+&amp;quot;&lt;/td&gt;
&lt;td&gt;读写，创建新文件/清空原有文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;quot;a+&amp;quot;&lt;/td&gt;
&lt;td&gt;读写，在文件末尾添加&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;九、实用技巧&lt;/h2&gt;
&lt;h3&gt;1. 清除输入缓冲区&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 清除所有残留字符
void clear_input_buffer() {
    int c;
    while ((c = getchar()) != &amp;#39;\n&amp;#39; &amp;amp;&amp;amp; c != EOF);
}

// 使用示例
int n;
scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);
clear_input_buffer();  // 清除换行符
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 交换两个数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 方法1：使用临时变量
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 方法2：不使用临时变量（仅整数）
void swap_xor(int *a, int *b) {
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 生成随机数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

// 初始化随机种子（只需调用一次）
srand(time(NULL));

// 生成随机数
int random_num = rand();               // 0到RAND_MAX之间
int range_random = rand() % 100;       // 0-99
int min_max_random = 10 + rand() % 91; // 10-100
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;十、常见错误与调试&lt;/h2&gt;
&lt;h3&gt;1. 编译错误&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 错误1：未声明的标识符
printf(&amp;quot;%d\n&amp;quot;, x);  // 如果x未声明

// 错误2：类型不匹配
int *p = 10;        // 应该：int *p = &amp;amp;a;

// 错误3：缺少分号
int a = 10          // 缺少分号
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 运行时错误&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 错误1：数组越界
int arr[5];
arr[5] = 10;  // 越界访问

// 错误2：除零错误
int result = 10 / 0;

// 错误3：使用未初始化指针
int *p;
*p = 10;  // 野指针

// 错误4：内存泄漏
int *p = malloc(100);
// 忘记free(p);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 调试技巧&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 1. 使用printf调试
printf(&amp;quot;调试：a=%d, b=%d\n&amp;quot;, a, b);

// 2. 条件编译调试
#ifdef DEBUG
    printf(&amp;quot;调试信息：x=%d\n&amp;quot;, x);
#endif

// 编译时：gcc -DDEBUG program.c

// 3. 使用assert
#include &amp;lt;assert.h&amp;gt;
assert(x &amp;gt; 0);  // 如果x&amp;lt;=0，程序会终止并报错
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Sun, 07 Dec 2025 00:00:00 GMT</pubDate></item><item><title>Paper Reading Week4</title><link>https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week4/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week4/</guid><description>12/01-12/07</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week4/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week4/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇延续了大模型轻量化主题，`SmoothQuant` 是后训练量化里非常常被提到的一篇。适合和上周的 `SpinQuant` 对照着读。
&lt;/Info&gt;

&lt;p&gt;近期准备系统的阅读一些关于&lt;strong&gt;大模型轻量化&lt;/strong&gt;的论文，在这里开个新坑。&lt;/p&gt;
&lt;details&gt;
  &lt;summary&gt;怎么和 Week3 对照阅读&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;`SmoothQuant` 更强调激活与权重之间的缩放迁移。&lt;/li&gt;
    &lt;li&gt;`SpinQuant` 更强调通过旋转降低量化难度。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h1&gt;论文信息&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2211.10438&quot;&gt;Arxiv ID&lt;/a&gt;
&lt;a href=&quot;https://hjfy.top/arxiv/2211.10438&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Title:&lt;strong&gt;SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models (ICML 2023)&lt;/strong&gt;&lt;/h2&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Thu, 04 Dec 2025 00:00:00 GMT</pubDate></item><item><title>Paper Reading Week3</title><link>https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week3/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week3/</guid><description>11/24-11/30</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week3/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week3/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这周开始进入大模型量化主题。`SpinQuant` 的关键词是 learned rotations，阅读时可以一直盯着“它到底在帮量化误差解决什么问题”。
&lt;/Info&gt;

&lt;h1&gt;论文信息&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2405.16406&quot;&gt;Arxiv ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hjfy.top/arxiv/2405.16406&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Title:&lt;strong&gt;SpinQuant: LLM Quantization with Learned Rotations SpinQuant : 带有学成旋转的 LLM 量化&lt;/strong&gt;&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;Part I: Foundation and Motivation&lt;/h2&gt;
&lt;h3&gt;1. 当前研究目标与挑战&lt;/h3&gt;
&lt;details&gt;
  &lt;summary&gt;阅读建议&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;先看问题背景和量化痛点，再回到方法细节。&lt;/li&gt;
    &lt;li&gt;如果第一次接触 PTQ，可以优先理解“为什么激活异常值会影响量化”。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;目标&lt;/strong&gt;：将大型语言模型（LLMs）从 16 位浮点数 (FP16) 转换到 4 位整数 (INT4)，以大幅减少模型大小（$4\times$ 压缩）并提高推理速度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;挑战&lt;/strong&gt;：LLMs 基于 &lt;strong&gt;Transformer&lt;/strong&gt; 架构，其内部存在大量 &lt;strong&gt;异常值 (Outliers)&lt;/strong&gt;，特别是经过 &lt;strong&gt;FFN&lt;/strong&gt; 模块的非线性激活函数后。这些 Outliers 会导致量化精度急剧下降。&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FFN (Feed-Forward Network)&lt;/strong&gt;：负责对每个 Token 的特征进行非线性提炼，是模型中参数量最大的部分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LayerNorm / RoPE&lt;/strong&gt;：这些结构虽然帮助模型稳定训练（如 LayerNorm），但它们的输出分布依然可能产生 Outliers。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. The Pre-SpinQuant Idea&lt;/h3&gt;
&lt;p&gt;为了解决 Outliers 问题，前人提出了一种思路：&lt;strong&gt;旋转平滑&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：Outliers 往往集中在特征向量的少数几个通道上。如果能对向量进行一次 &lt;strong&gt;空间旋转&lt;/strong&gt;，这些 Outliers 的能量就会被分散（摊平）到所有通道上，使数据分布变得更像“高斯分布”或至少更均匀，从而更适合量化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;传统做法&lt;/strong&gt;：之前的尝试（如 QuaRot）使用 &lt;strong&gt;随机&lt;/strong&gt; 或 &lt;strong&gt;固定的&lt;/strong&gt; 正交矩阵（如 Hadamard 矩阵）进行旋转。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. The Insight&lt;/h3&gt;
&lt;p&gt;SpinQuant 通过实验发现了一个关键事实：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“不同的随机旋转矩阵会导致高达 13 个百分点的下游任务精度差异。”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个发现表明，&lt;strong&gt;旋转矩阵的选择是至关重要的。&lt;/strong&gt; 既然随机旋转的风险太大，一个自然的想法产生了：那么为什么不通过优化算法，&lt;strong&gt;学习&lt;/strong&gt; 出一个能使量化误差最小的 &lt;strong&gt;最优旋转矩阵 $R$&lt;/strong&gt; 呢？&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Part II: Core Method&lt;/h2&gt;
&lt;p&gt;SpinQuant 的核心是 &lt;strong&gt;在保持模型功能不变的前提下，优化数据分布&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;1. Basic：Rotational Invariance 旋转不变性&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.5xb2phzfld.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;对于 Transformer 中的任何线性层（矩阵乘法）$Y = X W$：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$X$：输入激活值矩阵。&lt;/li&gt;
&lt;li&gt;$W$：权重矩阵。&lt;/li&gt;
&lt;li&gt;$R$：我们引入的 &lt;strong&gt;正交旋转矩阵&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们同时对 $X$ 和 $W$ 进行变换：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;旋转激活值&lt;/strong&gt;：$X&amp;#39; = X R$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逆旋转权重&lt;/strong&gt;：$W&amp;#39; = R^{-1} W$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;将它们代入计算：
$$Y&amp;#39; = X&amp;#39; W&amp;#39; = (X R) (R^{-1} W) = X (R R^{-1}) W$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键约束&lt;/strong&gt;：为了保证 $Y&amp;#39; = Y$，我们要求 $R$ 必须是 &lt;strong&gt;正交矩阵&lt;/strong&gt;，即 $R^{-1} = R^T$。
$$\implies Y&amp;#39; = X (R R^T) W = X (I) W = X W = Y$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;：在全精度下，新的 $Y&amp;#39;$ 严格等于 $Y$。这允许我们 &lt;strong&gt;离线 (Offline)&lt;/strong&gt; 计算 $W&amp;#39; = R^T W$，用 $W&amp;#39;$ 替换原始 $W$，而不引入额外的推理开销。&lt;/p&gt;
&lt;h3&gt;2. Cayley SGD&lt;/h3&gt;
&lt;p&gt;由于 $R$ 必须满足 $R R^T = I$ 的 &lt;strong&gt;正交约束&lt;/strong&gt;，我们不能使用传统的 SGD。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;挑战&lt;/strong&gt;：传统的 SGD 更新 $R \leftarrow R - \eta \nabla R$ 会使得 $R$ 失去正交性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：使用 &lt;strong&gt;Cayley SGD&lt;/strong&gt;（一种流形优化算法）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cayley SGD 的核心思想&lt;/strong&gt;：
它通过 Cayley 变换，确保每一步梯度更新后，新的矩阵 $R&amp;#39;$ 仍然严格保持在 &lt;strong&gt;正交矩阵的空间&lt;/strong&gt;（Stiefel 流形）内。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Simplified:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;计算梯度 $G = \nabla_R \mathcal{L}$。&lt;/li&gt;
&lt;li&gt;构造一个&lt;strong&gt;反对称矩阵&lt;/strong&gt; $Y$（满足 $Y^T = -Y$）：
$$Y \propto G R^T - R G^T$$&lt;/li&gt;
&lt;li&gt;应用 &lt;strong&gt;Cayley 变换&lt;/strong&gt; 进行更新：
$$R&amp;#39; = (I - \frac{\alpha}{2} Y)^{-1} (I + \frac{\alpha}{2} Y) R$$&lt;ul&gt;
&lt;li&gt;（其中 $\alpha$ 是学习率）。&lt;/li&gt;
&lt;li&gt;这个公式保证了 $R&amp;#39;$ 始终是正交的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. 目标函数 (Loss Function)&lt;/h3&gt;
&lt;p&gt;优化目标是最小化量化后模型的输出与全精度模型输出之间的误差：
$$\arg \min_{R} || \text{Logits}&lt;em&gt;{\text{FP16}} - \text{Logits}&lt;/em&gt;{\text{Quant}}(R) ||_2$$
只需要使用少量校准数据，对 $R$ 进行数百步的微小优化即可。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Part III: Architecture &amp;amp; Deployment&lt;/h2&gt;
&lt;p&gt;SpinQuant 在 Transformer Pipeline 中设置了四种旋转矩阵$R_1 R_2 R_3 R_4$
&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.9gx0faw5tf.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;1. 离线可吸收旋转 ($R_1, R_2$)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;矩阵&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;作用位置&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;目的&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;部署方式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;推理开销&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;$R_1$&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;残差流&lt;/strong&gt; (Block 输入)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;平滑最主要的激活值 Outliers。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;离线融合&lt;/strong&gt;进 $W_q, W_k, W_v$ 和 FFN 的 $W_{up}$ 中。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;零开销&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;$R_2$&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MHA 内部&lt;/strong&gt; ($V \rightarrow W_o$)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;进一步优化 Attention 内部的量化。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;离线融合&lt;/strong&gt;进 $W_o$ 权重中。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;零开销&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;在推理时，模型无需执行 $R_1$ 或 $R_2$ 的乘法，因为它们的逆 $R^T$ 已经编码到了权重中。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 在线计算旋转 ($R_3, R_4$)&lt;/h3&gt;
&lt;p&gt;这些矩阵无法被融合，必须在运行时计算，但它们被强制约束为 &lt;strong&gt;Hadamard 矩阵&lt;/strong&gt;，以实现高效计算。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.2vf6oa2sgs.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;矩阵&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;作用位置&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;目的&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;推理机制&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;关键技术&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;$R_3$&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;KV Cache 存入前&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;实现 &lt;strong&gt;4-bit KV Cache&lt;/strong&gt; 的极致压缩。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;在线计算 (Online)&lt;/strong&gt;。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;快速 Walsh-Hadamard 变换 (FWHT)&lt;/strong&gt;，复杂度 $O(N \log N)$。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;$R_4$&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;FFN 激活之后&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;处理非线性激活（SiLU/GeLU）产生的巨大 Outliers。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;在线计算 (Online)&lt;/strong&gt;。&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;FWHT，保证 FFN 激活值的 A4 精度。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Part IV: Results and Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://lnscq.github.io/picx-images-hosting/image.8dxb4fdcuf.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;1. W4A4KV4 极限量化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;strong&gt;LLaMA-2 7B&lt;/strong&gt; 模型上，实现 &lt;strong&gt;权重、激活值、KV Cache 全部 4-bit 量化&lt;/strong&gt; (W4A4KV4)。&lt;/li&gt;
&lt;li&gt;零样本推理任务的精度差距：&lt;strong&gt;仅 2.9 个百分点&lt;/strong&gt;（与 FP16 相比）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;baseline&lt;/strong&gt;：&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM-QAT&lt;/strong&gt;：差距高达 22.0 个百分点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SmoothQuant&lt;/strong&gt;：差距高达 25.0 个百分点（在 A4 场景下失效）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;QuaRot&lt;/strong&gt;：差距远大于 15 个百分点。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 结论&lt;/h3&gt;
&lt;p&gt;SpinQuant 将 &lt;strong&gt;流形优化&lt;/strong&gt; 引入了 &lt;strong&gt;PTQ&lt;/strong&gt; 领域。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;突破&lt;/strong&gt;：证明了通过学习最优旋转是实现 LLM 全链路 4-bit 极限量化的关键，效果远超硬编码规则（SmoothQuant）和随机方法（QuaRot）。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate></item><item><title>Paper Reading Week2</title><link>https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week2/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week2/</guid><description>10/27-11/03</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week2/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week2/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇周报主要围绕“生成模型 + 强化学习”展开。前一篇偏训练机制创新，后一篇偏系统架构设计，放在一起读会比较容易看出当前多模态生成研究的两个发力方向。
&lt;/Info&gt;

&lt;h1&gt;论文信息&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2505.05470&quot;&gt;Arxiv ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hjfy.top/arxiv/2505.05470&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Title:&lt;strong&gt;Flow-GRPO: Training Flow Matching Models via Online RL Flow-GRPO训练流匹配模型通过在线强化学习&lt;/strong&gt;&lt;/h2&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;strong&gt;1. Introduction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;介绍Flow matching的强大性能，并提出问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;然而,它们在涉及多个对象、属性和关系的复杂场景组合以及文本渲染方面往往存在困难。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;作者提出将在线强化学习（RL）引入到生成模型中，并列举出一些挑战：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流模型依赖于基于常微分方程 (ODEs)的确定性生成过程,这意味着它们在推理期间无法进行随机采样。&lt;/li&gt;
&lt;li&gt;在线 RL 需要高效的采样以收集训练 数据,但流模型通常需要许多迭代步骤来生成每个样本,显著降低了采样效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;研究提出了&lt;strong&gt;Flow-GRPO&lt;/strong&gt;，将GRPO整合到Flow matching模型中，提出了两种关键策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;采用ODE-to-SDE策略，克服了原始flow matching模型的确定性，将ODE转换为等效的随机微分方程，在保留原始边缘分布的前提下引入随机性&lt;/li&gt;
&lt;li&gt;应用&lt;strong&gt;降噪减少&lt;/strong&gt;策略，提到在线RL中的采样效率，即在训练期间减少模型的降噪步骤，在推理阶段保持完整的调度。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;2. Background&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;LLM的强化学习：
在线强化学习已被证明在提升大型语言模型(LLMs)的推理能力方  面非常有效，如近端策略优化(PPO) 和无价值组相对策略优化(GRPO)，这篇工作采用GRPO以节省内存。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;diffusion &amp;amp; flow matching 模型 &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;T2l对齐&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3.Flow-GRPO&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.3uv8uuja38.webp&quot; alt=&quot;对比图片&quot;&gt;&lt;/p&gt;
&lt;p&gt;受到GRPO算法的启发，通过在线强化学习来改进模型&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;4. Experiment&lt;/strong&gt;&lt;/h3&gt;
&lt;details&gt;
  &lt;summary&gt;阅读提示&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;看 `Flow-GRPO` 时，重点关注“如何把原本确定性的 flow matching 变成可用于在线 RL 的随机过程”。&lt;/li&gt;
    &lt;li&gt;看 `Dual-Process Image Generation` 时，重点关注系统 1 / 系统 2 的职责切分，而不只是图像质量本身。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h1&gt;论文信息&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2506.01955&quot;&gt;Arxiv ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hjfy.top/arxiv/2506.01955&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Title:&lt;strong&gt;Dual-Process Image Generation 双过程图像生成&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1. Introduction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;当前的大型语言模型在多个领域展现出卓越能力，并具备上下文学习新任务的能力。然而，当它们被训练为多模态模型以联合生成图像和文本时，要么无法达到仅生成图像的保真度，要么难以供学术研究实验使用。相比之下，当代图像生成模型在视觉质量上已接近照片级效果，但与之交互仍常令人沮丧。&lt;/p&gt;
&lt;p&gt;受认知科学中双过程理论的启发，该研究提出一种双过程架构，将一个知识丰富的多模态语言模型（VLM，作为“系统2”或“审慎过程”）与一个视觉精确的图像生成器（作为“系统1”或“反射过程”）相结合。该架构通过VLM对生成图像进行评分，并将梯度反向传播以更新图像生成器的权重，从而实现对图像生成过程的精细化控制。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. Background&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;分类器引导&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;推理时搜索&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;模型微调&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VQA 评分：与 CLIP 相比, VLM 提供了更准确且可解释的评分框架。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3.双过程蒸馏&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.9rjt1vofme.webp&quot; alt=&quot;对比图片&quot;&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;4. Experiment&lt;/strong&gt;&lt;/h3&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Wed, 29 Oct 2025 00:00:00 GMT</pubDate></item><item><title>贪吃蛇增强版 - 答辩报告</title><link>https://dannyshi.pages.dev/blog/ai%E8%AF%95%E7%82%B9%E7%8F%AD%E4%BD%9C%E4%B8%9A%E6%8A%A5%E5%91%8A%E8%B4%AA%E5%90%83%E8%9B%87/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/ai%E8%AF%95%E7%82%B9%E7%8F%AD%E4%BD%9C%E4%B8%9A%E6%8A%A5%E5%91%8A%E8%B4%AA%E5%90%83%E8%9B%87/</guid><description>程序设计基础（ai试点班）</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/ai%E8%AF%95%E7%82%B9%E7%8F%AD%E4%BD%9C%E4%B8%9A%E6%8A%A5%E5%91%8A%E8%B4%AA%E5%90%83%E8%9B%87/&quot;&gt;https://dannyshi.pages.dev/blog/ai%E8%AF%95%E7%82%B9%E7%8F%AD%E4%BD%9C%E4%B8%9A%E6%8A%A5%E5%91%8A%E8%B4%AA%E5%90%83%E8%9B%87/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇偏项目展示和答辩说明，适合让读者先快速建立“项目做了什么、亮点在哪、实现复杂度如何”的整体印象。
&lt;/Info&gt;

&lt;h1&gt;贪吃蛇增强版 - 答辩报告&lt;/h1&gt;
&lt;h2&gt;🎯 项目概述&lt;/h2&gt;
&lt;h3&gt;项目背景&lt;/h3&gt;
&lt;p&gt;贪吃蛇是一款经典的电子游戏，自1976年诞生以来广受欢迎。本项目在传统贪吃蛇游戏的基础上，增加了多种创新元素，形成了 &lt;strong&gt;&amp;quot;加速扩张＆当心炸弹&amp;quot;&lt;/strong&gt; 的独特游戏体验。&lt;/p&gt;
&lt;h3&gt;开发环境&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开发语言&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;C语言&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;编译器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GCC 9.4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开发工具&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DEV-C++&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;操作系统&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows 11 家庭版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;图形库&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows Console API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;版本控制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Git&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;🎮 游戏规则详解&lt;/h2&gt;
&lt;h3&gt;基本规则&lt;/h3&gt;
&lt;h4&gt;游戏目标&lt;/h4&gt;
&lt;p&gt;玩家控制一条不断移动的蛇，在封闭的游戏区域内：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过吃掉随机出现的食物获得分数&lt;/li&gt;
&lt;li&gt;每吃一个食物，蛇身增长一节，得分增加10分&lt;/li&gt;
&lt;li&gt;避免撞到墙壁、自己的身体或移动的炸弹&lt;/li&gt;
&lt;li&gt;尽可能获得更高的分数&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;控制方式&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;按键&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;W&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;向上移动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;向下移动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;向左移动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;D&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;向右移动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Q&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;退出游戏&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;重要提示&lt;/strong&gt;：蛇不能直接反向移动！例如，当蛇向右移动时，不能直接按A键向左移动。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;游戏元素说明&lt;/h3&gt;
&lt;h4&gt;视觉元素&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;蛇头&lt;/strong&gt;：■（绿色实心方块）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;蛇身&lt;/strong&gt;：□（绿色空心方块）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;食物&lt;/strong&gt;：●（红色实心圆）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;炸弹&lt;/strong&gt;：B（黄色字母）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;边界&lt;/strong&gt;：+ - |（青色线条）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;游戏机制&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;移动机制&lt;/strong&gt;：蛇按当前方向自动移动，玩家通过按键改变方向&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成长机制&lt;/strong&gt;：每吃一个食物，蛇身增加一节，得分增加10分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;速度机制&lt;/strong&gt;：游戏速度随时间逐渐加快，增加挑战性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;炸弹机制&lt;/strong&gt;：随机生成的炸弹在场内移动，增加游戏难度&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;死亡判定&lt;/h3&gt;
&lt;p&gt;当发生以下情况时，游戏结束：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🚫 &lt;strong&gt;撞墙死亡&lt;/strong&gt;：蛇头撞到场地边界&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;自噬死亡&lt;/strong&gt;：蛇头撞到自己的身体&lt;/li&gt;
&lt;li&gt;💥 &lt;strong&gt;炸弹爆炸&lt;/strong&gt;：蛇头撞到移动的炸弹&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;✨ 自定义新规则：&amp;quot;加速扩张＆当心炸弹&amp;quot;&lt;/h2&gt;
&lt;h3&gt;规则概述&lt;/h3&gt;
&lt;p&gt;在传统贪吃蛇基础上，引入&lt;strong&gt;动态速度递增&lt;/strong&gt;与&lt;strong&gt;移动炸弹威胁&lt;/strong&gt;两大机制，形成高强度对抗体验。&lt;/p&gt;
&lt;h3&gt;加速扩张机制&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;游戏启动后，每经过50个游戏周期（约10秒），全局速度提升一次&lt;/li&gt;
&lt;li&gt;每次速度提升减少5ms帧间隔，下限为50ms&lt;/li&gt;
&lt;li&gt;随着速度加快，蛇身扩张节奏被迫提速，操作容错率持续下降&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;移动炸弹机制&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;炸弹以字母&lt;strong&gt;B&lt;/strong&gt;标识，亮黄色显示，每5帧随机改变方向并移动一格&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成规则&lt;/strong&gt;：当场无炸弹时，每帧有1/30概率在空地生成一枚炸弹&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;碰撞判定&lt;/strong&gt;：蛇头一旦撞到炸弹，立即触发&amp;quot;炸弹爆炸&amp;quot;死亡&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;清除方式&lt;/strong&gt;：当蛇吃到普通食物时，有1/3概率清除当前炸弹（奖励式减压）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;关键常量与变量&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 速度控制
int gameSpeed;                    // 当前帧间隔(ms)
int speedIncreaseTimer;           // 已运行周期计数
#define SPEED_INCREASE_INTERVAL 50
#define MIN_GAME_SPEED 50

// 炸弹控制
int bombX, bombY;                 // 炸弹坐标
int bombActive;                   // 是否在场
int bombDirection;                // 当前方向
int bombMoveTimer;                // 移动计数器
#define BOMB_MOVE_INTERVAL 5
#define BOMB_SPAWN_CHANCE 30      // 分母
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;核心逻辑嵌入点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;速度提升&lt;/strong&gt;：在&lt;code&gt;updateWithoutInput()&lt;/code&gt;中每50周期执行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;炸弹生成&lt;/strong&gt;：同函数内随机触发&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;炸弹移动&lt;/strong&gt;：每5帧调用&lt;code&gt;moveBomb()&lt;/code&gt;，碰壁则随机换向&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;炸弹清除&lt;/strong&gt;：在&lt;code&gt;moveSnake()&lt;/code&gt;吃到食物分支内概率清除&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;🖥️ 游戏界面展示&lt;/h2&gt;
&lt;h3&gt;游戏主界面&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/%E5%9B%BE%E4%BE%8B%E5%B1%95%E7%A4%BA.9kgkku1vyk.webp&quot; alt=&quot;主界面&quot;&gt;&lt;/p&gt;
&lt;h3&gt;游戏结束界面&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;游戏结束！ 最终得分：10
死亡原因：炸弹爆炸
按任意键退出...
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;👥 分工合作说明&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;成员姓名&lt;/th&gt;
&lt;th&gt;负责模块&lt;/th&gt;
&lt;th&gt;具体贡献&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;石澄錡&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• 核心游戏逻辑&lt;br /&gt;• 蛇的移动控制&lt;br /&gt;• 碰撞检测系统&lt;br /&gt;• 基础界面绘制&lt;/td&gt;
&lt;td&gt;• 实现蛇的数据结构设计和移动算法&lt;br /&gt;• 开发完整碰撞检测系统&lt;br /&gt;• 编写游戏主循环逻辑&lt;br /&gt;• 完成基础绘图函数&lt;br /&gt;• 代码量：约400行&lt;br /&gt;• 占总工作量：65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;贾锡昶&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• 加速系统&lt;br /&gt;• 炸弹系统&lt;br /&gt;• 特效和动画&lt;br /&gt;• 用户界面优化&lt;br /&gt;• 测试和调试&lt;/td&gt;
&lt;td&gt;• 设计并实现随时间加速的完整机制&lt;br /&gt;• 开发移动炸弹系统&lt;br /&gt;• 实现闪烁效果和颜色切换&lt;br /&gt;• 优化界面显示和用户体验&lt;br /&gt;• 进行全面测试和bug修复&lt;br /&gt;• 代码量：约200行&lt;br /&gt;• 占总工作量：35%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;🔧 技术实现细节&lt;/h2&gt;
&lt;h3&gt;核心算法&lt;/h3&gt;
&lt;h4&gt;蛇身移动算法&lt;/h4&gt;
&lt;p&gt;采用&amp;quot;数字标记法&amp;quot;实现蛇的移动，避免传统数组移动的高复杂度：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 移动前：3 2 1 （蛇头为3，蛇身为2，蛇尾为1）
// 移动后：4 3 2 （整体数值增加，原位置减1）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;时间复杂度&lt;/strong&gt;：$O(n×m)$，其中$n$和$m$是画布尺寸。&lt;/p&gt;
&lt;h4&gt;碰撞检测优化&lt;/h4&gt;
&lt;p&gt;使用早期返回策略，提高检测效率：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;int checkCollision(int x, int y)
{
    // 按概率从高到低检查
    if (canvas[x][y] == BOMB) return 1; // 炸弹碰撞
    // 边界检查
    if (x &amp;lt;= 0 || x &amp;gt;= High-1) return 1;
    // 自身碰撞检查
    if (canvas[x][y] &amp;gt; 1 &amp;amp;&amp;amp; canvas[x][y] &amp;lt; snakeLength) return 1;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;性能优化&lt;/h3&gt;
&lt;h4&gt;减少屏幕闪烁&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;void drawCanvas()
{
    // 方法1：光标重定位，避免清屏
    COORD pos = {0, 0};
    SetConsoleCursorPosition(handle, pos);
    // 方法2: 只重绘变化区域
    // 实现脏矩形更新机制
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;内存管理&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;使用静态数组避免动态分配&lt;/li&gt;
&lt;li&gt;预分配所有需要的内存&lt;/li&gt;
&lt;li&gt;避免频繁的内存申请和释放&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;🧪 测试与调试&lt;/h2&gt;
&lt;h3&gt;测试用例设计&lt;/h3&gt;
&lt;h4&gt;功能测试&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;测试项&lt;/th&gt;
&lt;th&gt;输入&lt;/th&gt;
&lt;th&gt;预期输出&lt;/th&gt;
&lt;th&gt;结果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;蛇移动&lt;/td&gt;
&lt;td&gt;按W/A/S/D键&lt;/td&gt;
&lt;td&gt;蛇改变方向&lt;/td&gt;
&lt;td&gt;通过&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;吃食物&lt;/td&gt;
&lt;td&gt;蛇头接触食物&lt;/td&gt;
&lt;td&gt;得分+10，蛇身+1&lt;/td&gt;
&lt;td&gt;通过&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;撞墙&lt;/td&gt;
&lt;td&gt;蛇头接触边界&lt;/td&gt;
&lt;td&gt;游戏结束&lt;/td&gt;
&lt;td&gt;通过&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;炸弹移动&lt;/td&gt;
&lt;td&gt;随机生成炸弹&lt;/td&gt;
&lt;td&gt;炸弹每5帧移动&lt;/td&gt;
&lt;td&gt;通过&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h4&gt;边界测试&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;蛇长度为1时的碰撞检测&lt;/li&gt;
&lt;li&gt;同时吃到食物和炸弹的处理&lt;/li&gt;
&lt;li&gt;最高分数测试(INT_MAX)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;📊 项目总结与展望&lt;/h2&gt;
&lt;h3&gt;项目成果&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;✅ &lt;strong&gt;功能完整&lt;/strong&gt;：实现了所有计划功能，包括创新性的炸弹系统和加速机制&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;代码质量&lt;/strong&gt;：遵循良好的编码规范，注释详细，结构清晰&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;用户体验&lt;/strong&gt;：界面美观，操作流畅，反馈及时&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;可扩展性&lt;/strong&gt;：模块化设计，便于添加新功能&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;遇到的问题与解决方案&lt;/h3&gt;
&lt;h4&gt;问题1：屏幕闪烁严重&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：采用光标重定位技术替代清屏，显著减少闪烁。&lt;/p&gt;
&lt;h4&gt;问题2：炸弹可能困住蛇&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：限制炸弹生成位置，确保至少有一条通路。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📝 附录&lt;/h2&gt;
&lt;h3&gt;编译说明&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Windows 平台编译
gcc snake_game.c -o snake_game.exe -lwinmm
# Linux 平台编译（需要ncurses库）
gcc snake_game.c -o snake_game -lncurses
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;运行环境要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Windows 7/8/10/11 或 Linux 系统&lt;/li&gt;
&lt;li&gt;至少1GB内存&lt;/li&gt;
&lt;li&gt;支持ASCII字符的终端&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;报告结束&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;第四组 石澄錡 贾锡昶 - 2025年10月&lt;/em&gt;&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate></item><item><title>线性代数期中复习笔记</title><link>https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E6%9C%9F%E4%B8%AD%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E6%9C%9F%E4%B8%AD%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid><description>linear algebra</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E6%9C%9F%E4%B8%AD%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/&quot;&gt;https://dannyshi.pages.dev/blog/%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E6%9C%9F%E4%B8%AD%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  这篇更适合作为考前速查笔记来用。建议先看标题定位章节，再回到公式和图示复习，不需要从头顺序读完。
&lt;/Info&gt;

&lt;h1&gt;1 行列式&lt;/h1&gt;
&lt;h2&gt;1.1 n阶行列式的定义&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;$n$阶行列式是由$n^2$个数，排成$n$行、$n$列的算式&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
D = \begin{vmatrix}
a_{11} &amp;amp; a_{12} &amp;amp; \cdots &amp;amp; a_{1n} \
a_{21} &amp;amp; a_{22} &amp;amp; \cdots &amp;amp; a_{2n} \
\vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \
a_{n1} &amp;amp; a_{n2} &amp;amp; \cdots &amp;amp; a_{nn}
\end{vmatrix} = a_{11}A_{11} + a_{12}A_{12} + \cdots + a_{1n}A_{1n}
$$
记为$det(a_{ij})$，其中$A_{1j} = (-1) ^{1 + j}M_{ij}，j = 1,2,...,n$&lt;/p&gt;
&lt;p&gt;$$
D_n = \begin{vmatrix}
a_{11} &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 \
a_{21} &amp;amp; a_{22} &amp;amp; \cdots &amp;amp; 0 \
\vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \
a_{n1} &amp;amp; a_{n2} &amp;amp; \cdots &amp;amp; a_{nn}
\end{vmatrix} = a_{11}a_{22} \cdots a_{nn}
$$
&lt;strong&gt;注意到部分上（下）三角行列式有如下性质：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;$$
D_n = \begin{vmatrix}
a_{11} &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 \
a_{21} &amp;amp; a_{22} &amp;amp; \cdots &amp;amp; 0 \
\vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \
a_{n1} &amp;amp; a_{n2} &amp;amp; \cdots &amp;amp; a_{nn}
\end{vmatrix} = a_{11}a_{22}\cdots a_{nn}
$$&lt;/p&gt;
&lt;p&gt;$$
D_n = \begin{vmatrix}
0 &amp;amp; \cdots &amp;amp; 0 &amp;amp; a_{1n} \
0 &amp;amp; \cdots &amp;amp; a_{2,n-1} &amp;amp; a_{2n} \
\vdots &amp;amp; \ddots &amp;amp; \vdots &amp;amp; \vdots \
a_{n1} &amp;amp; \cdots &amp;amp; a_{n,n-1} &amp;amp; a_{nn}
\end{vmatrix} = (-1)^{\frac{n(n-1)}{2}} a_{1n}a_{2,n-1} \cdots a_{n1}
$$&lt;/p&gt;
&lt;p&gt;$$
\begin{vmatrix}
d_1 &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 \
0 &amp;amp; d_2 &amp;amp; \cdots &amp;amp; 0 \
\vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \
0 &amp;amp; 0 &amp;amp; \cdots &amp;amp; d_n
\end{vmatrix} = d_1d_2 \cdots d_n;
$$&lt;/p&gt;
&lt;p&gt;$$
\begin{vmatrix}
0 &amp;amp; \cdots &amp;amp; 0 &amp;amp; d_1 \
0 &amp;amp; \cdots &amp;amp; d_2 &amp;amp; 0 \
\vdots &amp;amp; \ddots &amp;amp; \vdots &amp;amp; \vdots \
d_n &amp;amp; \cdots &amp;amp; 0 &amp;amp; 0
\end{vmatrix} = (-1)^{\frac{n(n-1)}{2}} d_1d_2 \cdots d_n.
$$&lt;/p&gt;
&lt;h2&gt;1.2 行列式的性质&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;性质1&lt;/strong&gt;：行列式与它的转置行列式&lt;strong&gt;相等&lt;/strong&gt;，即$D^T = D$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质2&lt;/strong&gt;：互换行列式任意两行（列）的位置，行列式的值&lt;strong&gt;反号&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质3&lt;/strong&gt;：行列式$D$等于它的任一行（列）各元素分别与其对应的代数余子式的乘积之和&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推论1&lt;/strong&gt;： 若行列式$D$的某行元素全为零，则$D = 0$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质4&lt;/strong&gt;： 行列式的某一行（列）中所有的元素都乘以同一数$k$等于用数$k$乘此行列式&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质5&lt;/strong&gt;：若行列式的某一行（列）的元素都是两数之和，则此行列式可以写成两个行列式的和&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质6&lt;/strong&gt;： 若行列式有两行（列）对应元素相等，则此行列式为零&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推论2&lt;/strong&gt;：若行列式中有两行（列）成比例，则行列式为零&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质7&lt;/strong&gt;：行列式的某一行（列）乘以同一数后加到另一行（列），行列式不变&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性质8&lt;/strong&gt;：&lt;strong&gt;行列式的任一行（列）各元素与另一行（列）对应元素的代数余子式乘积之和等于零&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;details&gt;
  &lt;summary&gt;期中复习建议&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;行列式部分优先记性质 2、4、7，它们最常用于化简和证明。&lt;/li&gt;
    &lt;li&gt;平面方程部分优先区分点法式、一般式、截距式、参数式的使用场景。&lt;/li&gt;
    &lt;li&gt;最后再回看两平面位置关系，容易和法向量判定一起出题。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h1&gt;3 几何向量及其应用&lt;/h1&gt;
&lt;h2&gt;3.3 平面和空间直线&lt;/h2&gt;
&lt;h3&gt;3.3.1 平面方程&lt;/h3&gt;
&lt;h4&gt;平面的点法式方程&lt;/h4&gt;
&lt;p&gt;$$
M_0 (x_0,y_0,z_0)
$$
&lt;strong&gt;法线向量&lt;/strong&gt; 
$\vec{n} = (A, B, C)$
设平面上任一点为$M(x,y,z)$
则有$\vec{M_0M} \perp \vec{n} \Rightarrow \vec{M_0M} \cdot \vec{n} = 0$
即 &lt;strong&gt;$A(x-x_0) + B(y - y_0) + C(z - z_0) = 0$&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.2vf4walwek.webp&quot; alt=&quot;点法式&quot;&gt;&lt;/p&gt;
&lt;h4&gt;平面的一般式方程&lt;/h4&gt;
&lt;p&gt;由平面的点法式方程
$$
A(x-x_0) + B(y - y_0) + C(z - z_0) = 0 \
\Rightarrow Ax + By + Cz - (Ax_0 + By_0 + Cz_0) = 0 
$$&lt;/p&gt;
&lt;p&gt;其中 $Ax_0 + By_0 + Cz_0 = D$&lt;/p&gt;
&lt;p&gt;得到平面的一般式方程:&lt;/p&gt;
&lt;p&gt;$$
Ax + By + Cz + D = 0 
$$&lt;/p&gt;
&lt;p&gt;法向量 $\vec{n} = (A ,B, C)$&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;一般式方程的几种特殊情况&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;$ Ax + By + Cz + D = 0 $&lt;/p&gt;
&lt;p&gt;(1) $ D = 0 $，平面通过坐标原点；&lt;/p&gt;
&lt;p&gt;(2) $ A = 0 $，
$$
\begin{cases}
D = 0，&amp;amp; \text{平面通过x轴；} \
D \neq 0，&amp;amp; \text{平面平行于x轴；}
\end{cases}
$$
类似地可讨论 $ B = 0 $，$ C = 0 $ 情形。&lt;/p&gt;
&lt;p&gt;(3) $ A = B = 0 $，平面平行于$xoy$坐标面（即垂直于$Z$轴）；
类似地可讨论 $ A = C = 0 $，$ B = C = 0 $ 情形。&lt;/p&gt;
&lt;h4&gt;平面的截距式方程&lt;/h4&gt;
&lt;p&gt;设平面在x, y, z三轴上分别有截距 $OA = a, OB = b, OC = c$，（其中$a, b, c$，均为非零常数，求此平面方程。&lt;/p&gt;
&lt;p&gt;设平面为 $Ax + By + Cz + D = 0$，&lt;/p&gt;
&lt;p&gt;由已知，平面过点$(a, 0, 0), (0, b, 0), (0, 0, c)$&lt;/p&gt;
&lt;p&gt;有
$$
\begin{cases}
aA + D = 0, \
bB + D = 0, \
cC + D = 0,
\end{cases}
$$
$\Rightarrow A = -\frac{D}{a}, B = -\frac{D}{b}, C = -\frac{D}{c}.$&lt;/p&gt;
&lt;p&gt;代入所设方程得
$$
\frac{x}{a} + \frac{y}{b} + \frac{z}{c} = 1（截距式方程）
$$&lt;/p&gt;
&lt;h4&gt;平面的参数式方程&lt;/h4&gt;
&lt;p&gt;设平面$π$过点 $ P_0(x_0, y_0, z_0) $，且已知$π$上两个不共线的向量
$\vec{a} = (L_1, M_1, N_1), \vec{b} = (L_2, M_2, N_2)$，求此平面方程。&lt;/p&gt;
&lt;p&gt;设平面上任一点为 $ P(x, y, z) $&lt;/p&gt;
&lt;p&gt;则存在唯一的一组实数 $ s, t $，使得
$$
\overrightarrow{P_0P} = s\vec{a} + t\vec{b} \quad \text{或} \quad \vec{r} = \vec{r_0} + s\vec{a} + t\vec{b}
$$&lt;/p&gt;
&lt;p&gt;$$
\begin{cases}
x = x_0 + sL_1 + tL_2 \
y = y_0 + sM_1 + tM_2 \
z = z_0 + sN_1 + tN_2
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.3k8egbm2us.webp&quot; alt=&quot;参数式方程&quot;&gt;&lt;/p&gt;
&lt;h3&gt;3.3.2 两平面位置关系&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;定义：&lt;/strong&gt; 两平面法向量之间的夹角称为两平面的夹角&lt;/p&gt;
&lt;h4&gt;平面夹角计算&lt;/h4&gt;
&lt;p&gt;设平面 $\Pi_1$ 和 $\Pi_2$ 的方程分别为：
$$
 \Pi_1: A_1x + B_1y + C_1z + D_1 = 0, \
 \Pi_2: A_2x + B_2y + C_2z + D_2 = 0, 
$$&lt;/p&gt;
&lt;p&gt;对应的法向量为：
$$
 \vec{n}_1 = (A_1, B_1, C_1), \
 \vec{n}_2 = (A_2, B_2, C_2), 
$$&lt;/p&gt;
&lt;p&gt;平面夹角 $\theta$ 的余弦值为：
$$ \cos\theta = \frac{|A_1A_2 + B_1B_2 + C_1C_2|}{\sqrt{A_1^2 + B_1^2 + C_1^2} \cdot \sqrt{A_2^2 + B_2^2 + C_2^2}} $$&lt;/p&gt;
&lt;h4&gt;平面位置关系&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;$\Pi_1 \perp \Pi_2 \Leftrightarrow \vec{n}_1 \perp \vec{n}_2 \Leftrightarrow A_1A_2 + B_1B_2 + C_1C_2 = 0;$&lt;/li&gt;
&lt;li&gt;$\Pi_1 \parallel \Pi_2 \Leftrightarrow \vec{n}_1 \parallel \vec{n}_2 \Leftrightarrow A_1:B_1:C_1 = A_2:B_2:C_2$&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;两平面位置关系&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;$\Pi_1$ 与 $\Pi_2$ 相交 $\Leftrightarrow \vec{n}_1$ 与 $\vec{n}_2$ 不平行
$ \Leftrightarrow A_1:B_1:C_1 \neq A_2:B_2:C_2 $&lt;/li&gt;
&lt;li&gt;$\Pi_1$ 与 $\Pi_2$ 平行而不重合 $\Leftrightarrow \frac{A_1}{A_2} = \frac{B_1}{B_2} = \frac{C_1}{C_2} \neq \frac{D_1}{D_2}$&lt;/li&gt;
&lt;li&gt;$\Pi_1$ 与 $\Pi_2$ 重合 $\Leftrightarrow \frac{A_1}{A_2} = \frac{B_1}{B_2} = \frac{C_1}{C_2} = \frac{D_1}{D_2}$&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;strong&gt;3.3.3 直线方程&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;直线的对称式方程&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;过一点且与一已知非零向量平行的直线式唯一确定的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.102k4wsqgv.webp&quot; alt=&quot;对称式方程&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方向向量&lt;/strong&gt;：与直线平行的非零向量&lt;/p&gt;
&lt;p&gt;设$M_0 =(x_0,y_0,z_0),\vec{s} = (l,m,n),$
$M (x,y,z)$为直线上任一点
则有
$$
\vec{M_0M} \parallel \vec{s}
$$
即
$$
\frac{x-x_0}{l} = \frac{y-y_0}{m} = \frac{z-z_0}{n}（直线的对称式方程）
$$&lt;/p&gt;
&lt;h4&gt;直线的参数方程&lt;/h4&gt;
&lt;p&gt;$$
\frac{x-x_0}{l} = \frac{y-y_0}{m} = \frac{z-z_0}{n}（直线的对称式方程）
$$
令
$$
\frac{x-x_0}{l} = \frac{y-y_0}{m} = \frac{z-z_0}{n} = t
$$
得
$$
\begin{cases}
x = x_0 + lt \
y = y_0 + mt \quad 直线的参数方程\ 
z = z_0 + nt 
\end{cases}
$$&lt;/p&gt;
&lt;h4&gt;直线的一般式方程&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.70aq9nbvuf.webp&quot; alt=&quot;一般方程&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果两平面
$$
\Pi_1: A_1x + B_1y + C_1z + D_1 = 0 \
\Pi_2: A_2x + B_2y + C_2z + D_2 = 0
$$
不平行，则其交线是一条直线:
&lt;strong&gt;空间直线的一般式方程&lt;/strong&gt;
$$
\begin{cases}
 A_1x + B_1y + C_1z + D_1 = 0 \
 A_2x + B_2y + C_2z + D_2 = 0
\end{cases}
$$
其&lt;strong&gt;方向向量&lt;/strong&gt;为：
$$
\vec{s} = \vec{n_1} \times \vec{n_2} = (A_1,B_1,C_1) \times (A_2,B_2,C_2)
$$&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;两条直线的位置关系&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;定义：两直线的方向向量的夹角称为这两条直线的夹角（一般取锐角）。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直线 $ L_1 : \frac{x - x_1}{l_1} = \frac{y - y_1}{m_1} = \frac{z - z_1}{n_1} $&lt;br&gt;直线 $ L_2 : \frac{x - x_2}{l_2} = \frac{y - y_2}{m_2} = \frac{z - z_2}{n_2} $&lt;/p&gt;
&lt;p&gt;$$
\cos \theta = \frac{| l_1 l_2 + m_1 m_2 + n_1 n_2 |}{\sqrt{ l_1^2 + m_1^2 + n_1^2 } \cdot \sqrt{ l_2^2 + m_2^2 + n_2^2 }}
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特别地：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(1) $ L_1 \perp L_2 \iff l_1 l_2 + m_1 m_2 + n_1 n_2 = 0 $&lt;/li&gt;
&lt;li&gt;(2) $ L_1 \parallel L_2 \iff (l_1, m_1, n_1) \parallel (l_2, m_2, n_2) $&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h5&gt;&lt;strong&gt;两直线的位置关系：&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.6pnwgi50db.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;(1) $ L_1 $ 与 $ L_2 $ 异面&lt;br&gt;$\iff$ 三向量 $ \overrightarrow{P_1 P_2}, \vec{s}_1, \vec{s}_2 $ 不共面。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(2) $ L_1 $ 与 $ L_2 $ 相交于一点&lt;br&gt;$\iff$ 三向量 $ \overrightarrow{P_1 P_2}, \vec{s}_1, \vec{s}_2 $ 共面，且 $ \vec{s}_1 \nparallel \vec{s}_2 $。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(3) $ L_1 $ 与 $ L_2 $ 平行而不重合&lt;br&gt;$\iff$ $ \vec{s}_1 \parallel \vec{s}_2 $，且 $ \overrightarrow{P_1 P_2} \nparallel \vec{s}_1 $。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(4) $ L_1$ 与 $ L_2 $ 重合&lt;br&gt;$\iff$ $ \vec{s}_1 \parallel \vec{s}_2 \parallel \overrightarrow{P_1 P_2} $。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结：$ L_1 $ 与 $ L_2 $ 共面&lt;br&gt;$\iff$ 三个向量 $ \overrightarrow{P_1 P_2}, \vec{s}_1, \vec{s}_2 $ 共面&lt;/p&gt;
&lt;p&gt;$$
\begin{vmatrix}
x_2 - x_1 &amp;amp; y_2 - y_1 &amp;amp; z_2 - z_1 \
l_1 &amp;amp; m_1 &amp;amp; n_1 \
l_2 &amp;amp; m_2 &amp;amp; n_2
\end{vmatrix} = 0
$$&lt;/p&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate></item><item><title>Paper Reading Week1</title><link>https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week1/</link><guid isPermaLink="true">https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week1/</guid><description>10/11-10/17</description><content:encoded>&lt;blockquote&gt;This rendering was automatically generated by Frosti Feed and may have formatting issues. For the best experience, please visit: &lt;a href=&quot;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week1/&quot;&gt;https://dannyshi.pages.dev/blog/paper-reading/paper-reading-week1/&lt;/a&gt;&lt;/blockquote&gt; &lt;p&gt;import Info from &amp;quot;@/components/mdx/Info.astro&amp;quot;;&lt;/p&gt;
&lt;Info&gt;
  本周笔记聚焦两条很经典的 Agent 脉络：`Tree of Thoughts` 侧重搜索与回溯，`ReAct` 侧重推理与行动交替。阅读时可以优先对比它们各自解决的“决策瓶颈”。
&lt;/Info&gt;

&lt;h1&gt;论文信息&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2305.10601&quot;&gt;Arxiv ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hjfy.top/arxiv/2305.10601&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Title:&lt;strong&gt;Tree of Thoughts: Deliberate Problem Solving with Large Language Models 树状思维：大型语言模型的深思熟虑问题求解&lt;/strong&gt;&lt;/h2&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;strong&gt;1. Introduction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;介绍了当前大语言模型（如GPT-4）在推理时仅限于&amp;quot;&lt;strong&gt;从左到右、逐词生成&lt;/strong&gt;&amp;quot;的局限性，并将其类比为人类认知中的“系统1”（快速、自动）。受人类“系统2”（慢速、深思熟虑）和早期人工智能“问题求解即搜索”思想的启发，提出了“&lt;strong&gt;思维树&lt;/strong&gt;”框架，旨在让模型能够进行探索、前瞻和回溯等更复杂的决策过程。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. Background&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Input-output (IO) prompting（输入-输出提示）： 最基本的直接生成答案的方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chain-of-thought (CoT) prompting（思维链提示）： 通过生成一系列中间推理步骤来连接输入和输出。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self-consistency with CoT (CoT-SC)（思维链自洽）： 通过采样多条思维链并取多数答案作为最终结果的集成方法。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3. Tree of Thoughts（ToT）&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.70aq76hmqt.webp&quot; alt=&quot;对比图片&quot;&gt;&lt;/p&gt;
&lt;p&gt;将问题视为对一棵树的搜索，每个节点存储一个状态。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ToT&lt;/strong&gt; 回答四个问题：&lt;/p&gt;
&lt;p&gt;1 &lt;strong&gt;如何将中间过程分解为思维步骤？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;根据具体问题的性质，将整个问题解决过程分解为多个连贯的中间步骤，每个步骤称为一个“思维”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2 &lt;strong&gt;如何从每个状态生成潜在的思维？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在树中的每个状态（即当前的部分解决方案）下，生成 k 个可能的后续“思维”。论文提出了两种策略：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;采样： 从思维链提示中独立同分布地采样 k 个思维。适用于思维空间丰富的情况（如生成段落计划）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;提议： 使用一个“提议提示”，让模型在同一个上下文中连续生成 k 个不同的思维。适用于思维空间受限的情况（如生成一个单词或一行方程），以避免重复。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3 &lt;strong&gt;如何启发式地评估状态？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不使用传统的搜索算法，而是用&lt;strong&gt;LLM&lt;/strong&gt;对节点状态进行评估打分，好处是比编程的规则更加灵活。考虑&lt;strong&gt;两种策略&lt;/strong&gt;对状态进行评估。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;独立评估&lt;/strong&gt;： 为每个状态 $S$ 独立生成一个标量值（如1-10分）或分类（如“确定/可能/不可能”）。评估基于快速前瞻模拟和常识。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;投票评估&lt;/strong&gt;： 让语言模型在多个状态 $S$ 中进行比较，并投票选出最有可能的一个。这相当于一个“逐步”的自洽性检查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4 &lt;strong&gt;使用什么搜索算法？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;广度优先搜索（BFS）&lt;/strong&gt; 每一步维持最多$b$个最有希望的状态。在深度有限的任务中使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;深度优先搜索（DFS）&lt;/strong&gt; 首先搜索最有希望的状态，直到完成输出或者评估器认为当前$S$无法完成问题。 对该$S$的子节点进行剪枝并回溯到$S$的父节点继续搜索。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;4. Experiment&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;结果部分通过在三个精心设计的任务上的实验，得出了一个核心且一致的结论：Tree of Thoughts (ToT) 框架能够极大地提升大语言模型（GPT-4）在需要进行探索、规划和搜索的复杂任务上的性能，显著优于传统的输入-输出（IO）提示、思维链（CoT）提示以及思维链自洽（CoT-SC）等基线方法。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;消融实验&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;无剪枝&lt;/li&gt;
&lt;li&gt;无回溯&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;
  &lt;summary&gt;快速抓重点&lt;/summary&gt;

  &lt;ul&gt;
    &lt;li&gt;`ToT` 强在显式搜索，适合多步规划和需要试错的问题。&lt;/li&gt;
    &lt;li&gt;`ReAct` 强在与外部环境交互，适合检索、网页操作、决策任务。&lt;/li&gt;
    &lt;li&gt;两者都在补足“直接一次性生成答案”时容易失控的问题。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/details&gt;

&lt;h2&gt;论文信息&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2210.03629&quot;&gt;Arxiv ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hjfy.top/arxiv/2210.03629&quot;&gt;幻觉翻译&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;strong&gt;Title:ReAct: Synergizing Reasoning and Acting in Language ModelsReAct: 在语言模型中协同推理和行动&lt;/strong&gt;&lt;/h3&gt;
&lt;h2&gt;论文结构&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1. Introduction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;当前的大语言模型在解决复杂任务时，其&amp;quot;推理&amp;quot;和&amp;quot;行动&amp;quot;能力是相互割裂的。纯推理方法容易产生事实幻觉且无法获取最新信息，而纯行动方法缺乏战略规划能力，容易在复杂任务中迷失方向。提出了 &lt;strong&gt;ReAct范式&lt;/strong&gt;，通过在大语言模型中交织生成&lt;strong&gt;推理轨迹&lt;/strong&gt;和&lt;strong&gt;任务特定动作&lt;/strong&gt;，创建&amp;quot;推理指导行动，行动辅助推理&amp;quot;的协同机制，使模型能够动态规划、利用外部信息并处理异常。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. Background&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standard prompting（标准提示）&lt;/strong&gt;： 直接生成答案或行动，缺乏显式推理过程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chain-of-Thought (CoT) prompting（思维链提示）&lt;/strong&gt;： 通过生成推理步骤提升模型表现，但是&lt;strong&gt;静态的、封闭的&lt;/strong&gt;，无法与外部环境交互，容易产生&lt;strong&gt;事实幻觉&lt;/strong&gt;和&lt;strong&gt;错误传播&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Act-only prompting（纯行动提示）&lt;/strong&gt;： 能够与环境交互，但缺乏&lt;strong&gt;高层次的语言推理&lt;/strong&gt;来指导行动规划、跟踪进度和处理异常。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3. ReAct&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/lnscq/picx-images-hosting/raw/master/image.3k8egkob9t.webp&quot; alt=&quot;ReAct对比图&quot;&gt;&lt;/p&gt;
&lt;p&gt;将任务求解视为在推理空间和行动空间中的交替执行过程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ReAct&lt;/strong&gt; 解决四个关键问题：&lt;/p&gt;
&lt;p&gt;1 &lt;strong&gt;如何融合推理与行动？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;通过扩展智能体的行动空间至 $\hat{\mathcal{A}} = \mathcal{A} \cup \mathcal{L}$，其中 $\mathcal{A}$ 是外部行动空间（如搜索、点击），$\mathcal{L}$ 是语言（推理）空间。模型可以交替或按需生成&amp;quot;思考&amp;quot;和&amp;quot;行动&amp;quot;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2 &lt;strong&gt;如何设计任务特定的行动空间？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;根据任务需求设计最小化但足够的行动集：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;知识任务&lt;/strong&gt;：搜索(Search)、查找(Lookup)、完成(Finish)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;决策任务&lt;/strong&gt;：导航(Go to)、拿取(Take)、使用(Use)等环境原生动作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网页任务&lt;/strong&gt;：搜索(Search)、点击(Click)、购买(Buy Now)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3 &lt;strong&gt;如何生成有效的推理轨迹？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;通过少量示例提示，引导模型生成多种类型的推理：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;任务分解&lt;/strong&gt;：&amp;quot;我需要先搜索X，然后查找Y&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信息提取&lt;/strong&gt;：&amp;quot;段落中提到成立于1844年&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进度跟踪&lt;/strong&gt;：&amp;quot;现在生菜已清洗，下一步是放到餐桌&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异常处理&lt;/strong&gt;：&amp;quot;搜索无结果，尝试换关键词&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常识推理&lt;/strong&gt;：&amp;quot;台灯通常放在桌子或架子上&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4 &lt;strong&gt;如何平衡推理与行动的密度？&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;根据任务类型动态调整：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;知识密集型任务&lt;/strong&gt;：采用&lt;strong&gt;密集、交替&lt;/strong&gt; 的思考-行动-观察步骤&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;决策制定任务&lt;/strong&gt;：采用&lt;strong&gt;稀疏、按需&lt;/strong&gt;的思考，在关键时刻（如规划、遇到困境时）进行推理&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;strong&gt;4. 实验验证&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;通过在四个不同领域的基准测试上的实验，证明了ReAct框架的显著优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;知识推理任务&lt;/strong&gt;（HotpotQA, FEVER）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReAct优于纯行动方法，展示了推理对行动的指导价值&lt;/li&gt;
&lt;li&gt;与CoT相比，ReAct减少了幻觉，提高了事实准确性&lt;/li&gt;
&lt;li&gt;ReAct + CoT-SC组合达到了最佳性能，结合了内部知识和外部信息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;交互决策任务&lt;/strong&gt;（ALFWorld, WebShop）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;少量提示&lt;/strong&gt;的ReAct显著超越了需要&lt;strong&gt;大量专家数据&lt;/strong&gt;训练的模仿学习和强化学习方法&lt;/li&gt;
&lt;li&gt;在ALFWorld上绝对成功率提升34%，在WebShop上提升10%&lt;/li&gt;
&lt;li&gt;纯行动基线容易陷入循环或迷失方向，而ReAct能有效规划并跟踪目标&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;消融与分析&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;与Inner Monologue对比&lt;/strong&gt;：ReAct的&lt;strong&gt;主动推理&lt;/strong&gt;优于单纯复述环境反馈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误模式分析&lt;/strong&gt;：ReAct的失败更多源于推理错误或搜索无效，而非事实幻觉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人机回环验证&lt;/strong&gt;：人类通过编辑推理轨迹可轻松纠正模型行为，证明了框架的可控性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;5. 核心贡献总结&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;范式创新&lt;/strong&gt;：首次系统性地将推理与行动在LLM中协同，提出统一框架&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通用性强&lt;/strong&gt;：在知识推理和交互决策两大类任务上均表现优异&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实用性突出&lt;/strong&gt;：通过提示方法实现，成本低且易于复现&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可解释性佳&lt;/strong&gt;：生成的推理轨迹提供透明的问题解决过程&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开辟新方向&lt;/strong&gt;：为构建更可靠、可控的AI智能体奠定了基础&lt;/li&gt;
&lt;/ol&gt;
</content:encoded><dc:creator>Danny&apos;s Blog</dc:creator><pubDate>Mon, 13 Oct 2025 00:00:00 GMT</pubDate></item></channel></rss>