<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>K1tyoo&apos; Log</title><description>GenAI is pure magic!</description><link>https://k1tyoo.ink</link><item><title>大语言模型</title><link>https://k1tyoo.ink/blog/dl/llm</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/llm</guid><description>深度学习 - 笔记 8</description><pubDate>Tue, 14 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;语言模型发展历程&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/his.png&quot; alt=&quot;语言模型发展历程&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;涌现能力 (Emergent Ability)&lt;/strong&gt; 指的是当模型扩展到一定规模时，其特定任务性能突然出现显著跃升的趋势。具体来说包括三种 - 上下文学习、指令遵循和逐步推理的能力。&lt;/p&gt;
&lt;h2&gt;训练阶段扩展法则&lt;/h2&gt;
&lt;p&gt;模型的性能随着 &lt;strong&gt;模型规模 (N)、数据规模 (D) 和计算算力 (C)&lt;/strong&gt; 的增长而呈现可预测的提升趋势。也就是在给定算力 (FLOPs) 的情况下，如何对其余参数进行合理的分配使得模型的性能最好。&lt;/p&gt;
&lt;h3&gt;OpenAI&lt;/h3&gt;
&lt;p&gt;$$
\small
N_{opt} \propto C^{\textcolor{red}{0.73}}, \hspace{0.2cm} B_{opt} \propto C^{\textcolor{red}{0.24}}, \hspace{0.2cm} S_{opt} \propto C^{\textcolor{red}{0.03}}, \hspace{0.2cm}D = B \cdot S, \hspace{0.2cm} C \approx 6ND
$$&lt;/p&gt;
&lt;p&gt;可以发现当算力固定的时候，扩大模型规模带来的收益最客观。&lt;/p&gt;
&lt;h3&gt;DeepMind&lt;/h3&gt;
&lt;p&gt;$$
\small
N_{opt} = G \left( \frac{C}{6} \right)^{a}, \hspace{0.2cm}D_{opt} = G^{-1} \left( \frac{C}{6} \right)^{b}, \hspace{0.2cm}a = \frac{\beta}{\alpha + \beta} = \textcolor{red}{0.46}, \hspace{0.2cm}b = \frac{\alpha}{\alpha + \beta} = \textcolor{red}{0.54}
$$&lt;/p&gt;
&lt;p&gt;可以发现指数 $\small a$ 和 $\small b$ 十分接近，意味着当计算预算增加时，模型规模和数据规模应该几乎等比例增长。&lt;/p&gt;
&lt;h2&gt;推理阶段扩展法则&lt;/h2&gt;
&lt;h2&gt;分词&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;分词可视化网址 - https://tiktokenizer.vercel.app/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;分词 (Tokenization)&lt;/strong&gt; 指的是将输入文本转换成若干词元 (Token)，且保证每个词元拥有相对完整和独立的语义。目前最常用的分词算法是 &lt;strong&gt;Byte-level BPE (B-BPE)&lt;/strong&gt;，其核心思想是通过滑动窗口来统计字节对，找到最频繁的连续字节对并将它们合并，重复这个过程直到达到预设的子词数量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/bbpe.png&quot; alt=&quot;B-BPE&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;词表 (Vocabulary)&lt;/strong&gt; 是由词元到索引的映射组成的字典，即 &lt;code&gt;{&apos;&amp;#x3C;pad&gt;&apos;: 0, &apos;hello&apos;: 1, &apos;world&apos;: 2}&lt;/code&gt;。可以通过 &lt;a href=&quot;https://huggingface.co/docs/transformers/tokenizer_summary&quot;&gt;Summary of the tokenizers&lt;/a&gt; 查看其他的分词类别。&lt;/p&gt;
&lt;h2&gt;词嵌入&lt;/h2&gt;
&lt;p&gt;分词过程结束之后，会得到一个优化后的词表，然后我们使用嵌入层 (Embedding) 将每个词元映射为一个稠密向量，全部映射完成之后得到一个 &lt;strong&gt;可学习的参数矩阵/查找表&lt;/strong&gt;，其大小为 [vocab_size, embed_dim]。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;hello world&quot;
    ↓ 分词
[&apos;hello&apos;, &apos;world&apos;]
    ↓ 映射为 ID - 由词表确定
[1, 2]
    ↓ 查找嵌入(lookup) - 大小为(2, 5)，即 (seq_len, embed_dim)
[[0.1234, -0.5678, 0.9012, -0.3456, 0.7890],
 [-0.1111,  0.2222, 0.3333, -0.4444, 0.5555]]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Word2Vec&lt;/h3&gt;
&lt;p&gt;基于分布式假设，即 &lt;strong&gt;语义相近的文本在向量空间中的距离也相近&lt;/strong&gt;。其模型的本质是具有一个隐藏层的网络，最后取输入层到隐藏层的权重矩阵作为词的分布式表示。&lt;/p&gt;
&lt;p&gt;word2vec 包含两种任务类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CBOW&lt;/strong&gt; - 上下文窗口内的词元向量平均值作为输入，目标词元作为输出，最大化目标词元的条件概率；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip-Gram&lt;/strong&gt; - 目标词元作为输入，上下文窗口内的词元作为输出，最大化上下文词元的条件概率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于要进行条件概率的计算，所以涉及 softmax 操作，但是该操作在词汇量较大的时候计算效率低，因此引入了两种优化算法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;层级 Softmax (Hierarchical Softmax)&lt;/strong&gt; - 构建一个树形结构来代替隐藏层到 softmax 层的映射，根据词频构建 &lt;strong&gt;哈夫曼树&lt;/strong&gt;，高频词在浅层，低频词在深层。将输出词的概率分布建模为从根节点到叶子结点的路径选择(多分类 -&gt; 二分类)，复杂度从 $\small O(V)$ 降低到 $\small O(\log V)$；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;负采样 (Negative Sampling)&lt;/strong&gt; - 从噪声分布中随机采样负样本(词表中词频较大的无关词)，并且使用词频的 0.75 次方作为权重，以平衡高频词和低频词的采样概率。&lt;strong&gt;目标是最大化正例的概率&lt;/strong&gt;，同时最小化负例的概率。在更新的过程中也仅更新正例和负例的权重。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;负采样的训练目标为：&lt;/p&gt;
&lt;p&gt;$$
\small
\min \left[ -\log \sigma(v^{\prime}_{w_o^\text{T}} h)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;\sum_{w_j \in \mathcal{W}&lt;em&gt;{\text{neg}}} \log \sigma(-v^{\prime}&lt;/em&gt;{w_j^\text{T}} h)\right]
$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中 $h$ 是中心词的词向量，$v&apos;&lt;em&gt;{w_o}$ 是正例上下文词的词向量，$\mathcal{W}&lt;/em&gt;{\text{neg}}$ 是噪声分布。&lt;/p&gt;
&lt;h3&gt;FastText&lt;/h3&gt;
&lt;p&gt;FastText 在 Word2Vec 的基础上进行了改进，引入了 &lt;strong&gt;子词嵌入&lt;/strong&gt;，即将输入文本拆分成子词，然后将子词嵌入向量进行平均得到输入文本的嵌入向量，有效提升了模型对 OOV 和形态变化的处理。&lt;/p&gt;
&lt;p&gt;在 n-gram 序列的构建上采用了 &lt;strong&gt;滑动窗口&lt;/strong&gt; 的方式，假设窗口大小为 3，对于输入文本 &quot;hello&quot;，其序列为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;#x3C;he, hel, ell, llo, lo&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并且为了避免显示存储所有子词的词向量，使用 &lt;strong&gt;哈希函数&lt;/strong&gt; 将 n-gram 序列映射到固定大小的哈希表中。&lt;/p&gt;
&lt;h2&gt;预训练&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;语言建模 (NTP)&lt;/strong&gt; - 给定一个词元序列 $\small u= {u_1, \cdots, u_{T}}$，语言建模的任务是基于当前位置之前的词元序列 $\small {u_{&amp;#x3C;t}}$ 以自回归的方式对下一个词元进行预测。代表模型为 GPT、LLaMA。&lt;/p&gt;
&lt;p&gt;$$
\small
L_{\text{LM}}(u)=\sum_{t=1}^{T}\log P(u_t|u_{&amp;#x3C;t})
$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前缀语言建模 (Prefix LM)&lt;/strong&gt; - 专为前缀解码器架构而设计，本质是利用前缀信息来预测后缀的词元，并且只有后缀中的词元计入总损失。代表模型为 ChatGLM、U-PaLM。&lt;/p&gt;
&lt;p&gt;$$
\small
L_{\text{prefix}}=\log P(u_{\text{prefix}}|u_{\text{suffix}})=\sum_{t=k+1}^{T}\log P(u_t|u_{&amp;#x3C;t})
$$&lt;/p&gt;
&lt;p&gt;该架构对因果解码器的掩码机制进行了修改，即对输入(前缀)部分采用双向注意力机制进行编码，而对输出部分利用单向的掩码注意力进行自回归地预测。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;去噪自编码 (DAE)&lt;/strong&gt; - 输入序列经过一系列的随机替换和删除操作之后形成损坏的文本 $\small u_{\char92 \tilde{u}}$，模型的目标就是根据损坏的文本来恢复被替换或删除的词元片段 $\small \tilde{u}$。代表模型为 BERT、T5。&lt;/p&gt;
&lt;p&gt;$$
\small
L_{\text{DAE}}=\log P(\tilde{u}|u_{\char92 \tilde{u}})
$$&lt;/p&gt;
&lt;h2&gt;指令微调&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;指令微调 (Instruction Tuning)&lt;/strong&gt; 指的是用自然语言形式的数据对预训练模型进行参数微调，使得模型具备 &lt;strong&gt;指令遵循&lt;/strong&gt; 的能力，从而在 &lt;strong&gt;零样本&lt;/strong&gt; 的情况下完成诸多下游任务。该阶段的主要目的是优化模型输出格式，从而对齐人类和真实应用场景的需求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/it.png&quot; alt=&quot;指令微调&quot;&gt;&lt;/p&gt;
&lt;p&gt;指令微调最重要的一环是指令数据的构建，即 [指令+输入+输出] 对，例如下面的翻译任务：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;{
  &quot;instruction&quot;: &quot;将下述中文翻译为英文&quot;,
  &quot;input&quot;: &quot;中国的首都是北京。&quot;,
  &quot;output&quot;: &quot;China&apos;s capital city is Beijing.&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;主要有三种构建方式 - 在已有的 NLP 数据集上添加指令、人类专家编写的指令数据集以及通过大模型来生成指令数据集 (&lt;strong&gt;Self-Instruct&lt;/strong&gt;)。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/itd.png&quot; alt=&quot;指令微调&quot;&gt;&lt;/p&gt;
&lt;h2&gt;参数高效微调&lt;/h2&gt;
&lt;h3&gt;Adapter Tuning&lt;/h3&gt;
&lt;p&gt;Adapter Tuning 指的是在模型中引入适配器(瓶颈网络架构)从而不需要训练整个模型，只需要更新适配器参数即可，不同的任务可以使用不同的适配器。&lt;/p&gt;
&lt;p&gt;$$
\small
x=x+\sigma(x\cdot W_\text{up})\cdot W_{\text{down}}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small W_{\text{down}}\in \mathbb{R}^{k\times r}$、$\small W_\text{up}\in \mathbb{R}^{r\times k}$、$r \ll k$。&lt;/p&gt;
&lt;p&gt;具体来说，首先将特征向量压缩到较低维度，然后使用激活函数进行非线性变换，最后恢复到初始维度。并且使用残差连接来保证梯度的传递。&lt;/p&gt;
&lt;h3&gt;LoRA&lt;/h3&gt;
&lt;p&gt;LoRA 指的是在预训练模型的参数矩阵的旁路添加低秩分解矩阵来近似每层的参数更新。&lt;/p&gt;
&lt;p&gt;$$
\small
W=W_0+\Delta W=W_0+BA
$$&lt;/p&gt;
&lt;p&gt;其中 $\small W_0\in \mathbb{R}^{d\times k}$、$\small B\in \mathbb{R}^{d\times r}$、$\small A\in\mathbb{R}^{r\times k}$、 $\small r \ll \min(d,k)$，且矩阵 $\small A$、$\small B$ 分别通过高斯、零初始化。&lt;/p&gt;
&lt;p&gt;具体来说，模型在前向传播的过程中，原始参数矩阵保持不变，而引入的低秩矩阵会被更新。训练完成之后将二者合并得到新的参数矩阵。推理阶段，相较于 Adapter 的串行来说，并行推理速度会更快。&lt;/p&gt;
&lt;h2&gt;对齐&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;对齐 (Alignment)&lt;/strong&gt; 指的是大语言模型的行为与人类价值观、人类真实意图和社会伦理相一致。我们希望对齐之后的大模型是 &lt;strong&gt;有用的、诚实的、无害的 (3H 标准)&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;RLHF&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/rlhf.png&quot; alt=&quot;RLHF&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(1) 监督微调&lt;/strong&gt; - 使用标注数据 $\small (q,o)$ 训练基于 GPT-3 的微调模型 $\small \pi^{\text{SFT}}$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(2) 奖励模型&lt;/strong&gt; - 使用筛选的偏好数据 $\small(q,o_w,o_l)$ 基于 $\small \pi^{\text{SFT}}$ 训练奖励模型 $\small r_\varphi(q,o_w)$ 来输出标量分数&lt;/p&gt;
&lt;p&gt;基于 Bradley-Terry 模型，给出人类偏好片段 $\small o_w$ 超过 $\small o_l$ 的概率：&lt;/p&gt;
&lt;p&gt;$$
\small
P(o_w\succ o_l\mid q)=\frac{\exp(r_\varphi(q,o_w))}{\exp(r_\varphi(q,o_w))+\exp(r_\varphi(q,o_l))}
$$&lt;/p&gt;
&lt;p&gt;通过最大化对数 / 最小化负对数似然来训练该模型，即希望偏好/非偏好输出之间的奖励差值较大：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{loss}(\varphi)=-\mathbb{E}&lt;em&gt;{(q,o_w,o_l)\sim D}\left[\log \underbrace{\sigma(r&lt;/em&gt;\varphi(q,o_w)-r_\varphi(q,o_l))}_{\text{Bradley-Terry 模型}}\right]
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bradley-Terry 模型是基于偏好对的 (两个输出)，Lackett–Luce 模型是基于排序的 (多个输出)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;(3) PPO 优化&lt;/strong&gt; - 初始策略为 $\small \pi^{\text{SFT}}$，结合奖励模型和 KL 惩罚不断优化策略从而最大化奖励模型的输出期望&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{loss}(\theta)&amp;#x26;=\mathbb{E}&lt;em&gt;{q\sim D&lt;/em&gt;\text{RL}} \mathbb{E}&lt;em&gt;{o\sim \pi^\text{RL}&lt;/em&gt;\theta(q)}\frac{1}{|o|} \sum_{t=1}^{|o|}\overbrace{\left[r_\varphi(q,o_{\le t})-\beta\underbrace{ ~\log \frac{\pi_{\theta}^{\text{RL}}(o_t\mid q,o_{&amp;#x3C;t})}{\pi^{\text{SFT}}(o_t\mid q,o_{&amp;#x3C;t})}}&lt;em&gt;{\text{KL 惩罚}}\right]}^{\text{最终奖励}} \ &amp;#x26;+ \gamma ~\underbrace{\mathbb{E}&lt;/em&gt;{q\sim D_\text{pretrain}}\log \pi_{\theta}^{\text{RL}}(o_t \mid q, o_{&amp;#x3C;t})}_{\text{预训练目标函数}}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;加入 KL 惩罚是希望模型的优化目标不会太过偏离微调结果，减少奖励模型对 OOD 数据的敏感性以及避免 Reward Hacking 问题，需要注意分布之间的 KL 散度是逐词元计算 (Per-Token KL Penalty)。加入预训练目标函数是希望模型能够保留基础能力，避免遗忘预训练知识 (减轻对齐税)。&lt;/p&gt;
&lt;p&gt;直接优化带 KL 散度的目标函数是二阶的，通过引入裁剪 (Clipping) 概率比来直接限制新旧策略的更新幅度，从而在实践中达到类似 KL 散度的约束效果，并将其转换为一阶优化问题：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{loss}(\theta)&amp;#x26;=\mathbb{E}&lt;em&gt;{[q\sim D&lt;/em&gt;\text{RL},{o\sim \pi_{\theta_{old}}^{\text{RL}}}]} \frac{1}{|o|} \sum_{t=1}^{|o|} \ &amp;#x26; \min \left[\frac{\pi_\theta^{\text{RL}}(o_t\mid q_t,o_{&amp;#x3C;t})}{\pi_{\theta_{\text{old}}}^{\text{RL}}(o_t\mid q_t,o_{&amp;#x3C;t})}A_t, \text{clip}\left(\frac{\pi_\theta^{\text{RL}}(o_t\mid q_t,o_{&amp;#x3C;t})}{\pi_{\theta_{\text{old}}}^{\text{RL}}(o_t\mid q_t,o_{&amp;#x3C;t})}, 1-\varepsilon, 1+\varepsilon\right)A_t\right]
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small A_t$ 是优势函数，定义为实际奖励与基准奖励的差值，其回答了在当前状态 $\small q_t$ 下，采取某个动作 $\small o_t$ 比平均水平好多少的问题。其中实际奖励通过奖励模型输出得到，而基准奖励则由可学习的价值模型 $\small V$ 提供：&lt;/p&gt;
&lt;p&gt;$$
\small
A_t=r(q_t, o_t) - V(o_t)
$$&lt;/p&gt;
&lt;p&gt;在实践中，通常使用广义优势估计 (GAE) 来平衡偏差和方差，从而计算一个更加稳健的优势值。单步优势函数进一步扩展为多步优势的指数加权平均 (Per-Token)：&lt;/p&gt;
&lt;p&gt;$$
\small
A_t^{\text{GAE}} = \sum_{l=0}^{T-t} (\gamma \lambda)^l \delta_{t+l}, \quad \delta_t = \underbrace{r(q_t, o_t) + \gamma V(o_{t+1})}&lt;em&gt;{新的估计} - \underbrace{V(o_t)}&lt;/em&gt;{旧的估计}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small \delta_t$ 表示时序差分误差 (TD Error)，该差值衡量了单步更新的 &quot;惊喜&quot; 程度，若其大于 0，则表示为正向惊喜，反之为负向惊喜。具体的步骤为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在生成序列的每一步 $\small t$ 都会计算一个 TD 误差 $\small \delta_t$，它告诉我们这一步的表现是正向还是负向惊喜；&lt;/li&gt;
&lt;li&gt;计算在 $\small t$ 时刻的总优势 $\small A_t^{\text{GAE}}$，我们不仅需要这一步的惊喜 $\small \delta_t$，还需要未来几步的惊喜 $\small \delta_t, \delta_{t+1}, \dots$；&lt;/li&gt;
&lt;li&gt;把所有惊喜加起来并用衰减因子 $\small (\gamma \lambda)^l$ 限制，意味着越遥远的未来的惊喜对当前的决策影响越小。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;(4) 详细流程图&lt;/strong&gt; - 来自 &lt;a href=&quot;https://openlmlab.github.io/MOSS-RLHF/paper/SecretsOfRLHFPart1.pdf&quot;&gt;Secrets of RLHF in Large Language Models Part I: PPO&lt;/a&gt;
&lt;img src=&quot;./llm.assets/ppos.png&quot; alt=&quot;PPO&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TL;DR - 引入 Clip 机制的好处是可以通过优势函数的正负来判断是否更新策略，而优势函数通过对比模型回答内容的实际奖励是否高于基准奖励来实现策略更新的定向调节。如果高于基准奖励，则指导模型增大当前输入下相应输出的概率 (增大策略在这个状态下采取对应动作的概率)，反之减小。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;GRPO&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;以写作来举例 - PPO 当你每写一个词，他都给你一个反馈。而 GRPO 让你先写出 G 篇完整的文章，然后他阅读所有文章并告诉你哪一篇是最好的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/grpo.png&quot; alt=&quot;GRPO&quot;&gt;&lt;/p&gt;
&lt;p&gt;由于价值模型是与策略模型是类似规模的，且都要进行参数更新，因此会引入较大的内存和计算负担，并且 PPO 的优化信号是基于词元级别，这种机制可能导致训练过程不稳定，且不一定能达到最优性能。&lt;/p&gt;
&lt;p&gt;GRPO 通过消除价值模型并 &lt;strong&gt;将相同问题、不同输出的归一化奖励作为基准奖励&lt;/strong&gt;，从而在 &lt;strong&gt;序列级别&lt;/strong&gt; 对策略进行优化：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{loss}(\theta)&amp;#x26;= \mathbb{E}&lt;em&gt;{[q\sim D&lt;/em&gt;\text{RL}, {o_i}&lt;em&gt;i^G \sim \pi&lt;/em&gt;{\theta_{\text{old}}}]} \frac{1}{G}\sum_{i=1}^{G}\frac{1}{|o_{i}|}\sum_{t=1}^{|o_{i}|} \&lt;/p&gt;
&lt;p&gt;&amp;#x26;\left{\min \left[\frac{\pi_{\theta}(o_{i,t}|q,o_{i,&amp;#x3C;t})}{\pi_{\theta_{\mathrm{old}}}(o_{i,t}|q,o_{i,&amp;#x3C;t})}\hat{A}&lt;em&gt;{i,t},\text{clip}\left(\frac{\pi&lt;/em&gt;{\theta}(o_{i,t}|q,o_{i,&amp;#x3C;t})}{\pi_{\theta_{\mathrm{old}}}(o_{i,t}|q,o_{i,&amp;#x3C;t})},1-\varepsilon,1+\varepsilon\right)\hat{A}&lt;em&gt;{i,t}\right]-\beta~\mathbb{D}&lt;/em&gt;{KL}\left[\pi_{\theta}||\pi_{\text{ref}}\right]\right} \
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;使用无偏差估计方法来计算 KL 散度：&lt;/p&gt;
&lt;p&gt;$$
\small
\mathbb{D}&lt;em&gt;{\text{KL}}[\pi&lt;/em&gt;\theta||\pi_{\text{ref}}]=\frac{\pi_{\text{ref}}(o_{i,t}|q,o_{i,&amp;#x3C;t})}{\pi_\theta(o_{i,t}|q,o_{i,&amp;#x3C;t})}-\log\frac{\pi_{\text{ref}}(o_{i,t}|q,o_{i,&amp;#x3C;t})}{\pi_\theta(o_{i,t}|q,o_{i,&amp;#x3C;t})}-1
$$&lt;/p&gt;
&lt;p&gt;具体来说，通过旧策略采样同一输入的一组输出并使用奖励模型对组内的每个输出打分，然后采用 &quot;群组相对优势估计&quot; 来计算归一化之后的基准奖励 / 优势，有两种不同的途径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结果监督&lt;/strong&gt; - 使用每个输出的最后一个词元计算奖励值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
\small
\hat{A}&lt;em&gt;{i,t} = \tilde{r}&lt;/em&gt;{i} = \frac{r_{i} - \text{mean}(\mathbf{r})}{\text{std}(\mathbf{r})}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;过程监督&lt;/strong&gt; - 使用每个输出的每个词元计算奖励值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
\small
\hat{A}&lt;em&gt;{i,t}=\sum&lt;/em&gt;{\text{index}(j) \geq t}\tilde{r}&lt;em&gt;{i}^{\text{index}(j)}=\sum&lt;/em&gt;{\text{index}(j) \geq t}\frac{r_i^{\text{index}(j)}-\text{mean}(\mathbf{r})}{\text{std}(\mathbf{r})}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small \hat{A}_{i,t}$ 表示在第 $\small i$ 个样本下第 $\small t$ 个时间步的优势估计，且 $\small \mathbf{r}={r_1,r_2,\cdots,r_G}$。&lt;/p&gt;
&lt;h3&gt;DPO&lt;/h3&gt;
&lt;p&gt;上述两种对齐方法都依赖显式奖励模型，且需要复杂的策略优化过程 (多阶段)。而 DPO 提出我们可以直接绕过奖励模型直接优化人类偏好策略，从而将多阶段学习转换为端到端学习。&lt;/p&gt;
&lt;p&gt;根据 KL 约束下的最优策略表达式反解得到关于策略的奖励函数：&lt;/p&gt;
&lt;p&gt;$$
\small
\underbrace{\pi_r^\text{RL}(o\mid q)=\frac{1}{Z(x)}\pi^{\text{SFT}}(o\mid q)\exp \left(\frac{1}{\beta}r(q, o)\right)}&lt;em&gt;{\text{用奖励函数表示策略}} \iff \underbrace{r&lt;/em&gt;\pi(q,o) =\beta \log \frac{\pi^\text{RL}(o\mid q)}{\pi^{\text{SFT}}(o\mid q)}+\beta \log Z(x)}_{\text{用策略表示奖励函数}}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small Z(x)$ 是配方函数。然后将关于策略的奖励函数 $\small r_{\pi_\theta}(q,o)$ 代入 RLHF 中奖励模型的目标函数得到(奖励模型的重参数化)：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{loss}(\theta)&amp;#x26;= -\mathbb{E}&lt;em&gt;{[o_w \succ o_l]}\overbrace{\left[\log \sigma(r&lt;/em&gt;{\pi_{\theta}}(q, o_w)-r_{\pi_\theta}(q, o_l))\right]}^{对比排序损失} \
&amp;#x26;= -\mathbb{E}&lt;em&gt;{[o_w \succ o_l]}\left[\log \sigma\left(\beta \log \frac{\pi&lt;/em&gt;{\theta}^{\text{RL}}(o_w\mid q)}{\pi^{\text{SFT}}(o_w\mid q)}-\beta \log \frac{\pi_{\theta}^\text{RL}(o_l\mid q)}{\pi^{\text{SFT}}(o_l\mid q)}\right)\right]
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;通过隐式定义奖励函数 $\small r_{\pi_{\theta}}(q, o)$ 使其与策略函数 $\small \pi_{\theta}$ 关联，将强化学习的策略优化问题转换为直接优化策略参数 $\small \theta$ 的监督学习问题。并且只要让策略在同一输入下更偏向被选中的 $\small o_w$，就能对齐偏好，而不需要显式训练一个奖励 / 价值模型。适用于有大量的偏好对数据，希望稳定、低成本提升对齐与风格，并且对 &quot;过程奖励 / 逐步信号&quot; 依赖不强的任务。&lt;/p&gt;
&lt;h3&gt;RLAIF&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/rlaif.png&quot; alt=&quot;RLAIF&quot;&gt;&lt;/p&gt;
&lt;p&gt;Constitutional AI 是一种以原则为核心的监督方式，人类仅制定一套高层次的规则 / 宪法，AI 便可依此生成反馈并自我改进，而无需人工撰写示范答案或进行排序。整个训练过程分为两个阶段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;监督阶段&lt;/strong&gt; - Critique (批判) → Revision (修正) → Supervised Learning (监督学习)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RLAIF 阶段&lt;/strong&gt; - AI Comparison (AI 比较) → Preference Model (偏好模型) → RL (强化学习)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;帕累托改进 (Pareto Improvement) 在这里意味着 CAI 在提升 &quot;无害性&quot; 的同时，并没有牺牲 &quot;有用性&quot;。&lt;/p&gt;
&lt;h2&gt;提示工程&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;提示工程 (Prompt Engineering)&lt;/strong&gt; 指的是通过在提示词中写入有价值的信息从而提升大语言模型的现有能力。&lt;a href=&quot;https://www.promptingguide.ai/zh&quot;&gt;提示工程指南&lt;/a&gt;收集了非常多的方法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文学习 (In-Context Learning)&lt;/strong&gt; 指的是大语言模型在推理阶段无需参数更新，仅通过在输入中添加任务示例即可快速适应并完成新任务的能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/cot.png&quot; alt=&quot;思维链&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果仅是使用 &quot;Let&apos;s think step by step.&quot; 而不提供示例，则为 Zero-shot CoT。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;思维链 (Chain-of-Thought)&lt;/strong&gt; 指的是在给定的示例中添加具体的推理步骤使得模型能够应对复杂推理问题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;思维树 (ToT)&lt;/strong&gt; - 将线形 CoT 扩展为树形结构，通过回溯和前瞻策略促进对多条推理路径的探索；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;思维图 (GoT) - 将线形 CoT 扩展为图结构，来更好地捕捉推理步骤之间的依赖和组合关系。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;基于采样的方法 (Self-Consistency)&lt;/strong&gt; - 生成多条推理路径和答案，然后选取多数为最终答案；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于验证的方法 - 比对真实答案和生成答案训练分类器，并对整个推理路径和中间推理步骤进行验证。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过上述策略，能够有效避免单一推理路径不稳定以及推理错误累积现象。&lt;/p&gt;
&lt;h2&gt;检索增强生成&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;推荐阅读 - &lt;a href=&quot;https://arxiv.org/pdf/2407.21059&quot;&gt;Modular RAG&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;检索增强生成&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; - 将输入内容和向量数据库中的内容进行相似度检索，选取若干最优相关片段；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成&lt;/strong&gt; - 将选取到的片段拼接到输入中提供给大模型，生成回答。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/NirDiamant/RAG_Techniques&quot;&gt;RAG techniques&lt;/a&gt; 这里面收集了非常多的 RAG 技巧。&lt;/p&gt;
&lt;h2&gt;智能体&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;智能体&lt;/strong&gt; 指的是基于大语言模型的智能代理，能自主理解任务、规划步骤并调用工具以完成复杂目标。它主要包含四个部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;规划&lt;/strong&gt; - 子任务分解、反思与完善 (ReAct / Reflexion)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆&lt;/strong&gt; - 长期记忆 (RAG / mem0)、短期记忆 (上下文学习)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具使用&lt;/strong&gt; - 调用外部 API 补全模型权重信息、直接是使用外部模型 (HuggingGPT)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行动&lt;/strong&gt; - 与环境交互并更改环境的状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;多智能体系统&lt;/strong&gt; 指的是通过多个自主或半自主的智能体进行协作、竞争或角色分工，以动态交互和互补能力解决复杂任务，并提升生成结果的可靠性、一致性和创造性。&lt;/p&gt;
&lt;h2&gt;多模态基础模型&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;https://github.com/BradyFU/Awesome-Multimodal-Large-Language-Models&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;多模态的核心是在语言模型中通过可训练的 &lt;strong&gt;连接模块 (Connection Module)&lt;/strong&gt; 来注入视觉特征，通过自回归预测下一个文本令牌。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/mllm.png&quot; alt=&quot;MLLM&quot;&gt;&lt;/p&gt;
&lt;h3&gt;CLIP&lt;/h3&gt;
&lt;p&gt;CLIP (Contrastive Language-Image Pretraining) 是 OpenAI 在 2021 年提出的第一个 &lt;strong&gt;多模态预训练算法&lt;/strong&gt;。它首次将图像和文本映射到同一个高维空间 (多模态嵌入空间)，使得跨模态的相似度计算成为可能。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/clip.png&quot; alt=&quot;clip&quot;&gt;&lt;/p&gt;
&lt;p&gt;CLIP 采用 &lt;strong&gt;对比学习 (Contrastive Learning)&lt;/strong&gt; 预训练来训练两个编码器 - Image/Text Encoder，并通过对比损失来学习一个优质的嵌入空间，在该空间中 &lt;strong&gt;正样本的距离较近，而负样本的距离较远&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;常用的对比损失函数为 InfoNCE Loss，其本质上是带有温度系数的交叉熵+Softmax损失：&lt;/p&gt;
&lt;p&gt;$$
\small
L_q = -\log \frac{\exp{(\text{sim}{(q,k_+)}}/\tau)}{\sum_{i=0}^{k}\exp{(\text{sim}{(q,k_-)}/\tau})}
$$&lt;/p&gt;
&lt;p&gt;其中温度系数为 $\small \tau$, 较小的系数会使相似度分布变得更“尖锐”，模型会更专注于区分困难的负样本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在训练过程中，将每个批量的 &lt;strong&gt;图像-文本对&lt;/strong&gt; 传入模型得到若干个图像/文本嵌入，我们希望最大化真实匹配的图像-文本嵌入的余弦相似度 (对角线)，同时最小化错误匹配的相似度。此外由于不同编码器输出的嵌入维度不一致，因此使用线形映射进行维度统一。训练完成后可以通过提示词实现零样本推理能力。&lt;/p&gt;
&lt;p&gt;在推理过程中，以 ImageNet 为例，对一千个类别标签，分别生成一千个对应的文本，比如 A photo of a #Class，然后通过 Image/Text Encoder 计算特征向量并进行相似度匹配，最后选择相似度最高的类别。&lt;/p&gt;
&lt;h3&gt;SigLIP&lt;/h3&gt;
&lt;p&gt;SigLIP 是 Google 在 2023 年提出的用于解决 CLIP 中依赖大批量以及对比损失中 Softmax 计算复杂度过高的问题，其通过 Sigmoid 来判断每一个图像-文本对是否匹配来解决 &lt;strong&gt;CLIP 中单个正样本的相似度计算依赖于批量中所有负样本的二次复杂度问题&lt;/strong&gt;，从而将“多选一”的分类问题转换为二分类问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/loss_compare.png&quot; alt=&quot;目标函数对比&quot;&gt;&lt;/p&gt;
&lt;p&gt;对比学习通常采用 DP 来加快训练速度，单个正样本计算的时候，需要通过 All-Gather 操作来获取所有其他设备上的嵌入，并且该过程需要构建一个批量大小二次方的相似度矩阵，这无疑是非常耗时且占用显存的。因此，作者根据 Sigmoid 函数的特性，提出了一种内存高效、速度快且数值稳定的分布式计算方法：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/sig_graph.png&quot; alt=&quot;Sigmoid Graph&quot;&gt;&lt;/p&gt;
&lt;p&gt;在上图中，只有黄色方块存储在内存中，分块实现可以总结为每个 GPU 的以下步骤：1）计算本地文本/图像的嵌入损失；2）从相邻 GPU 获取文本嵌入；3）使用本地图像和相邻文本嵌入计算损失；4）将新的损失累加到总损失中；5）重复步骤 2 直到所有相邻 GPU 完成文本嵌入的传递。&lt;/p&gt;
&lt;h3&gt;BLIP&lt;/h3&gt;
&lt;p&gt;BLIP 是 Salesforce Research 在 2022 年提出的视觉语言预训练 (VLP) 框架，其引入了两种创新方法来解决现有 VLP 模型在理解/生成任务上的局限性以及 &lt;strong&gt;如何高效利用网页噪声图文对的问题&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Captioning &amp;#x26; Filtering&lt;/strong&gt; - 提出数据集 &quot;自举 (Bootstrapping)&quot; 的方法，利用 &quot;字幕器&quot; 为网络图像生成合成描述，再通过“过滤器”剔除原始网络文本和合成文本中的噪声数据，以此来提升样本的整体质量；&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/capfilt.png&quot; alt=&quot;Caption Filter&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multimodal Mixture of Encoder-Decoder/MED&lt;/strong&gt; - 提出统一架构来切换单模态编码器、图像引导的文本编码器、图像引导的文本解码器，并联合优化三个目标：1）&lt;strong&gt;图文对比损失(ITC)&lt;/strong&gt; - 对称 InfoNCE 损失，引入动量编码器 (EMA) 来生成伪标签，并通过图/文动态队列来扩充负样本规模；2）&lt;strong&gt;图文匹配损失(ITM)&lt;/strong&gt; - 二分类任务，在融合后的图文对嵌入上添加分类头来判断正/负样本，采用难负样本挖掘 (Hard Negative Mining) 从批量中筛选正例类似样本优先训练，强化模型对细粒度图文差异的判别能力；3）&lt;strong&gt;语言建模损失(LM)&lt;/strong&gt; - 以图像嵌入作为前缀输入给自回归文本解码器，通过交叉熵最大化下一个词元的预测概率。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/blip.png&quot; alt=&quot;BLIP 模型架构&quot;&gt;&lt;/p&gt;
&lt;p&gt;BLIP‑2 通过在冻结的视觉编码器和大语言模型之间 &lt;strong&gt;引入两阶段预训练的轻量级模块 Q‑Former&lt;/strong&gt;，以可学习的查询向量提取与文本相关的关键视觉嵌入，避免二次微调，大幅降低训练成本，实现跨模态理解与生成。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/rp.png&quot; alt=&quot;表示学习&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;表示学习阶段&lt;/strong&gt; - 联合优化三个目标：1）&lt;strong&gt;图文对比损失 (ITC)&lt;/strong&gt; - 计算每一个视觉 Query 嵌入与 Text 嵌入的相似度，选取最高的一个作为图文相似度，并采用对比学习进行训练；2）&lt;strong&gt;图生文损失 (ITG)&lt;/strong&gt; - 通过自注意力融合 Text 嵌入与提取的 Query 嵌入，使得 Q-Former 学习文本相关的视觉嵌入，并能够根据视觉嵌入生成相应文本；3）&lt;strong&gt;图文匹配损失 (ITM)&lt;/strong&gt; - 将每个 Query 嵌入与 Text 嵌入融合后输入到二线性分类器中来判断是否匹配，并通过难负样本挖掘强化模型细粒度判别能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/gp.png&quot; alt=&quot;生成学习&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生成学习阶段&lt;/strong&gt; - 在第一阶段训练完成后，Q-Former 已经具备了提取高质量视觉表示的能力，而该阶段训练 Q-Former 具备高质量的文本生成能力。首先将一阶段提取的视觉嵌入通过全连接层映射到文本嵌入相同维度一并传入大模型，目的是使得模块提取的视觉嵌入能被大模型读懂并用于生成相应的文本。&lt;/p&gt;
&lt;h3&gt;Flamingo&lt;/h3&gt;
&lt;p&gt;Flamingo 是 Google 在 2022 年提出的视觉语言模型(VLM)，其不仅能理解视觉信息并生成流畅的文本，且能通过 &lt;strong&gt;跨模态的少样本学习&lt;/strong&gt;，使其能够适应全新的视觉语言任务。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/flam.png&quot; alt=&quot;Flamingo&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;感知重采样器 (Perceiver Resampler)&lt;/strong&gt; - 解决高维视觉表征输入给语言模型导致的开销问题。其使用固定数量的“潜在查询嵌入”，通过交叉注意力机制去“查询”和“总结”视觉嵌入，将变长的视觉嵌入浓缩为定长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;门控交叉注意力单元 (Gated Cross-Attention-Dense)&lt;/strong&gt; - 解决浓缩的视觉嵌入如何有效注入给语言模型的问题。其使用门控交叉注意力单元，该单元插入可训练的交叉注意力层使得模型在生成文本的时候可以参考图像内容。并且通过门控机制来保证训练初期的稳定性，让模型能够平滑地适应多模态输入。&lt;/p&gt;
&lt;p&gt;该模型使用了注意力掩码来处理交错的图文序列，使得每一个文本 Token 在计算注意力时只会关注紧邻其前一张图片的视觉 Token。并且更早的图片已经通过交叉注意力融入到文本表示中，因此能够泛化到任意数量的视觉输入而不需要在训练中见过同等数量输入。&lt;/p&gt;
&lt;h3&gt;LLaVA&lt;/h3&gt;
&lt;p&gt;LLaVA 是 Microsoft 在 2023 年提出的通过 &lt;strong&gt;指令微调&lt;/strong&gt; 的方式来增强模型的零/少样本学习能力，从而实现端到端的多模态系统 (基于多模态输入来生成连贯的问答、描述、推理)。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/llava.png&quot; alt=&quot;LLaVA&quot;&gt;&lt;/p&gt;
&lt;p&gt;预训练模态对齐 - 为语言模型训练一个的“模态对齐器”。只更新线形投影层，冻结视觉编码器和语言模型权重。对于图像 $\small X_v$，随机采样一个问题 $\small X_q$，要求助手简要描述图像，真实答案 $\small X_a$ 是原始标题。&lt;/p&gt;
&lt;p&gt;端到端微调 - 只更新语言模型和线形投影层，冻结视觉编码器权重。将问题和上下文作为 $\small X_{\text{Instruct}}$，推理过程和答案作为 $\small X_a$，进行单论对话微调。&lt;/p&gt;
&lt;p&gt;指令跟随数据集构建过程 - 将带有 Caption 和 BBox 信息的 COCO 数据集提供给 GPT 让它输出三种指令数据，分别是对话数据、详细描述数据和复杂推理数据，形成 LLaVA-Instruct-158K 数据集。&lt;/p&gt;
&lt;h3&gt;Qwen-VL&lt;/h3&gt;
&lt;p&gt;Qwen-VL 是 Alibaba 在 2023 年提出的大规模视觉语言模型(LVLM)，其核心目标是构建一个能够统一理解图像、文本甚至更多模态输入的模型，以掌握真实世界应用中的多样化能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/qwen_vl.png&quot; alt=&quot;Qwen-VL&quot;&gt;&lt;/p&gt;
&lt;p&gt;关注架构中的 &quot;适配器&quot;，其使用一组可训练 Query，通过单层交叉注意力模块来压缩视觉编码器输出的视觉嵌入，并引入 2D 绝对位置编码来保留图像位置信息。并且通过三阶段训练之后的模型在细粒度识别、多语言 OCR、视觉定位等方面具备强大的能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./llm.assets/qwen2_vl.png&quot; alt=&quot;Qwen2-VL&quot;&gt;&lt;/p&gt;
&lt;p&gt;Qwen2-VL 旨在解决现有 LVLMs 中存在的固定输入尺寸、依赖 CLIP 风格视觉编码器的问题，提出了：1）&lt;strong&gt;Naive Dynamic Resolution&lt;/strong&gt; - 将 ViT 结构中的绝对位置嵌入修改为 2D-RoPE，合并输出特征图上的 2x2 Visual Token 为 1 个，并添加 &amp;#x3C;|vision_start/end|&gt; 特殊标记；2）&lt;strong&gt;M-RoPE&lt;/strong&gt; - 将原始 1D-RoPE 分解为时间、宽度和高度三个部分，并为不同的模态数据分配不同的位置 ID 组合。&lt;/p&gt;
&lt;h2&gt;高效训练技术&lt;/h2&gt;
&lt;h3&gt;3D 并行训练&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/3dp.png&quot; alt=&quot;3D 并行&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据并行 (Data Parallelism / DP)&lt;/strong&gt; - 该方法将完整的模型参数和优化器状态同步至所有参与训练的设备，并将全局批次划分成多个小批次给每个设备，然后执行前向/反向传播计算梯度，通过 All-Reduce 操作对各设备计算后的梯度进行聚合，并确保所有计算设备基于统一的梯度进行更新。优点是实现简单，能有效扩展训练的吞吐量。缺点是每个设备都需要存储完整的模型参数、梯度和优化器状态，&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;流水线并行 (Pipeline Parallelism / PP)&lt;/strong&gt; - 该方法将模型的不同层计算划分为多个阶段，并分配到不同的设备上，比如 24 层划分为 4 个阶段，每台设备处理 6 层。并且需要将输入的小批次进一步划分为微批次(Micro-Batch)，当第一台设备的微批次的前向传播完成后，将中间值发送给第二台设备，当第二台设备开始处理第一个微批次的时候第一台设备开始处理第二个微批次，全部处理完成之后按相反的顺序进行反向传播。优点是降低了单台设备的显存占用，且通信开销较低。缺点是存在 &quot;流水线气泡&quot;，即流水线的启动和结束会存在设备空闲，导致部分计算资源浪费，因此有效进行模型切分是关键，需要保证计算的负载均衡。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;张量并行 (Tensor Parallelism / TP)&lt;/strong&gt; - 该方法将计算过程中的参数矩阵按列/行分块并分配到不同的设备上，然后并行地执行矩阵乘法，最后将结果合并。需要注意针对不同的算子类型采用不同的切分方法。优点是解决了单卡显存瓶颈问题。缺点是引入了大量的通信开销，因为每一层的计算需要多次合并操作，对带宽的要求较高，因此 TP 通常在节点内的多台设备上进行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;专家并行 (Expert Parallelism / EP)&lt;/strong&gt; -&lt;/p&gt;
&lt;h3&gt;零冗余优化器 (ZeRO)&lt;/h3&gt;
&lt;p&gt;该方法由 DeepSpeed 团队提出，旨在解决 DP 中的内存冗余问题，其通过 &lt;strong&gt;分片存储&lt;/strong&gt; 策略，将模型参数、优化器状态和梯度分散到不同的设备上，从而减少单设备的显存需求。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ZeRO-1 - 将优化器状态平摊到每台设备上，而模型参数和梯度各自保留；&lt;/li&gt;
&lt;li&gt;ZeRO-2 - 在 ZeRO-1 的基础上，将梯度也平摊到每台设备上；&lt;/li&gt;
&lt;li&gt;ZeRO-3 - 在 ZeRO-2 的基础上，将模型参数也平摊到每台设备上。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;激活重计算&lt;/h3&gt;
&lt;p&gt;激活重计算也称为梯度检查点 (Gradient Checkpointing)，该技术在前向计算的过程中保留部分激活值，在反向传播的过程当中重新激活需要的激活值，从而达到节约显存的目的。&lt;/p&gt;
&lt;h3&gt;混合精度训练&lt;/h3&gt;
&lt;p&gt;混合精度训练指的是同时使用半精度浮点数 (2 个字节) 和单精度浮点数 (4 个字节) 进行运算，以实现显存开销减半、训练效率翻倍的效果。即在前向/反向传播中使用半精度计算，在参数更新的时候使用单精度计算。&lt;/p&gt;
&lt;p&gt;常见的半精度浮点数表示方式为 FP16，包含 1 位符号位、5 位指数位、10 位尾数位。进一步 Google 研究人员开发出了 BF16，其包含 1 位符号位、8 位指数位、7 位尾数位，表示范围可以达到 $10^{38}$ 数量级，在模型训练中被广泛使用。&lt;/p&gt;
&lt;h2&gt;长上下文&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2311.12351&quot;&gt;Advancing Transformer Architecture in Long-Context Large Language Models&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;幻觉&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2309.01219&quot;&gt;Siren&apos;s Song in the AI Ocean: A Survey on Hallucination in Large Language Models&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;评估&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2310.19736&quot;&gt;Evaluating Large Language Models: A Comprehensive Survey&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/654910335&quot;&gt;历史技术文章导航 / 猛猿&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hijkzzz/Awesome-LLM-Strawberry&quot;&gt;Awesome-LLM-Strawberry / hijkzzz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/OpenRLHF/OpenRLHF/tree/main&quot;&gt;OpenRLHF / OpenRLHF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Transformer</title><link>https://k1tyoo.ink/blog/dl/trm</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/trm</guid><description>深度学习 - 笔记 7</description><pubDate>Mon, 13 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;注意力机制&lt;/h2&gt;
&lt;p&gt;通过引入同一序列计算得出的 Query/Key/Value 来改进上下文向量的计算公式，从而 &lt;strong&gt;&quot;避免 RNN 中编(解)码器的串行隐状态计算&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
e_{ij}&amp;#x26;=\alpha{(s_{i-1},h_j)} &amp;#x26;&amp;#x26; \quad \rightarrow \quad a_{ij}=\alpha{(q_{i-1},k_j)} \
c_i&amp;#x26;=\sum_{j=1}^{T} a_{ij}h_j &amp;#x26;&amp;#x26; \quad \rightarrow \quad y_i=\sum_{j=1}^{T}a_{ij}v_j
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;通过评分函数 $\small \alpha$ 计算 &quot;查询&quot; 对每一个 &quot;键&quot; 的相似度得到权重矩阵，然后与 &quot;值&quot; 聚合起来得到上下文向量。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用查字典来举例：查询的信息为 &quot;中国&quot;，计算对字典中每个词的相似度得到相似度最大的两个词 &quot;华夏&quot;、&quot;唐宋&quot;。然后将这两个词对应的信息聚合起来，来代表 &quot;中国&quot; 这个词。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Transformer&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;推荐查看 - https://jalammar.github.io/illustrated-transformer/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;缩放点积注意力&lt;/h3&gt;
&lt;p&gt;自注意力(Self-Attention)通过 &lt;strong&gt;&quot;计算同一段序列中不同词元之间的注意力&quot;&lt;/strong&gt;，从而对序列中的每一个词元进行上下文建模。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/sdpa.png&quot; alt=&quot;缩放点积注意力&quot;&gt;&lt;/p&gt;
&lt;p&gt;第一个词元的查询向量 $\small q_1$ 与所有词元的键向量 $\small k_{1,2,3}$ 之间计算相似度得到 $\small a_{11,12,13}$ 权重向量，然后权重向量与所有的值向量 $\small v_{1,2,3}$ 进行矩阵相乘得到第一个词元的上下文向量 $\small y_1$，该向量聚合了其余词元对当前词元的影响程度。以此类推就可以得到每一个词元的上下文向量，从而建模所有词元之间的关系依赖。&lt;/p&gt;
&lt;h3&gt;多头注意力&lt;/h3&gt;
&lt;p&gt;单头无法表征序列的所有信息，通过引入不同的头在 &lt;strong&gt;&quot;同一时刻关注序列中的不同部分&quot;&lt;/strong&gt;，从而学习到不同的上下文向量，汇总之后作为逐词元的上下文向量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/mha.png&quot; alt=&quot;多头注意力&quot;&gt;&lt;/p&gt;
&lt;p&gt;(每个头独立计算) 以第二个头的计算举例，第一个词元的切分查询向量 $\small q_{12}$ 与所有词元的切分键向量 $\small k_{12, 22}$ 之间计算相似度得到 $\small a_{112,122}$ 切分权重向量，然后与所有切分值向量 $\small v_{12,22}$ 进行矩阵相乘得到第一个词元的切分上下文向量 $\small y_{12}$。此时第一个头的并行计算结果为 $\small y_{11}$，将其汇总之后得到第一个词元的上下文向量 $\small y_1$。以此类推得到每个头为每个词元计算的切分向量，汇总之后注入更多信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数维度分析&lt;/strong&gt; - 假设 $\small d$ 是词向量维度、$\small n_h$ 是注意力头的数量、$\small \small d_h$ 是每个头的维度、$\small s$ 是序列长度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入为 $\small X\in \mathbb{R}^{d\times s}$、权重参数为 $\small W^q\in \mathbb{R}^{d_hn_h\times d}$，那么查询矩阵为 $\small Q \in \mathbb{R}^{d_hn_h\times s}$；&lt;/li&gt;
&lt;li&gt;结合查询矩阵和键矩阵得出权重矩阵为 $\small A\in \mathbb{R}^{s\times s}$，且值矩阵为 $\small V\in \mathbb{R}^{d_hn_h\times s}$；&lt;/li&gt;
&lt;li&gt;结合权重矩阵和值矩阵得出上下文矩阵 $\small Y \in \mathbb{R}^{d_hn_h\times s}$，每一个上下文向量为 $\small y \in \mathbb{R}^{d_hn_h\times 1}$；&lt;/li&gt;
&lt;li&gt;结合后续的输出矩阵 $\small W^o\in \mathbb{R}^{d\times d_hn_h}$ 得到最终的注意力层输出为 $\small O\in \mathbb{R}^{d\times s}$。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以发现 &quot;注意力层的输入和输出维度是相同的&quot;。&lt;/p&gt;
&lt;h3&gt;逐位前馈神经网络&lt;/h3&gt;
&lt;p&gt;将注意力层输出的特征进一步进行非线性变换从而进一步提升模型的表达能力。逐位指的是 &lt;strong&gt;&quot;每个词元的特征重计算都是独立的&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/pffn.png&quot; alt=&quot;逐位前馈神经网络&quot;&gt;&lt;/p&gt;
&lt;p&gt;上图右侧展示的是一次非线性变化的结果，并且可以使用 $\small 1\times 1$ 卷积替代非线性变换操作。&lt;/p&gt;
&lt;h3&gt;绝对位置编码&lt;/h3&gt;
&lt;p&gt;自注意力机制具有 &lt;strong&gt;&quot;置换不变形&quot;&lt;/strong&gt;，无法捕捉序列中的顺序关系，因此引入位置编码对序列进行位置建模。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/pe.png&quot; alt=&quot;位置编码&quot;&gt;&lt;/p&gt;
&lt;p&gt;根据 &lt;strong&gt;&quot;正余弦函数&quot;&lt;/strong&gt; 来生成 &lt;strong&gt;&quot;对应位置的唯一位置嵌入&quot;&lt;/strong&gt;，并将其加到词元的词向量上。对于维度大小为 $\small d$ 的词向量，它的编码方式为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{cases}
p_{k, 2i} = \sin\left(k/10000^{2i / d}\right) \
p_{k, 2i+1} = \cos\left(k/10000^{2i / d}\right)
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small p_{k,2i}$ 和 $\small p_{k,2i+1}$ 表示第 $\small k$ 个词元的词向量的 $\small 2i$ 和 $\small 2i+1$ 个分量。&lt;/p&gt;
&lt;h3&gt;激活函数&lt;/h3&gt;
&lt;p&gt;GeLU(Gaussian Error Linear Unit)利用基于正态的累积分布函数来调节输入信息的激活程度，使得中间区域的输入梯度更为平滑，起到正则化的作用。&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{GeLU}(x)&amp;#x26;=x\cdot \Phi(x) \
&amp;#x26;= x\cdot \frac{1}{2}\left(1+\text{erf}(\frac{x}{\sqrt{2}})\right)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small \Phi(x)$ 是累积分布函数、$\small \text{erf}(\cdot)$ 表示误差函数。&lt;/p&gt;
&lt;p&gt;SwiGLU(Swish-Gated Linear Unit)将 Swish 的平滑与 GLU 的门控机制结合起来使得梯度能够有效传播，是目前 LLM 使用的主流激活函数。&lt;/p&gt;
&lt;p&gt;$$
\small
\text{SwiGLU}(x)=\text{Swish}(xW_1+b_1)\otimes \sigma(xW_2+b_2)
$$&lt;/p&gt;
&lt;h3&gt;编码器 / 解码器&lt;/h3&gt;
&lt;p&gt;Transformer 堆叠了六层编(解)码器，并且 &lt;strong&gt;&quot;每层输入和输出的维度都是 (batch, seq, hidden)&quot;&lt;/strong&gt;，即批量大小、序列长度、词向量维度。&lt;/p&gt;
&lt;p&gt;解码器在推理阶段具有 &lt;strong&gt;自回归属性&lt;/strong&gt;，具体来说：1）输入经过解码器后获得词表上的概率分布并采样得到输出；2）将输出添加到下一步输入后侧并继续生成。&lt;/p&gt;
&lt;p&gt;而在训练阶段因为提供了目标序列，使得模型能够参考该序列直接获得下一个词元。而通过 &lt;strong&gt;&quot;掩码多头注意力&quot;&lt;/strong&gt; 对权重矩阵进行下三角遮掩，就能使得模型在训练阶段 &lt;strong&gt;&quot;只参考历史信息而忽略未来信息&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;$$
\small
a_{ij}=\begin{cases}
0 &amp;#x26;  j \leq i \
-\infty &amp;#x26;  j &gt; i \quad \rightarrow \text{\footnotesize 未来词元}
\end{cases}
$$&lt;/p&gt;
&lt;p&gt;通过对注意力权重进行遮掩，使未来词元对应的分数在随后进行 softmax 时趋近于 0，从而在计算上下文向量时屏蔽未来词元的影响，进而保持解码器训练阶段的自回归属性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/causal.png&quot; alt=&quot;掩码多头注意力机制&quot;&gt;&lt;/p&gt;
&lt;p&gt;通过 &lt;strong&gt;&quot;交叉注意力(Cross Attention)&quot;&lt;/strong&gt; 机制来处理编码器最后一层的 K/V 和解码器当前层的 Q。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/eda.png&quot; alt=&quot;交叉注意力&quot;&gt;&lt;/p&gt;
&lt;h2&gt;注意力模块的优化&lt;/h2&gt;
&lt;p&gt;自注意力模块中的权重矩阵计算是二次复杂度 $\small O(n^{2})$，因为它要对序列中的任意两个词向量计算相似度。&lt;/p&gt;
&lt;h3&gt;Sparse Attention&lt;/h3&gt;
&lt;p&gt;从注意力分数矩阵的角度来说，就是除了相对距离不超过 $\small k$ 的、相对距离为 $\small k$ 的倍数的注意力权重都设置为 0。这样注意力就具有了 &lt;strong&gt;&quot;局部紧密相关和远程稀疏相关&quot;&lt;/strong&gt; 的特性。&lt;/p&gt;
&lt;p&gt;该方法的不足之处就是需要人工选择保留的注意力区域，不利于扩展。但是由于将每个词元的注意力压缩在了较小的空间中(每个词元只能看到训练长度的词元)，因此能 &lt;strong&gt;&quot;一定程度上缓解长度外推问题&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;Linear Attention&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/la.png&quot; alt=&quot;线形注意力&quot;&gt;&lt;/p&gt;
&lt;p&gt;通过观察上图可以发现如果去掉 softmax 函数和缩放系数，那么注意力的计算实际上就是三个矩阵连乘，复杂度仅有 $\small O(s)$。因此用一般函数 $\small \text{sim}(\cdot)$ 替代指数操作：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{attn}(q_i,k_j,v_j)=\frac{\sum_{j=1}^{n}\text{sim}(q_i,k_j)v_j}{\sum_{j^\prime=1}^{n}\text{sim}(q_i,k_{j^\prime})}
$$&lt;/p&gt;
&lt;p&gt;为了保留注意力相似的分布特征，我们需要保证 $\small \text{sim}(q_i,k_j) \geq0$ 恒成立。&lt;/p&gt;
&lt;p&gt;而线形注意力就是用 &lt;strong&gt;&quot;核函数&quot;&lt;/strong&gt; 代表这个一般函数，即 $\small \text{sim}(q_i, k_j) = \phi(q_i)^{\text{T}}\phi(k_j)$。&lt;/p&gt;
&lt;p&gt;$$
\small
\text{attn}(q_i, k_j, v_j) = \phi(q_i)\cdot \left[\phi(k_j)^{\text{T}}v_j\right]
$$&lt;/p&gt;
&lt;p&gt;其中核函数选择 $\small\phi(x)=\text{elu}(x)+1$。&lt;/p&gt;
&lt;h3&gt;KV Cache&lt;/h3&gt;
&lt;p&gt;自回归属性的解码器在 &lt;strong&gt;&quot;Token-by-Token&quot;&lt;/strong&gt; 生成时每一次上下文向量的计算都涉及当前时刻的 &quot;查询&quot; 和历史时刻的 &quot;键/值&quot;。而 KV Cache 通过 &lt;strong&gt;&quot;缓存并重用历史的键/值&quot;&lt;/strong&gt;，从而提升推理速度。&lt;/p&gt;
&lt;p&gt;假设解码器的层数为 $\small l$，那么每生成一个词元就需要保存 $\small 2n_hd_hl$ 个元素，可以发现缓存的大小 &lt;strong&gt;&quot;随着序列长度的增加呈现线形增长&quot;&lt;/strong&gt;。但是缓存的内容都保存在 &quot;HBM&quot; 中，因此容易导致读写/存储带宽瓶颈。&lt;/p&gt;
&lt;p&gt;后续针对注意力机制的改进都是围绕如何在减少缓存的同时能够实现在更少设备上推理更长的上下文，或者在相同推理上下文的背景下使用更大的批量，从而实现更快的推理速度 / 更大的吞吐总量。&lt;/p&gt;
&lt;h3&gt;GQA / MQA / MLA&lt;/h3&gt;
&lt;p&gt;GQA 将注意力头切分为 $\small g$ 组，每组共享同一个键/值，若原来是 $\small n_h$ 个头，那么每 $\small \frac{n_h}{g}$ 个头共享一份键/值。而 MQA 在所有头中共享一份键/值。可以发现当 $\small g=1$ 时 GQA 就会退化为 MQA。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/mla.png&quot; alt=&quot;MLA&quot;&gt;&lt;/p&gt;
&lt;p&gt;Multi-Head Latent Attention(MLA) 的核心思想是 &lt;strong&gt;&quot;低秩键值联合压缩 / 解耦 RoPE&lt;/strong&gt;&quot;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过缓存压缩的潜在向量 $\small c_t^{KV}$ 从而避免在每次生成时重复计算高维的 &quot;键/值向量&quot;：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{score}(q_t^{C}, k_t^{C}) &amp;#x26;= (q_t^C)^{T} \times k_t^{C} \
&amp;#x26;= (W^{UQ}c_t^{Q})^{T} \times (W^{UK}c_t^{KV}) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 基于对应的潜在向量} \hspace{0.1cm} c_t\
&amp;#x26;=(c_t^Q)^{T}(W^{UQ})^{T}\times (W^{UK})(c_{t}^{KV}) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 基于矩阵转置性质} \
&amp;#x26;=(c_t^{Q})^{T}\underbrace{\left[(W^{UQ})^{T}\times (W^{UK})\right]}_{上投影矩阵权重融合}(c_t^{KV}) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 基于乘法结合律进行权重融合}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;若不采用 &quot;权重融合&quot; 且假设推理阶段生成 $\small n$ 个新词元，那么就需要进行 $\small n-1$ 次矩阵向量乘法，这无疑是非常低效的。同理也可以将 $\small W^{UV}$ 融合到 $\small W^{O}$ 中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解耦(Decoupled) RoPE 将 &quot;查询/键&quot; 向量切分为内容部分(携带语义信息)和位置部分(携带位置信息)：
$$
\small
\begin{aligned}
q_{t}^R&amp;#x26;=\text{RoPE}(W^{QR}c_t^{Q}) \quad k_t^R=\text{RoPE}(W^{KR}h_t) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 解耦键向量共享} \
q_{t}&amp;#x26;=[q_{t}^C; q_{t}^R] &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 注入位置信息} \
o_{t}&amp;#x26;=\sum_{j=1}^t\mathrm{softmax}&lt;em&gt;j\left(\frac{q&lt;/em&gt;{t}^\text{T}k_{j}}{\sqrt{d_h+d_h^R}}\right)v_{j}^C &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 使用拼接后的向量计算注意力} \
u_t&amp;#x26;=W^Oo_t &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 计算汇总后的上下文向量}
\end{aligned}
$$
通过对新的位置部分 $\small k_t^R$ 进行 RoPE 然后将信息拼接注入到内容部分上，从而避免了对 &quot;查询/键&quot; 向量旋转产生的带有位置信息的矩阵 $\small \mathcal{R}_{n-m}$ 而无法进行 &quot;权重融合&quot; 的现象。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在实际的推理过程中，我们只需要缓存低维潜在向量 $\small c_t^{KV} \in \mathbb{R}^{d_c}$ ($\small d_c \ll d_hn_h$) 以及解耦出的低维位置键向量 $\small k_t^R \in \mathbb{R}^{d_h^R}$ 即可，分别用来计算上下文向量和位置信息。此时每个词元的缓存元素大小为 $\small (d_c + d_h^R)l$。&lt;/p&gt;
&lt;h3&gt;Flash Attention&lt;/h3&gt;
&lt;p&gt;注意力计算过程中最大中间结果就是分数矩阵，而最终的上下文向量反而很小。Flash Attention 通过将中间计算结果保留在大带宽的 SRAM 中，获得最终结果再写回小带宽的 HBM 中的操作，避免了带宽瓶颈。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/flash.png&quot; alt=&quot;Flash Attention&quot;&gt;&lt;/p&gt;
&lt;p&gt;具体来说，其将所有的注意力计算操作融合(Fuse)到一个单独的 GPU 内核中，在这个融合内核中，包括 &lt;strong&gt;分块计算(Tiling)&lt;/strong&gt; 和 &lt;strong&gt;重计算(Recomputation)&lt;/strong&gt; 两项技术。最终的 HBM IO 复杂度对比：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vanilla Attention - $\small O(nd+n^{2})$；&lt;/li&gt;
&lt;li&gt;Flash Attention - $\small O(n^2d^2/m) \ll O(nd+n^2)$。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Ring Attention&lt;/h3&gt;
&lt;h2&gt;混合专家模型(MoE)&lt;/h2&gt;
&lt;p&gt;MoE 将原来 Transformer 等架构中的 FFN 层替换为一个包含 &lt;strong&gt;&quot;多路专家子网络&quot;&lt;/strong&gt; 的稀疏模块，每个专家在训练阶段根据输入数据动态学习不同的特征，而在推理阶段只调用最相关的若干个专家，从而达到提高模型表达能力同时节省计算资源的目的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/moe.png&quot; alt=&quot;混合专家模型&quot;&gt;&lt;/p&gt;
&lt;p&gt;首先通过 &lt;strong&gt;&quot;门控网络(Router)&quot;&lt;/strong&gt; 计算权重，该权重表示每个专家对当前词元的关注程度。通常是一个简单的神经网络，将输入隐状态 $\small h_t^{l}$ 通过 softmax 映射为概率分布：&lt;/p&gt;
&lt;p&gt;$$
\small
s_{i,t}=\text{softmax}_i(h_t^{l}w_i^{l})
$$&lt;/p&gt;
&lt;p&gt;其中 $\small w_i^{l}$ 表示第 $\small l$ 层第 $\small i$ 个专家的权重、$\small s_{i,t}$ 表示第 $\small i$ 个专家对第 $\small t$ 个词元的关注程度(亲和度分数)。然后取 top-k 个专家参与计算，其余权重置零(稀疏激活)，最后将专家权重/输出聚合。&lt;/p&gt;
&lt;p&gt;$$
\small o_t^l=\sum_{i=1}^N\left[g_{i,t} \times \text{FFN}_i(h_t^l)\right]+h_t^l
$$&lt;/p&gt;
&lt;p&gt;传统的 MoE 存在以下问题：1）单个专家涵盖多种知识，无法充分同时利用；2）多个专家涵盖通用的冗余知识，阻碍了 MoE 的理论性能上限。&lt;/p&gt;
&lt;p&gt;DeepSeekMoE 通过 &lt;strong&gt;&quot;划分更细粒度的专家&quot;&lt;/strong&gt; 以及 &lt;strong&gt;&quot;单个专家存储通用知识&quot;&lt;/strong&gt; 来解决上述问题，从而实现每个专家的高度专业化：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
o_t^l &amp;#x26;= \sum^{k_s}&lt;em&gt;{i=1}\text{FFN}&lt;em&gt;i(h_t^l) + \sum&lt;/em&gt;{i=k&lt;/em&gt;{s+1}}^{mN}\left(g_{i,t}\times \text{FFN}&lt;em&gt;i(h_t^l)\right) + h_t^l \
g&lt;/em&gt;{i,t}&amp;#x26;=\begin{cases}s_{i,t} &amp;#x26; s_{i,t}\in \text{topk}({s_{j,t}|k_s+1 \leq j \leq mN}, mk-k_s)\ 0&amp;#x26; \text{otherwise}\end{cases}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;将专家的中间维度缩小 $\small 1/m$ 倍并将数量提升 $\small m$ 倍。隔离 $\small k_s$ 个专家作为共享专家并时刻保持激活，而其它路由的专家数量就要相应减少 $\small k_s$ 个，因此在保持计算成本和参数量的前提下激活的专家数量为 $\small mk-k_s$。&lt;/p&gt;
&lt;h2&gt;归一化&lt;/h2&gt;
&lt;h3&gt;Post / Pre-Norm&lt;/h3&gt;
&lt;p&gt;Post-Norm - 归一化放置在残差计算之后：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{Post-Norm}(x)=\text{Norm}(x+\text{Sublayer(x)})
$$&lt;/p&gt;
&lt;p&gt;训练时间较快、网络容易调优、输出层梯度较大引发的训练不稳定。&lt;/p&gt;
&lt;p&gt;Pre-Norm - 归一化放置在子层计算中：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{Pre-Norm}(x)=x+\text{Sublayer}(\text{Norm}(x))
$$&lt;/p&gt;
&lt;p&gt;训练稳定、效果不如 Post-Norm、缓解梯度消失(爆炸)问题，现代 LLM 首选。&lt;/p&gt;
&lt;h3&gt;RMS-Norm&lt;/h3&gt;
&lt;p&gt;在 Layer-Norm 中减去均值表示将数据分布的中心移动到原点(重中心化)、除以标准差表示将数据分布调整为标准大小(重缩放)。其成功的关键在于重缩放带来的方差不变性，而重中心化贡献较小且在某些情况下会损失性能。&lt;/p&gt;
&lt;p&gt;RMS-Norm 通过去除重中心化，保留重缩放从而在保证性能的情况下降低计算复杂度。&lt;/p&gt;
&lt;p&gt;$$
\small
\hat{h}&lt;em&gt;t=\frac{h_t}{\text{RMS}(h_t)}\odot \gamma, \quad \text{RMS}(h_t)=\sqrt{\frac{1}{d}\sum&lt;/em&gt;{i=1}^{d}h_i^2}
$$&lt;/p&gt;
&lt;h2&gt;位置编码&lt;/h2&gt;
&lt;h3&gt;绝对位置编码&lt;/h3&gt;
&lt;p&gt;输入由词向量 $\small E_{x_i}$ 和位置向量 $\small U_i$ 组成，对注意力分数计算公式 $\small q_i^{\text{T}}k_j$ 进行因式分解得到：&lt;/p&gt;
&lt;p&gt;$$
\small
A_{i,j}^{\text{abs}}=\underbrace{E_{x_{i}}^{\text{T}}W_q^{\text{T}}\textcolor{green}{W_k}E_{x_j}}&lt;em&gt;{\text{内容相关项}}+\underbrace{E&lt;/em&gt;{x_{i}}^{\text{T}}W_q^{\text{T}}\textcolor{green}{W_{k}}\textcolor{blue}{U_{j}}}&lt;em&gt;{\text{内容-位置耦合项}}+\underbrace{\textcolor{red}{U&lt;/em&gt;{i}^{\text{T}}W_q^{\text{T}}}\textcolor{green}{W_k}E_{x_j}}&lt;em&gt;{\text{位置-内容耦合项}}+\underbrace{\textcolor{red}{U&lt;/em&gt;{i}^{\text{T}}W_{q}^{\text{T}}}\textcolor{green}{W_{k}}\textcolor{blue}{U_{j}}}_{\text{位置相关项}}
$$&lt;/p&gt;
&lt;p&gt;可以发现只有最后一项包含 $\small U_i$ 和 $\small U_j$，理论上包含相对位置 $\small(j-i)$ 的信息，但因为 $\small W_q$ 和 $\small W_k$ 的非线形变换，导致相对位置信息被破坏了。&lt;/p&gt;
&lt;h3&gt;相对位置编码&lt;/h3&gt;
&lt;p&gt;$$
\small
A_{i,j}^{\text{rel}}=E_{x_{i}}^{\text{T}}W_q^{\text{T}}\textcolor{green}{W_{k,E}}E_{x_j}+E_{x_{i}}^{\text{T}}W_q^{\text{T}}\textcolor{green}{W_{k,R}}\textcolor{blue}{R_{i-j}}+\textcolor{red}{u^{\text{T}}}\textcolor{green}{W_{k,E}}E_{x_j}+\textcolor{red}{v^{\text{T}}}\textcolor{green}{W_{k,R}}\textcolor{blue}{R_{i-j}}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small R$ 为相对位置编码矩阵、$\small u$ 和 $\small v$ 都是所有层共享的可学习参数。并且由于 $\small R_{i-j}$ 的编码空间与输入空间 $\small E$ 不一定相同，所以将 $\small W_k$ 矩阵替换为了 $\small W_{k,E}$ 和 $\small W_{k,R}$。&lt;/p&gt;
&lt;h3&gt;T5 位置编码&lt;/h3&gt;
&lt;p&gt;如果认为输入信息和位置信息是应该独立/解耦的，那么内容-位置耦合项和位置-内容耦合项应该被移除，并且加上一个可训练的偏置项：&lt;/p&gt;
&lt;p&gt;$$
\small
A_{i,j}^{\text{rel}}=E_{x_{i}}^{\text{T}}W_{q}^{\text{T}}W_{k,E}E_{x_{j}}+r_{i-j}
$$&lt;/p&gt;
&lt;p&gt;其中可学习参数 $r$ 在所有层都是共享的，并且不同的注意力头使用不同的位置编码。&lt;/p&gt;
&lt;h3&gt;ALiBi&lt;/h3&gt;
&lt;p&gt;该方式具有优秀的长度外推能力，其注意力分数计算公式为：&lt;/p&gt;
&lt;p&gt;$$
\small
q_i^{\text{T}}k_j-\lambda(i-j) \quad \lambda=2^{(-8i/k)}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small i-j$ 是 Q/K 之间的位置偏移、$\small \lambda$ 是每个注意力头 $\small k$ 的惩罚系数。位置偏移越大惩罚就越大。&lt;/p&gt;
&lt;h3&gt;RoPE&lt;/h3&gt;
&lt;p&gt;为 Query 和 Key 设置了单独的旋转矩阵 $\small \mathcal{R}$。考虑一个二维的情况：&lt;/p&gt;
&lt;p&gt;$$
\small
\mathcal{R}_mq=
\begin{pmatrix}
\cos m\theta &amp;#x26; -\sin m\theta \
\sin m\theta &amp;#x26; \cos m\theta
\end{pmatrix}
\begin{pmatrix}
q_0 \
q_1
\end{pmatrix} \quad
$$&lt;/p&gt;
&lt;p&gt;由于内积满足线形叠加性，因此任意偶数维的 RoPE，都可以表示为二维形式的拼接：&lt;/p&gt;
&lt;p&gt;$$
\small
{\underbrace{\begin{pmatrix}
\cos m\theta_0 &amp;#x26; -\sin m\theta_0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; \cdots &amp;#x26; 0 &amp;#x26; 0 \
\sin m\theta_0 &amp;#x26; \cos m\theta_0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; \cdots &amp;#x26; 0 &amp;#x26; 0 \
0 &amp;#x26; 0 &amp;#x26; \cos m\theta_1 &amp;#x26; -\sin m\theta_1 &amp;#x26; \cdots &amp;#x26; 0 &amp;#x26; 0 \
0 &amp;#x26; 0 &amp;#x26; \sin m\theta_1 &amp;#x26; \cos m\theta_1 &amp;#x26; \cdots &amp;#x26; 0 &amp;#x26; 0 \
\vdots &amp;#x26; \vdots &amp;#x26; \vdots &amp;#x26; \vdots &amp;#x26; \ddots &amp;#x26; \vdots &amp;#x26; \vdots \
0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; \cdots &amp;#x26; \cos m\theta_{d/2-1} &amp;#x26; -\sin m\theta_{d/2-1} \
0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; 0 &amp;#x26; \cdots &amp;#x26; \sin m\theta_{d/2-1} &amp;#x26; \cos m\theta_{d/2-1} \
\end{pmatrix}}&lt;em&gt;{\mathcal{R}&lt;em&gt;m} \begin{pmatrix}q_0 \ q_1 \ q_2 \ q_3 \ \vdots \ q&lt;/em&gt;{d-2} \ q&lt;/em&gt;{d-1}\end{pmatrix}}
$$&lt;/p&gt;
&lt;p&gt;也就是说，给位置 $\small m$ 的向量 $\small q$ 乘上矩阵 $\small \mathcal{R}_m$、位置 $\small n$ 的向量 $\small k$ 乘上矩阵 $\small \mathcal{R}_n$，并用 &lt;strong&gt;变换后的序列做注意力，那么就自动包含相对位置信息了&lt;/strong&gt;，因为如下恒等式成立：&lt;/p&gt;
&lt;p&gt;$$
\small
(\mathcal{R}_m q)^{\text{T}}(\mathcal{R}_n k) =  q^{\text{T}} \mathcal{R}_m^{\text{T}}\mathcal{R}&lt;em&gt;n k = q^{\text{T}} \mathcal{R}&lt;/em&gt;{n-m} k
$$&lt;/p&gt;
&lt;p&gt;由于 $\small \mathcal{R}_m$ 的稀疏性，直接使用矩阵乘法来计算会很浪费算力。因此使用下述方法来实现 RoPE：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{pmatrix}q_0 \ q_1 \ q_2 \ q_3 \ \vdots \ q_{d-2} \ q_{d-1}
\end{pmatrix}\otimes\begin{pmatrix}\cos m\theta_0 \ \cos m\theta_0 \ \cos m\theta_1 \ \cos m\theta_1 \ \vdots \ \cos m\theta_{d/2-1} \ \cos m\theta_{d/2-1}
\end{pmatrix} + \begin{pmatrix}-q_1 \ q_0 \ -q_3 \ q_2 \ \vdots \ -q_{d-1} \ q_{d-2}
\end{pmatrix}\otimes\begin{pmatrix}\sin m\theta_0 \ \sin m\theta_0 \ \sin m\theta_1 \ \sin m\theta_1 \ \vdots \ \sin m\theta_{d/2-1} \ \sin m\theta_{d/2-1}
\end{pmatrix}
$$&lt;/p&gt;
&lt;p&gt;其中 $\otimes$ 是逐位相乘。在 $\small \theta_i$ 的选择上，沿用了和 Sinusoidal 位置编码的方案，即 $\small \theta_i = 10000^{-2i/d}$。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RoPE 不带有显式的远程衰减，通过不同频率的三角函数有效区分了长程和短程。并且直接作用于 Q/K，不改变注意力计算的形式，与 Flash Attention 更为契合，容易 Scale Up。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;长度外推优化&lt;/h2&gt;
&lt;p&gt;长度外推问题指的是模型在推理阶段无法处理比训练阶段更长的输入的现象(&lt;strong&gt;Train Short, Test Long&lt;/strong&gt;)，从而导致模型无法有效捕捉全局信息。&lt;/p&gt;
&lt;p&gt;注意力机制理论上可以处理任意长序列，但是 &lt;strong&gt;越多的词元去平均注意力就会导致注意力分布越均匀&lt;/strong&gt;，就不能很好地表征词元之间的关系。&lt;/p&gt;
&lt;h3&gt;YaRN&lt;/h3&gt;
&lt;h2&gt;解码策略&lt;/h2&gt;
&lt;h3&gt;各类解码参数&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;长度惩罚(Length Penalty)&lt;/strong&gt; - 将词元概率除以其长度的指数幂 $\small \alpha$，缓解束搜索倾向于生成较短的句子；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;出现惩罚(Presence Penalty)&lt;/strong&gt; - 将输出词元的 logits 减去惩罚项 $\small \alpha$ 来降低该词元之后出现的概率；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;频率惩罚(Frequency Penalty)&lt;/strong&gt; - 在出现惩罚的基础上给乘法项乘上词元的出现次数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;随机采样的改进策略&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;温度采样(Temperature Sampling)&lt;/strong&gt; - 通过调整 logits 的温度系数，从而保证采样过程的随机性，其越小，概率分布越极端，反之越平坦；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-k 采样(Top-k Sampling)&lt;/strong&gt; - 从概率最高的 $\small k$ 个词元中进行采样，但是不考虑整体概率分布，无法适应不同的上下文语境；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-p 采样(Top-p Sampling)&lt;/strong&gt; - 从一个符合特定概率条件的最小词元集合中进行采样，要求其中包含的所有词元的累积概率大于或等于预设阈值 $\small p$。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;投机采样&lt;/h3&gt;
&lt;h2&gt;语言模型&lt;/h2&gt;
&lt;p&gt;预训练模型确立了 &lt;strong&gt;预训练-微调&lt;/strong&gt; 的范式，即通过大量无标注文本建立模型的基础能力，然后通过有标注数据进行下游任务的微调。&lt;/p&gt;
&lt;h3&gt;GPT / Decoder&lt;/h3&gt;
&lt;p&gt;在大规模语料 $\small u={u_1, \ldots, u_n}$ 上进行无监督预训练，根据前 $\small k$ 个词元来预测下一个词元，最大化输出词元的似然：&lt;/p&gt;
&lt;p&gt;$$
\small
L_{u}=\sum\nolimits_{i}\log P(u_i|u_{i-k},\ldots,u_{i-1})
$$&lt;/p&gt;
&lt;p&gt;然后 &lt;strong&gt;取最后一个词元的向量&lt;/strong&gt;，接一个任务专用的线形层，完成各类任务的微调，并加入预训练的目标函数，避免模型遗忘通用知识：&lt;/p&gt;
&lt;p&gt;$$
\small
L_s=\sum\nolimits_{x,y}\log P(y|x_1,\ldots,x_m), \hspace{0.2cm} L_{mtl}=L_s+\lambda L_u
$$&lt;/p&gt;
&lt;p&gt;GPT-2 发现通过海量数据训练出来的模型在不做微调的情况下，通过在 Prompt 里加入自然语言指令，就能完成下游任务，即零样本(Zero-Shot)的学习能力。而 GPT-3 发现在 Prompt 中给定少量示例就能让模型适应新任务(In-Context Learning)，即少样本(Few-Shot)的学习能力。&lt;/p&gt;
&lt;h3&gt;BERT / Encoder&lt;/h3&gt;
&lt;p&gt;自回归架构的 LM 只能单向建模，而 BERT 通过聚合上下文信息形成 &lt;strong&gt;双向建模&lt;/strong&gt;，从而提高下游任务的能力。&lt;/p&gt;
&lt;p&gt;模型的输入嵌入由三个部分构成：词元嵌入、位置嵌入和段嵌入(Segment Embedding)。并且 &lt;strong&gt;每个输入序列的首个标记是 [CLS]，用作当前句子的表征&lt;/strong&gt;。用 [SEP] 标记来分割句子，即 &lt;code&gt;[CLS] A [SEP] B&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;联合优化两个目标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Masked LM(MLM)&lt;/strong&gt; - 随机遮掩输入中 15% 的子词。但是微调的时候不会出现 [MASK]，就会导致训练推理失配问题，可以采用 Scheduled Sampling 解决。即将遮掩词元的 80% 替换为 [MASK]、10% 替换为随机词、10% 保持原词。然后让模型预测遮掩位置的原始词元；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next Sentence Prediction(NSP)&lt;/strong&gt; - 随机从语料库中采样句子对，其中 50% 为相邻句子、50% 为不相邻句子，取 [CLS] 标记的表征输入到分类层中，用来表明输入句子对是否相邻。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后续的改进包括 RoBERTa 去掉了 NSP 任务，引入了 &lt;strong&gt;动态遮码&lt;/strong&gt; 的机制，即每个回合输入句子的 mask 位置都不同，使得模型适应不同的遮码策略，学习不同的表征。还有 ALBERT，将输入嵌入 V x H 转换为两个较小的矩阵 V x E + E x H，从而大幅减少内存消耗和训练速度。&lt;/p&gt;
&lt;h3&gt;T5 / Encoder-Decoder&lt;/h3&gt;
&lt;p&gt;T5 的核心思想是 &lt;strong&gt;将所有的 NLP 任务都统一为 &quot;文本-文本&quot; 的格式&lt;/strong&gt;，并用同一个模型/训练过程/解码方式来完成生成任务。其极大简化了 NLP 的应用流程，研究者们只需关注如何将任务 &quot;表述&quot; 为文本即可。&lt;/p&gt;
&lt;p&gt;该模型通过 Span Corruption 的预训练策略来让模型具备通用的文本理解和生成能力，具体来说：1）从文本语料库(C4)中随机抽取句子；2）随机选取连续的文本片段(Spans)，并用一个特殊的哨兵标记来替换它们；3）模型的目标就是恢复被破坏的文本片段。其与 BERT 中的 MLM 的区别为 MLM 侧重于局部上下文理解，而 &lt;strong&gt;T5 的跨度破坏要求模型不仅要理解上下文，还需要具备生成连贯上下文的能力&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;微调阶段给输入文本加上特定任务的前缀即可，比如说 &quot;summarize: [text]&quot;。这种前缀的形式可以看作是指令微调的雏形，其给该模型带来了优秀的泛化能力。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;BERT 和 T5 这种遮掩/恢复的自监督范式被称为去噪自编码，&quot;去噪&quot; 指的是给干净文本加入 &quot;噪声&quot;，然后训练模型来恢复原始文本，即 &quot;去噪&quot; 的过程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;架构分析&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/ta.png&quot; alt=&quot;Transformer 架构&quot;&gt;&lt;/p&gt;
&lt;h2&gt;视觉模型&lt;/h2&gt;
&lt;h3&gt;ViT&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/huggingface/transformers/blob/v4.53.3/src/transformers/models/vit/modeling_vit.py#L477&quot;&gt;ViT&lt;/a&gt; 是 Google 在 2020 年提出的将 Transformer 架构应用在图像分类的模型，其表明了当训练数据较多的时候(14M-300M images)，ViT 的表现就会超过 CNN 类模型。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/vit.png&quot; alt=&quot;ViT 模型架构&quot;&gt;&lt;/p&gt;
&lt;p&gt;首先将输入图像 $\small[H,W,C]$ 划分成若干 2D 块然后展平得到 $\small[N, (P^2 \times C)]$，其中 N 代表块数、P 代表块大小、C 代表通道数。然后添加一个可学习的类别嵌入块，在编码器输出时可作为图像的特征表示。且为了保留图像的位置信息，引入了可学习的 1D 位置编码，直接叠加在嵌入向量上。&lt;/p&gt;
&lt;p&gt;以 ViT-L/16 为例，将输入图像 (224, 224) 按 (16, 16) 划分为 (224/16)^2=196 块，每个块展平后变成长度为 16x16x3=768 的一维向量，然后将该一维向量通过线性映射转换为长度为 1024 的块向量，最后添加类别嵌入块向量。最终输入向量大小变化为 (196, 768) -&gt; (196, 1024) -&gt; (197, 1024)。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上述向量化过程称为 Patch Embedding，并且线性映射也可以采用二维卷积来做，即将步长、核大小设置为块大小/16，将输出通道设置为嵌入向量大小/1024。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;预训练阶段采用单隐藏层的 MLP 实现，而微调阶段使用单层线性分类器，大小为 $\small D\times K$，其中 $\small K$ 表示下游任务类别数量。但是由于微调阶段采用更高分辨率的图片，输入序列的有效长度变长，导致预训练阶段的位置编码不再匹配，因此使用二维插值调整位置编码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/vit-config.png&quot; alt=&quot;ViT 模型配置&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2106.10270&quot;&gt;How to train your ViT? Data, Augmentation, and Regularization in Vision Transformers&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Swin Transformer&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/huggingface/transformers/blob/v4.53.3/src/transformers/models/swin/modeling_swin.py#L882&quot;&gt;Swin Transformer&lt;/a&gt; 是 Microsoft 在 2021 年提出的用于充当视觉领域的通用骨干网络，其在 Transformer 的基础上引入了 CNN 的归纳偏置：1）局部性 - 只计算窗口和移动窗口内的注意力，同时跨窗口连接，节省计算量；2）层次化 - 通过分层结构，提取不同尺度的特征，应对视觉实体尺度变化问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/ar.png&quot; alt=&quot;Swin Transformer Architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;整个模型架构的流程为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Patch Partition/Linear Embedding - 将图像分割成不重叠的大小为 4x4 的块，个数为 $\small \frac{H}{4} \times \frac{W}{4}$，将每个块的像素值展平得到 48 维的初始特征向量，然后将投影至指定维度 $\small C$，此时输入为 $\small \frac{H}{4}\times \frac{W}{4}\times C$；&lt;/li&gt;
&lt;li&gt;Patch Merging/Swin Transformer Block - 通过 Merge 操作对特征图进行 2 倍的降采样，此时通道维度变为 4 倍，然后通过全连接层调整为 2 倍，逐步形成层次化设计。在进入 W/SW-MSA 之前，首先经过 Window Partition 将特征图划分为多个不重叠的窗口，假设输入特征图大小为 $\small (H, W, C)$，转换后变为 $\small (\frac{H}{ws} \times \frac{W}{ws}, ws^2, C)$，分别表示总窗口数、窗口内块个数、通道纬度。执行 MSA 计算之后输出特征图大小不变。然后经过 Window Reverse 将特征图大小还原为 $\small (H, W, C)$。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由于 W-MSA 只作用在独立窗口内，忽略了窗口之间的联系，因此提出 Shifted Window 划分方法。具体来说，第一个模块采用常规的窗口划分策略，下一个模块在前一个模块的基础上移动 $\small (⌊M/2⌋, ⌊M/2⌋)$ 像素点，$\small M$ 表示窗口大小。下图左侧就是向右/下移动了两个像素之后形成的划分图。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/wp.png&quot; alt=&quot;循环位移&quot;&gt;&lt;/p&gt;
&lt;p&gt;但是该划分方法会导致窗口数量增加以及窗口尺寸不统一，后续进行批处理的时候若通过 Padding 进行填充，则十分低效，因此提出了循环位移(Cyclic Shift)与掩码的方法。具体来说，对原特征图进行左上角的循环位移，再使用掩码机制抑制不相邻块的自注意力计算，从而保持窗口数量和尺寸一致，并确保有效建模。&lt;/p&gt;
&lt;h3&gt;Image GPT&lt;/h3&gt;
&lt;p&gt;Image GPT 是 OpenAI 在 2020 年提出的将 GPT 系列的自回归训练范式运用在图片像素值预测的模型。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./trm.assets/igpt.png&quot; alt=&quot;Image GPT&quot;&gt;&lt;/p&gt;
&lt;p&gt;首先将输入图像进行下采样并将其转换为 1D 序列避免原始图像过大导致的注意力计算爆炸。然后使用预训练+微调的范式，采用两种预训练方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next Pixel Prediction&lt;/strong&gt; - 该方法根据前面的像素值预测下一个像素值(采用光栅顺序)，并最终对图像的概率密度进行整体建模。训练目标是最小化负对数似然：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
\small
L_{\mathrm{AR}}=\mathbb{E}&lt;em&gt;{x\sim X}[-\log p(x&lt;/em&gt;{\pi_i}|x_{\pi_1},x_{\pi_2},\cdots,x_{\pi_{i-1}},\theta)]
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Masked Pixel Prediction&lt;/strong&gt; - 该方法先遮掩输入序列若干位置的值，然后预测遮掩的值。训练目标是最小化遮掩位置元素的负对数似然：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
\small
L_{\mathrm{MASK}}=\mathbb{E}&lt;em&gt;{x\sim X}\mathbb{E}&lt;em&gt;M\sum&lt;/em&gt;{i\in M}[-\log p(x_i|x&lt;/em&gt;{[1,n]\setminus M})]
$$&lt;/p&gt;
&lt;p&gt;预训练阶段模型学到了输入序列的表示，有两种来评估后续任务的方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微调/Fine-tuning - 同时优化 $\small L_{\text{GEN}}+L_{\text{CLF}}$，其中 $\small L_{\text{GEN}}$ 代表 AR 或 MASK 损失、$\small L_{\text{CLF}}$ 代表分类损失。该方法也被称为带有 &lt;strong&gt;辅助训练目标&lt;/strong&gt; 的微调(Fine-tuning with auxiliary training objective)；&lt;/li&gt;
&lt;li&gt;线性探针/Linear Probe - 使用一个线性分类器对冻结参数的模型的内部的某一层特征进行分类的方法。具体来说，对该层特征进行全局平均池化转换为一个特征向量，然后根据该向量来评估下游任务。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spaces.ac.cn/archives/10091&quot;&gt;缓存与效果的极限拉扯 / 科学空间&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://spaces.ac.cn/archives/8265&quot;&gt;Transformer升级之路：2、博采众长的旋转式位置编码 / 科学空间&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/638468472&quot;&gt;从 Flash Attention 到 Paged Attention / 紫气东来&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>循环神经网路</title><link>https://k1tyoo.ink/blog/dl/rnn</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/rnn</guid><description>深度学习 - 笔记 5</description><pubDate>Sat, 11 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;动机&lt;/h2&gt;
&lt;p&gt;循环神经网络(RNN)是用来对 &lt;strong&gt;序列数据&lt;/strong&gt; 建模的模型，若使用 MLP 或 CNN 的话会有如下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MLP 和 CNN 只能接受固定的输入大小，不适用于变长序列，从而无法捕捉长距离/时间依赖性；&lt;/li&gt;
&lt;li&gt;MLP 和 CNN 会因为输入序列过长而导致模型复杂度过高，造成参数爆炸。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;语言模型&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/2-gram.png&quot; alt=&quot;2 元语言模型&quot;&gt;&lt;/p&gt;
&lt;p&gt;语言模型基于 &lt;strong&gt;马尔可夫假设&lt;/strong&gt;，即根据词序列中若干个连续的上下文来预测下一个词出现的概率(基于给定的上下文输出词表上的概率分布，然后采样得到输出词元)。若上下文长度为 2，则用前两个词来预测下一词。&lt;/p&gt;
&lt;p&gt;$$
\small
w_i|w_{i-1},w_{i-2}\sim \hat{p}(w_i|w_{i-1},w_{i-2})
$$&lt;/p&gt;
&lt;p&gt;语言模型使用 &lt;strong&gt;独热编码(One-Hot)&lt;/strong&gt; 来表示 &lt;strong&gt;词表&lt;/strong&gt; 中的每个词，称为 &lt;strong&gt;词向量(Word Embedding)&lt;/strong&gt;。但是当词表增加的时候，单个词向量是高维稀疏的，不利于计算。且词向量之间彼此正交，不利于相似度计算。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;apple:  [1, 0, 0]
banana: [0, 1, 0]
orange: [0, 0, 1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;随着语言模型上下文长度的增加，也会引入参数爆炸的问题，且只具备固定上下文的时间依赖性。那么如何优化该模型呢？我们引入两个归纳偏置：1）局部依赖性假设；2）时间平稳性假设。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/gn.png&quot; alt=&quot;归纳偏置&quot;&gt;&lt;/p&gt;
&lt;h2&gt;循环神经网络&lt;/h2&gt;
&lt;h3&gt;循环单元&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/rl.png&quot; alt=&quot;循环层&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数共享&lt;/strong&gt; 体现在任意时间步 $\small W$、$\small U$、$\small V$ 都是一样的，且对应 MLP 不同的层的权重；而 &lt;strong&gt;局部依赖&lt;/strong&gt; 体现在任意时间步的隐状态只依赖前一时间步的隐状态和当前时间步的输入。&lt;/p&gt;
&lt;p&gt;参数维度分析 - 输入为 $\small x_t \in \mathbb{R}^{n\times d}$、隐状态为 $\small h_t \in \mathbb{R}^{n\times h}$、输出为 $\small y_t \in \mathbb{R}^{n\times q}$、输入权重参数为 $\small U \in \mathbb{R}^{d\times h}$、隐状态权重参数为 $\small W \in \mathbb{R}^{h\times h}$、输出权重参数为 $\small V \in \mathbb{R}^{h\times q}$，其中 $\small n$ 表示批量大小、$\small d$ 表示每个样本的词向量维度、$\small h$ 表示隐状态维度、$\small q$ 表示输出词元的词向量维度，即词表的大小。&lt;/p&gt;
&lt;h3&gt;双向 / 深层循环神经网络&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/br.png&quot; alt=&quot;双向循环神经网络&quot;&gt;&lt;/p&gt;
&lt;p&gt;引入前向/反向的隐状态 $\small h^{1}$ 和 $\small h^{2}$，则对应的计算公式为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
h^1_t &amp;#x26;= g(x_tW_{xh}^1 + h^1_{t-1}W_{hh}^1 + b_h^1) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 前向隐状态计算} \&lt;/p&gt;
&lt;p&gt;h^2_t &amp;#x26;=g(x_tW_{xh}^2 + h^2_{t+1}W_{hh}^2 + b_h^2) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 反向隐状态计算} \&lt;/p&gt;
&lt;p&gt;y_t &amp;#x26;= h_tW_{hq} + b_q, \quad h_t = \text{concat}[h_t^1, h_t^2] &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 当前时间戳输出计算}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;如果隐状态的层数超过两层，就称为深层循环神经网络。其中第 $\small l$ 层的第 $\small t$ 个时刻的隐状态为：&lt;/p&gt;
&lt;p&gt;$$
\small
h_t^{l}=\text{tanh}(W_lh_{t-1}^{l}+U_lh_{t}^{l-1})
$$&lt;/p&gt;
&lt;p&gt;即来自上一层相同时间步的隐状态以及当前层上一个时间步的隐状态的融合。&lt;/p&gt;
&lt;h3&gt;RNN 用于语言模型&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/rlm.png&quot; alt=&quot;使用 RNN 来建模语言模型&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;理论上可以建模长距离依赖，&lt;strong&gt;实际上隐状态信息会随着时间逐渐更新，导致历史信息被遗忘&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;将历史状态的信息压缩到单个固定大小的隐状态中，且权重参数会因为共享机制的存在不会爆炸。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;网络架构&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/arch.png&quot; alt=&quot;循环神经网络架构&quot;&gt;&lt;/p&gt;
&lt;h3&gt;序列到序列模型&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/s2s.png&quot; alt=&quot;序列到序列建模&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编码器-解码器&lt;/strong&gt; 架构的序列到序列(S2S)模型可以看作是 &lt;strong&gt;给定输入序列，去生成输出序列的联合概率分布&lt;/strong&gt;。编码器负责将输入序列压缩成固定长度的上下文向量，解码器负责通过该上下文向量得到输出序列。&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
p(y_1,\cdots,y_{T^{\prime}}|x_1,\cdots,x_T)&amp;#x26;=\prod_{t=1}^{T^{\prime}}p(y_t|c,y_1,\cdots,y_{t-1}) \ &amp;#x26;= \prod_{t=1}^{T^{\prime}}g(y_t|c,s_{t-1},y_{t-1})
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small y_t$ 表示当前时间步输出、$\small y_{t-1}$ 表示前一时间步的输出作为当前时间步的输入、$\small c$ 表示上下文向量、$\small s_{t-1}$ 表示历史信息的隐状态。解码器在每个时间步 $\small t$ 基于上一时间步的隐状态和输出来更新当前隐状态，然后基于当前隐状态生成下一个词元的概率分布。&lt;/p&gt;
&lt;p&gt;该架构的缺点也十分明显：1）将长序列压缩到一个上下文向量会导致信息损失，且在梯度回传的时候会导致梯度消失；2）输入与输出序列可能是偏序关系(翻译任务)，无法使用 RNN 建模；3）传统 S2S 模型中的解码器仅依赖最后一个编码器的隐状态，会造成信息瓶颈。&lt;/p&gt;
&lt;h3&gt;束搜索&lt;/h3&gt;
&lt;p&gt;当我们得到了词表中的概率分布之后如何基于词表上的概率分布进行采样？若沿用贪心采样的策略取概率最大的词元作为输出，并不能保证得到联合概率最大的最优输出序列(输出语句通顺)。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/bs.png&quot; alt=&quot;束搜索&quot;&gt;&lt;/p&gt;
&lt;p&gt;束搜索(Beam Search) 提出在解码的每个时间步都 &lt;strong&gt;维护一个大小为 $\small B$ 的序列集合(称为 &quot;束&quot;)&lt;/strong&gt;，且将 &quot;束&quot; 中的每一个候选序列作为当前输入来预测词表上的概率分布，并取概率最大的 $\small B$ 个词元，因此会产生 $\small B \times B$ 个新序列，计算新序列的 &lt;strong&gt;累积对数分数&lt;/strong&gt; 并选取最高的 $\small B$ 个，然后不断重复直至结束。&lt;/p&gt;
&lt;h2&gt;时间反向传播&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/bptt.png&quot; alt=&quot;时间方向传播&quot;&gt;&lt;/p&gt;
&lt;p&gt;最下方的公式计算任意时刻对 $\small U$ 的偏导数，可以发现只有 $\small h_t$ 对 $\small h_s$ 不是直接依赖关系，需要通过链式法则得到 Jocobian 矩阵的乘积：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial h_t}{\partial h_s}&amp;#x26;=\frac{\partial h_t}{\partial h_{t-1}}\frac{\partial h_{t-1}}{\partial h_{t-2}}\cdots \frac{\partial h_{s+1}}{\partial h_s}\
&amp;#x26;=\prod_{k=s+1}^{t}W^{\text{T}}\text{diag}\left[f^{\prime}(Wh_{k-1})\right]
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;若只考虑相邻时刻，通过柯西不等式得到：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\Vert \frac{\partial h_t}{\partial h_{t-1}}\Vert &amp;#x26;\leq \Vert\overbrace{
\frac{\partial h_t}{\partial h_{t-1}} \frac{\partial h_{t-1}}{\partial h_{t-2}} \cdots \frac{\partial h_{s+1}}{\partial h_s}
}^{\text{长期依赖}}\Vert\
&amp;#x26;\leq \Vert W^{\text{T}}\Vert \Vert \text{diag}\left[f^{\prime}(Wh_{t-1})\right]\Vert \
&amp;#x26;\leq \sigma_{\text{max}}\gamma
\end{aligned}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\small \sigma_{\text{max}}$ 表示权重矩阵 $\small W^{\text{T}}$ 中最大的特征值(特征值分解)；&lt;/li&gt;
&lt;li&gt;$\small \gamma$ 表示 $\small \Vert \text{diag}\left[f^{\prime}(Wh_{t-1})\right]\Vert$ 的上界，依赖于激活函数 $\small f$ 的偏导数的上界，例如 $\small |\text{tanh}^{\prime}(x)| \leq 1$。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若考虑所有时刻，则可以得到：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\Vert\frac{\partial h_t}{\partial h_s} \Vert &amp;#x26;\leq \Vert \prod_{k=s+1}^{t} W^{\text{T}}\text{diag}\left[f^{\prime}(Wh_{k-1})\right]\Vert \
&amp;#x26;\leq (\sigma_{\text{max}}\gamma)^{t-s}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;可以发现当 $\small (t-s)$ 越来越大，整个结果会因为 $\small \sigma_{\text{max}}\gamma$ 大于(小于) 1 从而引发梯度爆炸(消失)问题，原因是 &lt;strong&gt;时间上的参数共享机制(共享参数 $\small W$)会导致连乘的发生&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;一个很自然的解决办法就是将 $\small (t-s)$ 分成均匀的长度，然后在每个长度内进行参数更新，这会带来真实梯度的近似，也就是 &lt;strong&gt;截断时间反向传播(Truncated BPTT)&lt;/strong&gt; 的思想。&lt;/p&gt;
&lt;h2&gt;梯度消失&lt;/h2&gt;
&lt;h3&gt;长短期记忆单元(LSTM)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/lstm.png&quot; alt=&quot;lstm&quot;&gt;&lt;/p&gt;
&lt;p&gt;形式化表示为：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{C}_t= \text{F}&lt;em&gt;t \odot \text{C}&lt;/em&gt;{t-1} + \text{I}_t \odot \tilde{\text{C}}_t \
\text{H}_t= \text{O}_t \odot \text{tanh}(\text{C}_t)
$$&lt;/p&gt;
&lt;p&gt;可以发现遗忘门 $\small \text{F}&lt;em&gt;t$ 控制了前一时刻的记忆单元状态 $\small \text{C}&lt;/em&gt;{t-1}$ 在当前时刻的状态 $\small \text{C}_t$ 中的保留程度，若 $\small \text{F}_t$ 接近 1，则保留大部分信息，梯度也能顺利传播。输入门 $\small \text{I}_t$ 和候选单元 $\small \tilde{\text{C}}_t$ 共同决定了新信息的流入。&lt;/p&gt;
&lt;p&gt;展开记忆单元的计算公式：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\text{C}&lt;em&gt;t&amp;#x26;=\text{F}&lt;em&gt;t\odot \text{C}&lt;/em&gt;{t-1}+ \text{I}&lt;em&gt;t \odot\tilde{\text{C}}&lt;em&gt;t \
&amp;#x26;= \text{F}&lt;em&gt;t\odot \text{F}&lt;/em&gt;{t-1} \odot \text{C}&lt;/em&gt;{t-2} + \text{F}&lt;em&gt;t \odot \text{I}&lt;/em&gt;{t-1} \odot \tilde{\text{C}}&lt;/em&gt;{t-1}+\text{I}&lt;em&gt;t \odot\tilde{\text{C}}&lt;em&gt;t \
&amp;#x26;= \sum&lt;/em&gt;{\tau=0}^{t}(\underbrace{\text{F}&lt;em&gt;t\odot \cdots \odot \text{F}&lt;/em&gt;{\tau+1}}&lt;/em&gt;{\text{遗忘门连续点乘}} )\odot \text{I}&lt;/em&gt;{\tau} \odot \tilde{\text{C}}_{\tau}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;可以发现记忆单元依赖于多个时刻的遗忘门，也是通过该设计来确保该模型能够在长时间序列中保留重要的信息，使得梯度可以在时间步之间流动，避免了梯度消失问题。&lt;/p&gt;
&lt;h3&gt;门控循环单元(GRU)&lt;/h3&gt;
&lt;p&gt;门控循环单元是长短期记忆单元的简化版本，它将遗忘门和输入门整合成了更新门，将输出门替换为重置门。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/gru.png&quot; alt=&quot;gru&quot;&gt;&lt;/p&gt;
&lt;p&gt;形式化表示为：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{H}_t=\text{Z}&lt;em&gt;t\odot \text{H}&lt;/em&gt;{t-1}+(1-\text{Z}_t)\odot\tilde{\text{H}}_t
$$&lt;/p&gt;
&lt;p&gt;重置门用来捕捉序列中的短期依赖关系，更新门用来捕捉序列中的长期依赖关系。在实际效果中，它能保持和长短期记忆单元相似的精度，但是训练和推理速度更快。&lt;/p&gt;
&lt;h2&gt;梯度爆炸&lt;/h2&gt;
&lt;h3&gt;梯度裁剪&lt;/h3&gt;
&lt;p&gt;梯度裁剪(Gradient Clipping) 是用来预防梯度爆炸的，指的是当梯度超过某一个阈值的时候，就对它进行归一化操作，将其拉回一个可控的范围，并保留了参数更新的正确方向，从而保证训练过程的稳定。&lt;/p&gt;
&lt;p&gt;$$
\small
\hat{\bold{g}} \leftarrow \frac{\text{threshold}}{\Vert \bold{g} \Vert_2}\hat{\bold{g}}
$$&lt;/p&gt;
&lt;p&gt;实践中在计算梯度之后进行裁剪：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;...
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;变分丢弃法&lt;/h3&gt;
&lt;p&gt;首先给出应用变分丢弃法的循环神经网络的计算公式：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
h_t &amp;#x26;= \text{tanh}[W\overbrace{(h_{t-1}\odot M_1)}^{\text{使用同一个掩码}} + U(x_t\odot M_2)] &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 隐状态计算} \
y_t &amp;#x26;= V(h_t\odot M_2) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 输出计算}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;如果将传统 Dropout 应用到循环神经网络中会导致如下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;参数共享机制&lt;/strong&gt; - 在每个时间步独立应用 Dropout，会导致隐状态/输入权重不一样，破坏了时序一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;梯度噪声累计&lt;/strong&gt; - 随机的 Dropout 可能在时间维度上引入噪声累计，导致训练不稳定。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/dp.png&quot; alt=&quot;Variational Dropout&quot;&gt;&lt;/p&gt;
&lt;p&gt;变分丢弃法(Variational Dropout) 将循环神经网络中的连接分为两种类型，分别是纵向连接(同一个时间步的连接)和横向/循环连接(跨越时间步的的连接)，并分别使用不同的丢弃法策略。这样无论是纵向还是横向，丢弃的神经元都是相同的，迫使网络学会利用剩下的神经元来存储和传递信息。&lt;/p&gt;
&lt;h3&gt;层归一化&lt;/h3&gt;
&lt;p&gt;层归一化(Layer Normalization) 是沿着单个样本隐状态的特征维度上计算统计量，不依赖批次中的其他样本。假设隐状态大小为 $\small (n, h)$，其中 $\small h$ 就是特征维度。&lt;/p&gt;
&lt;p&gt;$$
\small
\hat{h}_{t}=\frac{h_t-\mu_t}{\sqrt{\sigma_t^2+\epsilon}}\odot \gamma + \beta
$$&lt;/p&gt;
&lt;p&gt;其中 $\small \mu_t$ 和 $\small \sigma_t$ 是时间步 $ \small t$ 的隐状态中特征通道的均值和方差，缩放参数 $\small \gamma$ 和偏移参数 $\small \beta$ 在所有时间步都是共享的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么批归一化不适用于 RNN - 1）RNN 中每个时间步的批次中的样本长度不一致，为每个时间步存储独立的统计量是复杂且低效的；2）RNN 推理阶段只处理单个样本，不存在批次概念，且统计量的计算依赖训练阶段的移动平均。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;训练推理失配&lt;/h2&gt;
&lt;p&gt;RNN 在序列生成任务中存在训练推理失配问题(Training-Inference Shift)，即 &lt;strong&gt;模型在训练时看到的数据分布(以 &quot;正确&quot; 的历史为前提/教师强制)和在推理时看到的数据分布(以 &quot;自己生成的、可能错误&quot; 的历史为前提)之间存在明显的差异&lt;/strong&gt;。若在推理阶段的某一步出错，那么错误会迅速累积，导致生成的序列质量下降。&lt;/p&gt;
&lt;p&gt;解决该问题的方法是利用课程学习(Curriculum Learning)的思想，在模型训练初期依赖真实数据，随着训练的进行，&quot;强迫&quot; 模型更多地依赖自己生成的数据，从 &lt;strong&gt;真实值(简单样本)逐步过渡到预测值(复杂样本)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;基于计划采样(Scheduled Sampling)在每一个时间步基于概率来决定使用真实还是预测的数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在时间步 $\small t$ 以 $\small p$ 的概率选择真实数据 $\small y_{t-1}$；&lt;/li&gt;
&lt;li&gt;在时间步 $\small t$ 以 $\small 1-p$ 的概率选择预测数据 $\small \hat{y}_{t-1}$。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;随着训练的进行，概率 $\small p$ 会逐渐降低，促使模型基于预测数据进行学习，使得模型逐步提升自身的鲁棒性。&lt;/p&gt;
&lt;h2&gt;注意力机制&lt;/h2&gt;
&lt;p&gt;从脑科学的角度出发，注意力功能负责分配认知处理资源以便集中注意力于特定的信息上。深度学习只实现了选择注意力，即 &lt;strong&gt;将注意力根据任务的相关性动态地分配到输入中的不同部分&lt;/strong&gt; 以获得更好的性能。&lt;/p&gt;
&lt;h3&gt;注意力机制 S2S&lt;/h3&gt;
&lt;p&gt;在 S2S 架构中，注意力机制使得解码器(右)在每一个时间步生成词元的时候，都能够看见编码器(左)所有时间步的隐状态，而不仅仅是最后一个。这 &lt;strong&gt;使得解码器能够 &quot;动态关注&quot; 编码器中隐状态中的不同部分，找出对当前输出贡献最大的隐状态&lt;/strong&gt;，并汇聚成上下文向量用来与解码器当前的隐状态结合来生成输出。&lt;/p&gt;
&lt;p&gt;通过训练一个神经网络 $\small \alpha$ 来判断解码器的隐状态 $\small s_t$ 对编码器的隐状态 $\small h_t$ 的关注程度，形式化表示为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
e_{ij}&amp;#x26;=\alpha{(s_{i-1},h_j)} \
&amp;#x26;=v_{\alpha}^{\text{T}}\text{tanh}(W_{\alpha}s_{i-1}+U_{\alpha}h_j)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small e_{ij}$ 表示编码器的第 $\small j$ 个隐状态对解码器的第 $\small i$ 的隐状态的贡献程度。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/attention.png&quot; alt=&quot;注意力机制&quot;&gt;&lt;/p&gt;
&lt;p&gt;使用双向 RNN 作为编码器对输入序列 $\small x$ 进行增强得到隐状态 $\small h$，计算相关性分数 $\small e_{ij}$ 并通过 Softmax 分配得到相关性权重 $\small a$，将其与隐状态加权求和得到上下文向量 $\small c$，然后传入到解码器中进行隐状态 $\small s$ 的计算。&lt;/p&gt;
&lt;p&gt;具体链路为 - &lt;strong&gt;编码器输入 -&gt; 编码器隐状态 -&gt; 网络计算相关性分数 -&gt; 相关性权重 -&gt; 上下文向量 -&gt; 解码器隐状态 -&gt; 解码器输出&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在 Transfomer 模型中通过 qk 内积计算相关性分数，然后经过 softmax 得到相关性权重，最后与 v 进行加权求和得到上下文向量。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Google’s NMT System&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/nmt.png&quot; alt=&quot;nmt&quot;&gt;&lt;/p&gt;
&lt;p&gt;Google 神经机器翻译系统是之前所学知识的集大成者，利用了残差连接、双向循环神经网络(序列到序列模型)、注意力机制、逐层的分布式训练。&lt;/p&gt;
&lt;h2&gt;状态空间的 RNN&lt;/h2&gt;
&lt;p&gt;状态空间模型(State Space Model) 与循环神经网络结合旨在通过线性系统理论建模长期依赖关系，同时保留 RNN 的变长序列处理能力。核心目标是 &lt;strong&gt;通过状态方程描述隐状态的动态变化&lt;/strong&gt;，捕捉序列的全局依赖关系。&lt;/p&gt;
&lt;h3&gt;状态空间模型(SSM)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/ssm.png&quot; alt=&quot;连续状态空间模型&quot;&gt;&lt;/p&gt;
&lt;p&gt;为了适配循环神经网络的离散时间步，需要在 &lt;strong&gt;线形时不变(LTI)&lt;/strong&gt; 的背景下将连续时间系统离散化，来构建深度学习数字模型与物理模型的桥梁。使用 &lt;strong&gt;零阶保持(ZOH)&lt;/strong&gt; 假设来得到一个与原连续系统在所有采样时刻表现完全一致的离散模型。&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\bar{A}&amp;#x26;=\exp(\Delta_tA_t) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 离散状态转移矩阵} \
\bar{B}&amp;#x26;=(\Delta_tA_t)^{-1}(\exp(\Delta_tA_t)-I)\times \Delta_tB_t &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 离散输入矩阵}
\end{aligned}
$$&lt;/p&gt;
&lt;h3&gt;Mamba&lt;/h3&gt;
&lt;p&gt;Mamba 是一种 &lt;strong&gt;动态选择性状态空间模型&lt;/strong&gt;，通过输入相关的状态转移机制解决传统 SSM 的静态参数限制。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./rnn.assets/ma.png&quot; alt=&quot;Mamba&quot;&gt;&lt;/p&gt;
&lt;p&gt;传统 SSM 的参数 $\small A$、$\small B$、$\small C$、$\small \Delta$ 是静态的，而 Mamba 将它们变为输入的函数：&lt;/p&gt;
&lt;p&gt;$$
\small
A_t=\text{Linear}_A(x_t) \quad B_t=\text{Linear}&lt;em&gt;B(x_t) \quad \Delta_t=\text{SoftPlus}(\text{Linear}&lt;/em&gt;\Delta(x_t))
$$&lt;/p&gt;
&lt;p&gt;当 $\small A$ 为对角矩阵的时候，连续方程的离散化简化为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\bar{A}&amp;#x26;=\exp(\Delta_t \text{diag}(A_t)) &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 离散状态转移矩阵} \
\bar{B}&amp;#x26;=\Delta_tB_t\odot \frac{\exp{(\Delta_tA_t)}-1}{\Delta_tA_t} &amp;#x26;&amp;#x26; \quad \leftarrow \text{\footnotesize 离散输入矩阵}
\end{aligned}
$$&lt;/p&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zh.d2l.ai/chapter_recurrent-modern/lstm.html&quot;&gt;LSTM / 动手学深度学习&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zh.d2l.ai/chapter_recurrent-modern/gru.html&quot;&gt;GRU / 动手学深度学习&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>卷积神经网络</title><link>https://k1tyoo.ink/blog/dl/cnn</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/cnn</guid><description>深度学习 - 笔记 3</description><pubDate>Thu, 09 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;动机&lt;/h2&gt;
&lt;p&gt;卷积神经网络源于对生物视觉系统的模拟，即不同的视细胞能够看到的视野不一样，通过叠加视野来形成最终的视觉图像。相较于 MLP 处理图像的高参数量、空间信息损失来说，卷积神经网络在保留空间架构的同时，实现了效率和准确度的协同提升。&lt;/p&gt;
&lt;p&gt;CNN 的归纳偏置主要体现在以下方面：&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;h2&gt;卷积层&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;卷积的数学本质是空间位置滑动的内积。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2D 卷积&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/cnn.png&quot; alt=&quot;卷积&quot;&gt;&lt;/p&gt;
&lt;p&gt;其中 $\small I$ 表示原始图像的局部区域、$\small K$ 表示卷积核，其维度与输入图像一致、$\small d^\prime$ 表示 &lt;strong&gt;输出特征维度/卷积核个数&lt;/strong&gt;。假设输入特征维度为 $\small (w,h,c)$、卷积核维度为 $\small (k,k,c,d^\prime)$，则输出特征维度为 $\small (w-k+1,w-k+1,d^\prime)$，参数量为 $\small d(k^2c+1)$，加 1 表示偏置。&lt;/p&gt;
&lt;p&gt;通过公式可以看出 &lt;strong&gt;卷积神经网络在空间维度上是局部连接的，但是在通道维度上是全连接的&lt;/strong&gt;，即主要提取的是空间信息。&lt;/p&gt;
&lt;h3&gt;感受野&lt;/h3&gt;
&lt;p&gt;感受野(Receptive Field) 指的是 &lt;strong&gt;输出特征图上的一个元素在输入特征图上映射的区域大小&lt;/strong&gt;。随着层数的叠加，感受野也会逐渐变大，直到看完整个输入图像(深层特征中的单个元素会对应原始图像中更大的区域)。&lt;/p&gt;
&lt;h3&gt;填充和步长&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;填充(Padding)&lt;/strong&gt; - 对输入特征图周围采用 0 填充，目的是控制输出特征图空间尺寸以及增加边缘像素的计算次数(避免边界信息丢失)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;步长(Stride)&lt;/strong&gt; - 定义了卷积核在输入特征图上每次移动的像素步数，目的是调节特征图的下采样速度(减少参数量且增加后续神经元的感受野)以及控制特征提取精度。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果加上步长和填充，那么输出特征图空间大小为 $\small (w-k+1) \rightarrow \lfloor (w-k+2p)/s \rfloor + 1$。并且不同的卷积参数会导致不同的输出特征图，比如说边缘检测、锐化、高斯模糊等。&lt;/p&gt;
&lt;h3&gt;FLOPs 计算过程&lt;/h3&gt;
&lt;p&gt;标准卷积层计算公式：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{FLOPs}=k^{2}\times w_{\text{out}}\times h_{\text{out}} \times c \times d
$$&lt;/p&gt;
&lt;p&gt;全连接层计算公式：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{FLOPs}=2\times n\times m
$$&lt;/p&gt;
&lt;p&gt;其中 $\small n$ 和 $\small m$ 表示全连接层中输入/输出特征维度，$\small h_{\text{out}}$ 和 $\small w_{\text{out}}$ 表示输出特征图的空间维度，最后将每层的结果相加就得到最终的 FLOPs。&lt;/p&gt;
&lt;h3&gt;CAM 可视化技术&lt;/h3&gt;
&lt;p&gt;Class Activation Mapping 通过生成热力图，来表明输入图像中与预测类别最相关的区域。其最后一层卷积层 + 全局平均池化层 + MLP 层保证了 &lt;strong&gt;每个通道的特征映射对最终分类的结果都有直接贡献&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/cam.png&quot; alt=&quot;CAM&quot;&gt;&lt;/p&gt;
&lt;p&gt;具体步骤：1）输入图像经过若干 CNN 和最终 GAP 之后，得到每个通道的特征向量，然后进行加权求和，得到与输入图像尺寸相同的 2D 激活图，其中 &lt;strong&gt;每个 MLP 权重值代表其对应的特征向量对每个类别的贡献程度&lt;/strong&gt;；2）将激活图进行上采样和归一化并叠加到原始图像上形成热力图，从而突出模型关注的区域。&lt;/p&gt;
&lt;h2&gt;池化层&lt;/h2&gt;
&lt;h3&gt;最大 / 平均池化&lt;/h3&gt;
&lt;p&gt;池化(Pooling) 操作也是基于窗口扫描，与卷积操作不同的是池化取窗口内的最大值或平均值。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/pool.png&quot; alt=&quot;池化&quot;&gt;&lt;/p&gt;
&lt;p&gt;该操作会减少特征图的空间维度，但不会减少通道维度。并且能够有效减少参数量，但会过度压缩空间信息，因此后续基于 CNN 的模型都很少使用该技术。&lt;/p&gt;
&lt;h3&gt;空间金字塔池化&lt;/h3&gt;
&lt;p&gt;空间金字塔池化(Spatial Pyramid Pooling) 指的是 &lt;strong&gt;对输入特征图在不同尺度进行池化操作&lt;/strong&gt;，然后将这些不同尺度的特征拼接在一起，以捕获多尺度的信息，从而避免 &lt;strong&gt;单一尺度导致的空间信息损失&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/spp.png&quot; alt=&quot;空间金字塔池化&quot;&gt;&lt;/p&gt;
&lt;p&gt;这里需要注意经过池化操作得到的特征向量是在 &lt;strong&gt;通道维度&lt;/strong&gt; 进行拼接。&lt;/p&gt;
&lt;h3&gt;全局平均池化&lt;/h3&gt;
&lt;p&gt;全局平均池化(Global Average Pooling) 将每个特征图的 &lt;strong&gt;空间维度&lt;/strong&gt; 通过平均化压缩为单一的数值，这样就将 &lt;strong&gt;高维的特征转换成了低维的特征向量&lt;/strong&gt;，维度变化为 $\small (w,h,c) \rightarrow (1,1,c)$。&lt;/p&gt;
&lt;ul&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;strong&gt;由低级到高级的特征学习&lt;/strong&gt;。浅层提取到的是图像的低级特征，如边缘、纹理等，而深层提取到的是图像的高级特征，如物体的形状、结构等。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/hrl.png&quot; alt=&quot;分层表示学习&quot;&gt;&lt;/p&gt;
&lt;h2&gt;卷积种类&lt;/h2&gt;
&lt;h3&gt;组卷积&lt;/h3&gt;
&lt;p&gt;组卷积(Group Convolution) 由 AlexNet 提出的，其 &lt;strong&gt;将输入特征沿通道维度分成多个组&lt;/strong&gt;，然后对每个组执行标准卷积操作，最后将结果合并。其有效减少了模型的参数量和计算量，是构建轻量级网络的基础。&lt;/p&gt;
&lt;h3&gt;转置卷积&lt;/h3&gt;
&lt;p&gt;转置卷积(Transpose Convolution) 主要用于 &lt;strong&gt;上采样(Upsampling)&lt;/strong&gt; 操作，即将输入特征图的空间尺寸扩大，这对于需要恢复图像细节或扩大特征的尺寸的任务来说非常重要。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/trans.png&quot; alt=&quot;Transpose Conv&quot;&gt;&lt;/p&gt;
&lt;h3&gt;空洞卷积&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/dc.png&quot; alt=&quot;深度可分离卷积&quot;&gt;&lt;/p&gt;
&lt;p&gt;空洞卷积(Dilated Convolution) 通过引入 Dilation Rate 来控制卷积核处理数据时的采样步长，使得 &lt;strong&gt;同样大小的卷积核能够获得更大的感受野&lt;/strong&gt;，避免过度下采样带来的空间信息损失。当 Dilation Rate 为 1 时，退化为标准卷积。当 Dilation Rate 为 4 时，表示 &lt;strong&gt;在卷积核中间&lt;/strong&gt; 插入三个 0。&lt;/p&gt;
&lt;h3&gt;深度可分离卷积&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/dscn.png&quot; alt=&quot;深度可分离卷积&quot;&gt;&lt;/p&gt;
&lt;p&gt;深度可分离卷积(Depthwise Separable Convolution) 是一种高效的卷积操作，其通过 &lt;strong&gt;分解标准卷积&lt;/strong&gt; 操作来大幅减少参数量。可以看作是分组卷积的一种特殊形式(分组数等于通道数 / 每个组只有一个特征)。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;深度卷积(Depthwise convolution)&lt;/strong&gt; - 使用多组不同的卷积核对输入特征图进行标准卷积操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逐点卷积(Pointwise convolution)&lt;/strong&gt; - 使用 $\small 1\times 1$ 卷积对深度卷积的输出特征图上的每个位置进行卷积。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;标准卷积计算量：&lt;/p&gt;
&lt;p&gt;$$
\small
k\times k \times c \times d \times w_2 \times h_2
$$&lt;/p&gt;
&lt;p&gt;深度可分离卷积计算量：&lt;/p&gt;
&lt;p&gt;$$
\small
k \times k \times d \times w_2 \times h_2 + d\times n \times w_2 \times h_2
$$&lt;/p&gt;
&lt;p&gt;如何理解这个公式呢？深度卷积的通道数为 1，所以上方公式左侧 $\small c=1$；逐点卷积的卷积核大小为 1，所以上方公式右侧 $\small k=1$ 。&lt;/p&gt;
&lt;h3&gt;可变形卷积&lt;/h3&gt;
&lt;p&gt;可变形卷积(Deformable Convolution) 给卷积核在输入特征图上的每个采样点添加一个可学习的 2D 偏移量，从而使得固定的采样网格可以根据输入特征动态地变形，更好地贴合目标的形状和结构。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/vec.png&quot; alt=&quot;MobileNet unit&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;学习偏移量&lt;/strong&gt; - 原始输入特征图经过一个独立并行的标准卷积层之后生成 &quot;偏移量场&quot;，其空间大小与原始输入一致、通道大小为 $\small 2\times k^2$，乘以 2 表示每个采样点需要一个 $\small (x, y)$ 的偏移量；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行可变形采样与卷积&lt;/strong&gt; - 在对每个采样点进行卷积计算的时候，我们先从偏移量场中取出偏移坐标 $\small \Delta p_n$，这样最终输入特征图上的采样坐标就变为 $\small p_n^\prime=p_0 + p_n + \Delta p_n$，其表示一个具体的 $\small (x, y)$ 坐标。但由于是浮点数，无法准确定位，因此采用双线性插值对其进行变形得到最终坐标。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;实用训练技巧&lt;/h2&gt;
&lt;h3&gt;批归一化&lt;/h3&gt;
&lt;p&gt;批归一化(Batch Normalization) 假设 &lt;strong&gt;各个通道表示的特征一样重要&lt;/strong&gt;，并通过 &lt;strong&gt;减均值除方差&lt;/strong&gt; 逐通道引入数据先验。并且为了避免过度归一化破坏网络自身的表达能力而引入两个可学习参数。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/bn.png&quot; alt=&quot;BN&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;训练阶段&lt;/strong&gt; - 使用 &lt;strong&gt;当前小批次&lt;/strong&gt; 的均值和方差对输入特征图进行归一化，并且特征图的每一维都有独立的可学习参数。通过 &lt;strong&gt;指数移动平均(EMA)&lt;/strong&gt; 来计算移动均值和移动方差，以便在推理的时候使用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推理阶段&lt;/strong&gt; - 将单个样本作为一个批次，基于此计算均值和方差会导致模型输出不稳定，因此需要一个 &quot;能代表整个数据集分布的均值和方差&quot;，即移动均值和移动方差。查看 &lt;a href=&quot;https://zh.d2l.ai/chapter_convolutional-modern/batch-norm.html&quot;&gt;动手学深度学习 / 批量规范化&lt;/a&gt; 的代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):
    if not torch.is_grad_enabled():
        # 预测模式下，直接使用移动平均/方差
        X_hat = (X - moving_mean) / torch.sqrt(moving_var + eps)
    else:
        mean = X.mean(dim=(0, 2, 3), keepdim=True)
        var = ((X - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)
        # 训练模式下，用当前批次的均值和方差做标准化
        X_hat = (X - mean) / torch.sqrt(var + eps)
        # 更新移动平均的均值和方差
        moving_mean = momentum * moving_mean + (1.0 - momentum) * mean
        moving_var = momentum * moving_var + (1.0 - momentum) * var
    Y = gamma * X_hat + beta  # 缩放和移位
    return Y, moving_mean.data, moving_var.data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;有效性探讨&lt;/strong&gt; - 批归一化通过对网络进行重参数化，极大平滑了优化景观(Optimization Landscape)，意味着梯度更具可预测性，这允许我们使用更大的学习率，从而实现更快、更稳定的模型训练。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/bnl.png&quot; alt=&quot;bnl&quot;&gt;&lt;/p&gt;
&lt;p&gt;虽然主流 CNN 依赖这一项技术，但是将使用了批归一化的预训练模型适配到新的数据集上的时候，会因为使用了模型中存储的旧的移动均值和移动方差从而导致模型性能下降和训练不稳定，解决办法有两种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当使用大批量的时候，可以解冻批归一化层来动态更新移动均值和移动方差，从而适配新数据的分布；&lt;/li&gt;
&lt;li&gt;当使用小批量的时候，可以使用其他不依赖批量统计的归一化技术，比如实例归一化、组归一化等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/nor.png&quot; alt=&quot;归一化对比&quot;&gt;&lt;/p&gt;
&lt;h3&gt;数据增强&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;复杂数据增强库：https://github.com/albumentations-team/albumentations&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;经典的数据增强技术包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Color Jittering - 对图像的亮度、对比度、饱和度、色相(Hue)进行随机扰动；&lt;/li&gt;
&lt;li&gt;PAC Jittering - 特殊的色彩扰动，能模拟出更自然的光照颜色变化；&lt;/li&gt;
&lt;li&gt;Random Scale / Crop - 将图像随机缩放到不同尺寸，然后随机裁剪出一个固定大小的区域作为输入；&lt;/li&gt;
&lt;li&gt;Horizontal / Vertical Flip - 将图像沿垂直中轴线左右翻转、沿水平中轴线上下翻转；&lt;/li&gt;
&lt;li&gt;Shift / Rotation / Reflection - 将图像进行特定角度的旋转、特定范围的平移等；&lt;/li&gt;
&lt;li&gt;Noise - 在图像的像素值上添加高斯噪声或椒盐噪声，提高模型对输入数据中微小扰动的鲁棒性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;高级的数据增强技术包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mixup&lt;/strong&gt; - 将两个随机选取的训练样本(包括图像和标签)进行线性插值，从而创造出一个全新的合成样本。目的是鼓励模型在不同类别之间学习到更平滑线性的决策边界，并对对抗样本有更好的防御效果；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CutMix&lt;/strong&gt; - 从一张图像中随机裁剪出一个小块并粘贴到另一张图像的随机位置上，且新样本的标签也根据两个图像所占的面积比例进行混合。目的是让模型不仅依赖物体的局部特征，还依赖全局特征；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AutoAugment&lt;/strong&gt; - 将数据增强本身视为一个搜索问题，使用强化学习算法为特定的数据集自动地搜索出一套最优的数据增强策略组合。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;经典卷积架构&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Recipe is all you need：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pytorch.org/vision/stable/index.html&quot;&gt;TorchVision&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rwightman/pytorch-image-models&quot;&gt;Timm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/com.png&quot; alt=&quot;Compare&quot;&gt;&lt;/p&gt;
&lt;h3&gt;AlexNet&lt;/h3&gt;
&lt;p&gt;AlexNet 使用了两个 GPU 同时训练，首次证明了学习到的特征可以超越手工设计的特征，赢得了 2012 年 ImageNet 图像识别挑战赛。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/alexnet.png&quot; alt=&quot;alexnet&quot;&gt;&lt;/p&gt;
&lt;p&gt;ZFNet 在 AlexNet 的基础上进行超参数调优，将 top-5 错误率从 16.4% 降低至 11.7%。&lt;/p&gt;
&lt;h3&gt;VGG&lt;/h3&gt;
&lt;p&gt;VGG 采用了 &lt;strong&gt;连续的 $\small 3\times 3$ 小尺寸卷积核(步长为 1)&lt;/strong&gt; 来减少参数量并达到与大尺寸卷积核相同的有效感受野，其中两个 $\small 3\times 3$ 的有效感受野相当于 $\small 5\times 5$。且通过层叠多个类似的卷积层来增加网络的深度，提升网络的非线性表达能力。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/vgg.png&quot; alt=&quot;VGG&quot;&gt;&lt;/p&gt;
&lt;p&gt;VGG-16 的总参数量为 138M，并且大部分参数量都在末尾的全连接层中，我们可以使用 $\small 1\times 1$ 卷积来替代 FC 层从而减少参数量。&lt;/p&gt;
&lt;h3&gt;Inception Series&lt;/h3&gt;
&lt;p&gt;Inception 系列通过不同大小的卷积核提取不同的空间信息，并在必要的时候进行填充，最后将输出在通道维度上拼接起来。该网络主要由 &lt;strong&gt;Inception 模块&lt;/strong&gt; 组成，后续的版本迭代也是基于基础模块进行设计改良。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/inception.png&quot; alt=&quot;Inception Block&quot;&gt;&lt;/p&gt;
&lt;p&gt;通过引入 $\small 1\times 1$ 卷积操作，该网络相较与 AlexNet 减少了 12 倍的参数量，且 top-5 错误率下降至 6.7%。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$\small 1\times 1$ 卷积操作通道维度，不改变输入特征图的空间尺寸，且通过跨通道信息融合引入更多的非线形性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;ResNet / ResNeXt&lt;/h3&gt;
&lt;p&gt;ResNet 通过引入 &lt;strong&gt;残差连接&lt;/strong&gt; 解决了深度网络训练优化难的问题，该连接通过 &lt;strong&gt;将输入与通过若干层的输出相加&lt;/strong&gt;，从而缓解了梯度消失的问题，使得梯度能够根据该连接传递到浅层网络。并且残差连接使得网络学习输入的恒等映射，从而保留原始特征。该网络主要由 &lt;strong&gt;残差模块&lt;/strong&gt; 组成，即遵循 $\small 1\times 1 \rightarrow 3\times 3 \rightarrow 1\times 1$ 的设计，即降维 -&gt; 提取特征 -&gt; 恢复维度来有效提取特征和降低参数量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/resnet.png&quot; alt=&quot;Inception Block&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResNext&lt;/strong&gt; 在残差模块的基础上添加了多条并行路线 / 扩大宽度，类似 Inception 模块，相较于 ResNet 有更好的 FLOPs / Accuracy 权衡。&lt;/p&gt;
&lt;h3&gt;DenseNet&lt;/h3&gt;
&lt;p&gt;DenseNet 在 ResNet 的基础上进一步提高了特征的重用性，相较于 &quot;残差连接&quot; 的相加，该网络使用 &lt;strong&gt;密集连结&lt;/strong&gt; 来对输出特征图进行扩展，使得每一层都与前面所有层相连接，使得浅层的低级特征能够被每一层利用，并且进一步促进了梯度流动。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/dense.png&quot; alt=&quot;DenseNet&quot;&gt;&lt;/p&gt;
&lt;p&gt;该网络主要由 &lt;strong&gt;Dense 模块&lt;/strong&gt; 和 &lt;strong&gt;Transition 层&lt;/strong&gt; 组成，前者通过增长率定义输出特征图与输入特征图之间通道数的关系，后者通过卷积和池化控制输出特征的通道数量和空间尺寸。&lt;/p&gt;
&lt;h3&gt;ConvNeXt&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2201.03545&quot;&gt;ConvNeXt&lt;/a&gt; 是 Facebook AI Research 在 2022 年提出的，其证明了如果使用与 ViT 相似的现代化训练方法和架构设计原则来 &quot;逐步改造&quot; 一个标准的卷积网络(ResNet)，其性能完全可以与顶尖的 Transformer 模型相媲美，甚至超越它们。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/cn.png&quot; alt=&quot;ConvNext&quot;&gt;&lt;/p&gt;
&lt;h2&gt;模型压缩&lt;/h2&gt;
&lt;h3&gt;参数剪枝&lt;/h3&gt;
&lt;p&gt;剪枝(Pruning) 指的是 &lt;strong&gt;移除对模型性能贡献较少的冗余参数&lt;/strong&gt;，从而在不影响精度的前提下大幅减少参数和计算量。具体来说网络中的 Hessian 矩阵中的很多特征值接近零，表明模型在某些参数方向上存在冗余。&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; - 一个随机初始化的密集网络中存在一个稀疏子网络(&quot;中奖彩票&quot;)，该网络经过独立训练后，可以达到与原始网络相当甚至更好的性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/ticket.png&quot; alt=&quot;彩票假设&quot;&gt;&lt;/p&gt;
&lt;h3&gt;参数量化&lt;/h3&gt;
&lt;p&gt;量化(Quantization) 指的是 &lt;strong&gt;降低每个权重或激活值的比特数&lt;/strong&gt;，标准的深度学习模型通常使用 FP32 来存储参数和中间结果，而量化试图使用 FP16/BF16 或 INT8 来存储。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;(非)线性量化&lt;/strong&gt; - 将浮点数张量通过缩放因子和零点映射到定点整数向量。判断零点是否为 0 分为(非)对称量化，以及对层/通道使用同一套方案分为逐层/通道量化；非线性量化使用非均匀间隔表示权重，例如使用 K-Means 对数值分布中心使用更高精度；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;量化感知训练(QAT)&lt;/strong&gt; - 在训练过程中就 &quot;模拟&quot; 量化操作。前向传播时对权重进行伪量化，但在反向传播时梯度直接传给原始精度的浮点权重，从而让模型在训练阶段适应量化带来的误差；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练后量化(PTQ)&lt;/strong&gt; - 在模型训练完成后直接对权重进行量化。该方法简单快捷，但通常精度损失较大。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;知识蒸馏&lt;/h3&gt;
&lt;p&gt;知识蒸馏(Distillation) 指的是用一个训练好的精确的 &quot;教师网络(Teacher Network)&quot; 来指导一个轻量的 &quot;学生网络(Student Network)&quot; 进行训练，目标是 &lt;strong&gt;让学生网络不仅学习任务的真实标签(Hard Label)，还要学习教师网络输出的 &quot;软标签(Soft Label)&quot;&lt;/strong&gt;，即教师网络在最终层的概率分布。&lt;/p&gt;
&lt;p&gt;蒸馏的损失函数通常是学生(教师)网络输出的 logit 之间的 KL 散度，并引入温度系数使得输出概率分布变得平滑。总损失就是硬标签的交叉熵损失和软标签的蒸馏损失的加权和，推荐 &lt;a href=&quot;https://zhuanlan.zhihu.com/p/102038521&quot;&gt;知识蒸馏经典之作 / 潘小小&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;还有一些不需要教师网络的蒸馏方式，比如说使用网络深层来指导浅层学习的自蒸馏，以及让一组学生网络互相学习的在线蒸馏。&lt;/p&gt;
&lt;h2&gt;轻量级卷积架构&lt;/h2&gt;
&lt;h3&gt;SqueezeNet&lt;/h3&gt;
&lt;p&gt;SqueezeNet 通过 &lt;strong&gt;Fire 模块&lt;/strong&gt; 来大幅减少参数量和模型尺寸，并达到了与 AlexNet 的相似精度。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Squeeze&lt;/strong&gt; - 使用 $\small 1\times 1$ 的卷积核对输入特征图进行通道压缩；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expand&lt;/strong&gt; - 使用 $\small 1\times 1$ 和 $\small 3\times 3$ 的卷积核分别进行特征提取和通道扩展，并在通道维度上拼接结果。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SENet&lt;/h3&gt;
&lt;p&gt;SENet 通过 &lt;strong&gt;通道注意力机制&lt;/strong&gt; 来学习不同通道之间的依赖关系，并根据这些关系动态地增强有用的特征通道，抑制无用的特征通道。基于此设计了一个轻量级、即插即用的 &lt;strong&gt;SE 模块&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Squeeze&lt;/strong&gt; - 对输入特征图的每个通道进行全局平均池化(会丢失大量的空间信息)，用于提取每个通道的全局空间信息，此时特征图大小变为 $\small (h,w,c) \rightarrow (1,1,c)$；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Excitation&lt;/strong&gt; - 将一阶段得到的特征图送入两层 MLP 网络来显式地建模通道间的相关性，并为并为每个通道生成一个权重。其是一个瓶颈结构，特征图维度大小变换为 $\small c \rightarrow c/r \rightarrow c$，其中 $\small r$ 是衰减超参数；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scale&lt;/strong&gt; - 将二阶段得到的权重逐通道地乘以输入特征图的对应通道，以此来动态加强通道信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/seb.png&quot; alt=&quot;通道注意力模块&quot;&gt;&lt;/p&gt;
&lt;h3&gt;ShuffleNet&lt;/h3&gt;
&lt;p&gt;ShuffleNet 通过 &lt;strong&gt;逐点分组卷积&lt;/strong&gt; 和 &lt;strong&gt;通道混洗&lt;/strong&gt; 来建立不同组之间的特征交流，解决分组卷积中每个组的输出只与组内的特征有关而导致的表征问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/v1g.png&quot; alt=&quot;通道洗牌机制&quot;&gt;&lt;/p&gt;
&lt;p&gt;推荐查看 &lt;a href=&quot;https://docs.pytorch.org/docs/stable/generated/torch.nn.ChannelShuffle.html&quot;&gt;ChannelShuffle / Pytorch&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;MobileNet&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;MobileNet v1&lt;/strong&gt; 使用深度可分离卷积代替普通卷积，在准确率轻微下降的情况下极大地减少了模型的参数量和计算量，从而使得模型可以部署在移动端。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MobileNet v2&lt;/strong&gt; 认为网络深层部分的卷积核训练后容易变得稀疏是由于映射到低维空间的特征经过 ReLU 后会造成信息损失。因此我们可以通过取消激活函数并且通过增加输入特征图的通道数来增加信息量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/relu.png&quot; alt=&quot;ReLU 信息损失&quot;&gt;&lt;/p&gt;
&lt;p&gt;主要是引入了 &lt;strong&gt;倒置残差(Inverted residual)&lt;/strong&gt; 结构，其将传统瓶颈层的 &quot;宽-窄-宽&quot; 结构倒置为 &quot;窄-宽-窄&quot; 的结构，即先用一个 $\small 1\times 1$ 结构的逐点卷积增加输入特征图的通道数，然后使用 $\small 3\times 3$ 卷积提取特征信息，最后使用 $\small 1\times 1$ 卷积将特征图的通道数减少为原始个数。&lt;/p&gt;
&lt;h3&gt;轻量化卷积算子汇总&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/sum.png&quot; alt=&quot;轻量化卷积算子&quot;&gt;&lt;/p&gt;
&lt;p&gt;上图描述了各类卷积算子对输入特征在空间维度和通道维度的影响，以及对应的复杂度分析。&lt;/p&gt;
&lt;h2&gt;高级卷积架构&lt;/h2&gt;
&lt;h3&gt;3D 卷积&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/3d.png&quot; alt=&quot;3D 卷积&quot;&gt;&lt;/p&gt;
&lt;h3&gt;EfficientNet&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./cnn.assets/en.png&quot; alt=&quot;EfficientNet&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arthals.ink/blog/cnn&quot;&gt;卷积神经网络 / Arthals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://0809zheng.github.io/tags.html#%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB&quot;&gt;郑之杰的个人网站&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>多层感知机</title><link>https://k1tyoo.ink/blog/dl/mlp</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/mlp</guid><description>深度学习 - 笔记 2</description><pubDate>Wed, 08 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;感知机模型&lt;/h2&gt;
&lt;p&gt;感知机是一个简单的 &lt;strong&gt;两类线形分类模型&lt;/strong&gt;，它是多层感知机的基本单元：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mlp.assets/perceptron.png&quot; alt=&quot;mlp&quot;&gt;&lt;/p&gt;
&lt;p&gt;其中 $\small \text{sgn}$ 表示单位跃迁函数，其根据输入的正负返回 1 或者 0。我们也可以加上偏置 $\small T$，来增加模型的表达能力。其学习算法是一种 &lt;strong&gt;错误驱动&lt;/strong&gt; 的在线学习算法。&lt;/p&gt;
&lt;p&gt;定义训练集为 $\small {(x^{(n)},y^{(n)})}_{n=1}^N\subset\mathbb{R}^d\times{-1,+1}$，初始化权重向量 $\small w\leftarrow 0$。每次模型预测标签和原标签符号相反的时候，即 $\small yw^{\top}x&amp;#x3C;0$，就用这个错误样本来更新权重：&lt;/p&gt;
&lt;p&gt;$$
\small
w\leftarrow w+yx
$$&lt;/p&gt;
&lt;p&gt;根据感知机收敛定理可以知道，如果训练集线形可分，则权重更新的次数不超过 $\small (\frac{R}{\gamma})^{2}$。&lt;/p&gt;
&lt;h2&gt;激活函数&lt;/h2&gt;
&lt;p&gt;激活函数 $\small g(\cdot)$ 对神经元的输出进行 &lt;strong&gt;非线性变换&lt;/strong&gt;，增强网络的表达能力。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个激活函数是 &lt;strong&gt;饱和&lt;/strong&gt; 的指的是 $\small \lim_{|z|\to\infty}|\nabla g(z)|=0$，即梯度趋近于零；&lt;/li&gt;
&lt;li&gt;一个激活函数是 &lt;strong&gt;零中心化&lt;/strong&gt; 的指的是它的输出是在零点附近的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;避免后面混淆，我们需要知道激活函数的输入称为 &quot;净输入&quot;，其输出称为 &quot;激活值&quot;。&lt;/p&gt;
&lt;h2&gt;多层感知机&lt;/h2&gt;
&lt;p&gt;多层感知机(MLP)是一种 &lt;strong&gt;前馈神经网络&lt;/strong&gt;，由 &lt;strong&gt;输入层&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;p&gt;&lt;img src=&quot;./mlp.assets/mlp.png&quot; alt=&quot;mlp&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\small z_i^{(l)}$ 表示第 $\small l$ 层第 $\small i$ 个神经元，等于 $\small (l-1)$ 层的神经元与权重的加权和加上偏置 $\small b_i^{(l-1)}$；&lt;/li&gt;
&lt;li&gt;$\small a_i^{(l-1)}$ 表示第 $\small (l-1)$ 层第 $i$ 个神经元经过激活函数 $\small g(\cdot)$ 激活之后的值；&lt;/li&gt;
&lt;li&gt;$\small \theta_{ij}^{(l)}$ 表示第 $\small l$ 层的第 $\small j$ 个神经元与第 $\small (l+1)$ 层的第 $\small i$ 神经元之间的权重。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;参数学习&lt;/h3&gt;
&lt;p&gt;MLP 的参数学习基于 &lt;strong&gt;反向传播算法&lt;/strong&gt;，其思想是利用链式法则来求每一层参数的偏导数：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;前馈计算每一层的净输入 $\small z^{(l)}$ 和激活值 $\small a^{(l)}$ 直到最后一层；&lt;/li&gt;
&lt;li&gt;反向传播计算每一层的残差项 $\small \delta^{(l)}$，根据残差来计算每一层参数的偏导数。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;首先计算每一层的净输入和激活值：&lt;/p&gt;
&lt;p&gt;$$
\small
z^{(l)}=w^{(l-1)}a^{(l-1)}+b^{(l-1)}, \quad a^{(l)}=g(z^{(l)})
$$&lt;/p&gt;
&lt;p&gt;根据链式法则 $\small \nabla L(\cdot) \rightarrow \nabla a^{(l)} \rightarrow \nabla z^{(l)} \rightarrow \nabla a^{(l-1)}$ 得到误差项的递推公式，从而求出 $\small L$ 对神经元的误差：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\delta^{(l)}&lt;em&gt;{i}&amp;#x26;=\frac{\partial}{\partial z&lt;/em&gt;{i}^{(l)}} L(w,b) \
&amp;#x26;=\sum_{j=1}^{(l+1)}\frac{\partial L(w,b)}{\partial z_{j}^{(l+1)}} \times \frac{\partial z_{j}^{(l+1)}}{\partial a_{i}^{(l)}} \times \frac{\partial a_{i}^{(l)}}{\partial z_{i}^{(l)}} \
&amp;#x26;= \sum_{j=1}^{(l+1)}\delta^{(l+1)}&lt;em&gt;{j} \times \frac{\partial}{\partial a&lt;/em&gt;{i}^{(l)}} \underbrace{\left[\sum_{i=1}^{(l)} w_{ji}^{(l+1)} a_{i}^{(l)}+b_{j}^{(l+1)}\right]}&lt;em&gt;{净输入计算公式} \times g^{\prime}(z&lt;/em&gt;{i}^{(l)}) \
&amp;#x26;= \sum_{j=1}^{(l+1)}\delta_{j}^{(l+1)} w^{(l+1)}&lt;em&gt;{ji} g^{\prime}(z&lt;/em&gt;{i}^{(l)})
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;延续上面的计算方法，我们可以得到损失函数对参数 $w$ 和 $b$ 的偏导数：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial}{\partial w_{ij}^{(l)}}L(w,b)&amp;#x26;=\frac{\partial L(w,b)}{\partial z_i^{(l+1)}}\times \frac{\partial z_i^{(l+1)}}{\partial w_{ij}^{(l)}}=a_j^{(l)}\delta_i^{(l+1)} \ \frac{\partial}{\partial b_i^{(l)}}L(w,b)&amp;#x26;=\frac{\partial L(w,b)}{\partial z_i^{(l+1)}}\times \frac{\partial z_i^{(l+1)}}{\partial b_i^{(l)}}=\delta_i^{(l+1)}
\end{aligned}
$$&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;img src=&quot;./mlp.assets/ad.png&quot; alt=&quot;自动微分&quot;&gt;&lt;/p&gt;
&lt;p&gt;上图描述的是复合函数 $\small f(x;w,b)={1} / ({\exp\left[-(wx+b)\right]+1})$ 的计算图，表示将复合函数拆分成 6 个基本操作 $\small h$，计算完成后按照链式法则计算梯度。&lt;/p&gt;
&lt;h2&gt;Softmax 回归&lt;/h2&gt;
&lt;p&gt;令 $\small z=w^\top x$。给定训练集 $\small D={(x_i,y_i)}_{i=1}^m\in{1,2,\cdots,k}$ 。则第 $\small i$ 个样本属于类别 $\small j$ 的概率为：&lt;/p&gt;
&lt;p&gt;$$
\small
\hat{y} = p(y_i=j | x_i) = \begin{bmatrix}
p(y_{i} = 1 | x_{i}; w) \
p(y_{i} = 2 | x_{i}; w) \
\vdots \
p(y_{i} = k | x_{i}; w)
\end{bmatrix}
= \frac{1}{\sum_{j=1}^{k} \exp(z_j^{(l)})} \begin{bmatrix}
\exp(z_1^{(l)}) \
\exp(z_2^{(l)}) \
\vdots \
\exp(z_k^{(l)})
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;使用 Softmax 的好处是能够 &lt;strong&gt;将离散的连续值转换为和为 1 的概率&lt;/strong&gt;，概率最高的就是输入样本的类别。但是坏处是涉及指数运算，会有数值稳定性问题，需要减去输入中最大的值：&lt;/p&gt;
&lt;p&gt;$$
\small
p(y_i=j|x_i)=\frac{\exp (z_i-z_u)}{\sum_{j=1}^k\exp(z_j-z_u)},\hspace{0.2cm}u=\arg\max(z_j)
$$&lt;/p&gt;
&lt;p&gt;下面通过多伯努利变量的最大似然估计来得出交叉熵损失函数。假设所有样本独立同分布，且样本 $\small i$ 属于类别 $\small j$ 的概率为 $\small p(y_i=j\mid x_i;w)$，那么 $m$ 个样本在所有类别上的联合概率为：&lt;/p&gt;
&lt;p&gt;$$
\small
\prod_{i=1}^m\prod_{j=1}^kP(y_i=j | x_i;w)^{I{y_i=j}}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small I{y_i=j}$ 表示当样本 $\small i$ 的真实类别为 $\small j$ 的时候，返回 1。那么参数 $\small w$ 在训练集 $\small D$ 上的似然函数为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
p(D|w)&amp;#x26;=\prod_{i=1}^m\prod_{j=1}^kp(y_i=j | x_i,w)^{I{y_i=j}} \
-\log p(D|w)&amp;#x26;=-\frac{1}{m}\sum_{i=1}^m\left[\sum_{j=1}^kI{y_i=j}\times\log P(y_i=j|x_i;w)\right] \hspace{0.5cm} \leftarrow \text{\footnotesize 负对数}\
&amp;#x26;=-\frac{1}{m}\sum_{i=1}^m\left[\sum_{j=1}^k   I{y_i=j}\times\log \frac{\exp(z_i^{(l)})}{\sum_{j=1}^{k}\exp {(z_j^{(l)})}}\right]
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;实际上就和多分类交叉熵损失一致了。&lt;/p&gt;
&lt;h2&gt;实用训练技巧&lt;/h2&gt;
&lt;h3&gt;小批量随机梯度下降&lt;/h3&gt;
&lt;p&gt;小批量随机梯度下降算法的改进在于将梯度转换为随机梯度，且梯度的计算是在一个 &lt;strong&gt;小批量随机采样&lt;/strong&gt; 的 $\small m$ 条样本上进行(每个 epoch 对数据集进行 shuffle， 然后按顺序进行无放回采样，引入随机性，且能保证每条样本都能读到)，而不是默认的整个样本集。&lt;/p&gt;
&lt;p&gt;$$
\small
\frac{1}{m}\sum_{i=1}^{m}\frac{\partial}{\partial w^{(l)}&lt;em&gt;{ij}}L(\cdot) \quad \rightarrow \quad \frac{1}{m}\frac{\partial}{\partial w^{(l)}&lt;/em&gt;{ij}}L(\cdot)
$$&lt;/p&gt;
&lt;p&gt;这样做的好处就是能够逃离鞍点且计算效率更高，但它不能很好地逃离局部极值。而 &lt;strong&gt;SGD with Momentum&lt;/strong&gt; 很好的解决了这一点，它在计算的时候考虑了梯度在 &lt;strong&gt;时间上的滑动平均&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
w_{ij}^{(l)}&amp;#x26;=w_{ij}^{(l)} -\eta\Delta\\Delta&amp;#x26;=\beta\Delta+(1-\beta)\frac{\partial}{\partial w_{ij}^{(l)}}L(\cdot)
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;其中 $\beta$ 是冲量参数，一般取 0.9。后续许多算法的改进(RMSProp、Adam)多数都借鉴了冲量的思想。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;迭代(iteration)和回合(epoch)的概念：&lt;/p&gt;
&lt;p&gt;$$
\small
\text{epoch}=\frac{m}{b} \times \text{iteration}
$$&lt;/p&gt;
&lt;p&gt;其中 $\small m$ 表示样本数量、$\small b$ 表示批量大小。一个回合包含多轮迭代，每一次迭代遍历一遍批量。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;梯度消失和爆炸&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;梯度消失&lt;/strong&gt; 指反向传播的时候激活函数的梯度太小，导致网络浅层的权重无法更新。解决办法为使用 ReLU 激活函数、合适的归一化方法、He 初始化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;梯度爆炸&lt;/strong&gt; 指反向传播的时候深层网络梯度非常大，参数更新非常迅速，导致训练不稳定。解决办法为使用梯度裁剪、Adam 优化算法、Xavier 初始化。&lt;/p&gt;
&lt;h3&gt;学习率衰减 / 预热&lt;/h3&gt;
&lt;p&gt;学习率是基于梯度算法中的一个重要超参数，它决定了模型收敛的稳定性和速度。如果太大会导致参数更新过快，从而错过最优解；反之太小会导致参数更新过慢，导致训练时间过长。最好是一开始保持较大的学习率来保证收敛速度，在收敛到接近最优点的时候采用较小的学习率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学习率衰减&lt;/strong&gt; 指的是学习率按照迭代周期 / 回合进行衰减，常用的方法有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;固定步长衰减(StepLR) - 每隔固定回合将学习率乘上衰减系数(0.1)；&lt;/li&gt;
&lt;li&gt;余弦衰减(CosineAnnealingLR) - 学习率按余弦曲线从初始值平滑下降到最小值；&lt;/li&gt;
&lt;li&gt;自适应衰减(ReduceLRonPlateau) - 监控验证集指标，当它不再改善的时候自动降低学习率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;学习率预热&lt;/strong&gt; 指的是在训练初期(总回合的 5% ~ 10%)逐渐增大学习率到设定的基线，目的是避免模型在初始阶段因参数随机初始化后直接使用较大学习率导致的训练不稳定问题。&lt;/p&gt;
&lt;h3&gt;权重衰减&lt;/h3&gt;
&lt;p&gt;权重衰减指的是在进行参数更新的时候引入一个衰减系数 $\small \lambda$，通常为 5e-4：&lt;/p&gt;
&lt;p&gt;$$
\small
w_t \leftarrow(1-\eta\lambda)w_{t-1}-\eta\nabla_tL(w_{t-1})
$$&lt;/p&gt;
&lt;p&gt;在 SGD 当中，权重衰减相当于 $\ell_2$ 正则化。但在 Adam 中，设置衰减系数会造成权重衰减与自适应学习率耦合，导致效果不佳，这时可以使用 AdamW 优化器。&lt;/p&gt;
&lt;h3&gt;丢弃法&lt;/h3&gt;
&lt;p&gt;Dropout 是一种随机正则化方法，其动机是大量神经元的网络参数其实是饱和的，很容易过拟合，所以可以在训练过程中 &lt;strong&gt;随机丢弃一部分神经元(对隐藏层输出置 0)&lt;/strong&gt;，从而减少模型的复杂度。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mlp.assets/dropout.png&quot; alt=&quot;dropout&quot;&gt;&lt;/p&gt;
&lt;p&gt;而在推理的时候不再随机置 0 的原因是确保模型的输出稳定且充分利用训练时学到的所有信息。&lt;/p&gt;
&lt;h2&gt;多层感知机的可表达性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Shallow MLP - 浅层 MLP 只要宽度足够，就能以任意精度逼近 &lt;strong&gt;任意连续函数&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;Role of Depth - 深层网络通过逐层非线性变换，逐步提取 &lt;strong&gt;从低级到高级的特征&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;Role of Width - 提升网络每一层的特征表达能力，允许同时捕捉更多模式，但 &lt;strong&gt;无法捕捉层次信息&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;Linear Regions - 输入空间被划分成多个线性区域。线性区域数量随深度指数增长 / 宽度多项式增长；&lt;/li&gt;
&lt;li&gt;Convex Polytopes - 多层叠加后，网络的决策边界由多个超平面交叠形成的 &lt;strong&gt;凸多面体&lt;/strong&gt; 组合而成。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通用逼近定理表示神经网络的学习能力可以去近似任意一个给定的连续函数，但没有说明如何找到这个函数以及是否是最优的。&lt;/p&gt;
&lt;h2&gt;MLP-Mixer&lt;/h2&gt;
&lt;p&gt;MLP-Mixer 是一种基于 MLPs 的视觉模型，其舍弃了卷积和注意力机制，仅通过 MLP 实现图像特征的高效提取和融合。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mlp.assets/mixer.png&quot; alt=&quot;MLP-Mixer&quot;&gt;&lt;/p&gt;
&lt;p&gt;首先将输入图像 $\small[H,W,C]$ 划分成若干 2D 块然后展平得到 $\small[N, (P^2 \times C)]$，其中 N 代表块数、P 代表块大小、C 代表通道数。然后将每个块经过全连接层投影到维度 $\small C$ 作为 Mixer 层的输入，经过若干层处理后，通过全局平均池化和全连接输出层进行分类。&lt;/p&gt;
&lt;p&gt;Mixer 层由两种 MLP 层组成，分别是 Token-mixing/融合不同块的每个通道的信息 和 Channel-mixing/融合单个块的不同通道信息，且它们的 MLPs 共享参数。&lt;/p&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arthals.ink/blog/neural-network-basics&quot;&gt;神经网络基础 / Arthals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>深度学习简介</title><link>https://k1tyoo.ink/blog/dl/intro</link><guid isPermaLink="true">https://k1tyoo.ink/blog/dl/intro</guid><description>深度学习 - 笔记 1</description><pubDate>Tue, 07 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;两个有用的东西：&lt;a href=&quot;https://github.com/ChristosChristofidis/awesome-deep-learning&quot;&gt;Awesome things&lt;/a&gt; 和 &lt;a href=&quot;http://mlss.cc/&quot;&gt;Machine Learning Summer School&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;会议：1）理论 - COLT；2）方法论 - ICML、NIPS、ICLR；3）应用 - CVPR、ICCV、ACL；&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;机器学习系统&lt;/h2&gt;
&lt;p&gt;深度学习指利用 &lt;strong&gt;多层非线性变化&lt;/strong&gt; 的架构来 &lt;strong&gt;建模数据的高维特征&lt;/strong&gt;；而机器学习指通过 &lt;strong&gt;非显示编程&lt;/strong&gt; 在某些任务 T 上通过经验 E 来提升性能 P，即任务可用 &amp;#x3C;T,P,E&gt; 三元组表示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./intro.assets/system.png&quot; alt=&quot;机器学习系统&quot;&gt;&lt;/p&gt;
&lt;p&gt;机器学习系统可以粗略地分为三个要素：1）&lt;strong&gt;模型&lt;/strong&gt; - 函数集合/假设空间；2）&lt;strong&gt;学习准则&lt;/strong&gt; - 结构/经验风险最小化；3）&lt;strong&gt;优化算法&lt;/strong&gt; - GD/Adam。&lt;/p&gt;
&lt;p&gt;深度学习解决了 &lt;strong&gt;如何找到一个好的假设空间的问题&lt;/strong&gt;，不同的假设空间具有不同的拟合能力和复杂度，用于解决不同的现实问题以及选用不同的学习算法。&lt;/p&gt;
&lt;h3&gt;学习准则&lt;/h3&gt;
&lt;p&gt;$$
\small
\theta^* = \underbrace{\arg \min}&lt;em&gt;{\text{学习准则}} \frac{1}{N}\sum&lt;/em&gt;{n=1}^{N}L(y^{(n)}, \underbrace{f(x^{(n)};\theta)}&lt;em&gt;{\text{假设空间}}) + \underbrace{\lambda\Vert \theta\Vert^{2}}&lt;/em&gt;{\text{正则项}}
$$&lt;/p&gt;
&lt;p&gt;一个好的模型应当拥有较小的期望错误，但由于不知道真实的数据分布和映射函数，因此通过计算经验风险来近似期望错误。加入正则项的目的是减少参数空间，避免过拟合。&lt;/p&gt;
&lt;h1&gt;$$
\small
\theta_{t+1} \leftarrow \theta_t - \eta\nabla_{\theta}L(D;\theta_t), \hspace{0.2cm}
\nabla_{\theta}L(D;\theta_t)&lt;/h1&gt;
&lt;p&gt;\begin{bmatrix}
\displaystyle \frac{\partial}{\partial \theta_1}L(D;\theta_t) \[0.6em]
\displaystyle \frac{\partial}{\partial \theta_2}L(D;\theta_t) \[0.4em]
\vdots
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;采用梯度下降来更新参数，即计算当前参数 $\small \theta_t$ 在训练集 $\small D$ 上的梯度 $\small \eta\nabla_{\theta}L(D;\theta_t)$，然后根据学习率 $\small \eta$ 沿着 &quot;负梯度&quot; 的方向移动，从而降低损失优化参数。&lt;/p&gt;
&lt;h3&gt;泛化误差&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./intro.assets/ge.png&quot; alt=&quot;泛化误差&quot;&gt;&lt;/p&gt;
&lt;p&gt;优化指南：1）使用一个好的假设空间，使得训练误差低；2）使用正则化技术，使得模型复杂度低；3）使用大量的训练数据，使得数据容量大；4）只在需要的时候使用复杂模型。&lt;/p&gt;
&lt;h2&gt;线性回归&lt;/h2&gt;
&lt;p&gt;采用最小二乘法(Least Square Method)进行参数估计，其是一种利用极值来求解参数的方法。首先将偏置 $\small b$ 合并到权重参数 $\small w$ 当中：&lt;/p&gt;
&lt;p&gt;$$
\small
\hat{y}^{(n)}=w^{\top}x^{(n)}
$$&lt;/p&gt;
&lt;p&gt;采用 &lt;strong&gt;均方误差损失函数&lt;/strong&gt;，根据结构风险最小化原则：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
L(D;w)&amp;#x26;=\sum_{n=1}^{N}(y^{(n)}-\hat{y}^{(n)})^{2} + \lambda\Vert w\Vert^{2}
\&amp;#x26;=|Y-X^{\top}w|^2 + \lambda\Vert w\Vert^{2} \hspace{0.5cm} \leftarrow\text{\footnotesize 将样本转换为向量并写成范数}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;损失函数对参数 $\small w$ 求偏导数并置 0 得到最优的参数 $\small w$ 为：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial L}{\partial w}&amp;#x26;=\frac{\partial}{\partial w}[(Y-Xw)^{\top}(Y-Xw)] + \frac{\partial}{\partial w}[\lambda w^{\top}w] \
&amp;#x26;= -2X^{\top}(Y-Xw) + 2\lambda w = 0 \&lt;/p&gt;
&lt;p&gt;\implies (X^{\top}X + \lambda I)w &amp;#x26;= X^{\top}Y \
w &amp;#x26;=(X^{\top}X + \lambda I)^{-1}X^{\top}Y
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;通过该方法得到的参数被称为 &lt;strong&gt;解析解&lt;/strong&gt;。但是当特征维度过高的时候，计算 $\small XX^{\top}$ 的逆会 &lt;strong&gt;非常耗时且不稳定&lt;/strong&gt;，实践中通常使用梯度下降等迭代方法。&lt;/p&gt;
&lt;h2&gt;Logistic 回归&lt;/h2&gt;
&lt;p&gt;为了解决连续线形函数不适合进行分类的问题，引入 &lt;strong&gt;单调可微的非线性函数&lt;/strong&gt; $g: \mathbb{R}^D\to(0,1)$ 来预测标签的后验概率：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\hat{y}^{(n)}&amp;#x26;=\sigma(w^{\top}x) \
&amp;#x26;=\frac{1}{1+\exp(-w^{\top}x)}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;使用 Sigmoid 激活函数，其是单位阶跃函数的连续可微版本。采用 &lt;strong&gt;交叉熵损失函数&lt;/strong&gt;，那么学习准则为：&lt;/p&gt;
&lt;p&gt;$$
\small
\arg\min-\frac{1}{N}\sum_{n=1}^N\left[y^{(n)}\log\hat{y}^{(n)}+(1-y^{(n)})\log(1-\hat{y}^{(n)})\right]
$$&lt;/p&gt;
&lt;p&gt;有两种视角来理解该学习准则：1）采用最大似然的 &lt;strong&gt;概率模型&lt;/strong&gt; - 假设每个样本的标签在给定特征和参数的情况下服从伯努利分布，那么整个数据集的对数似然就等于方括号中的内容；2）采用交叉熵的 &lt;strong&gt;分类模型&lt;/strong&gt; - 交叉熵 &lt;strong&gt;度量了真实标签分布和预测标签分布之间的 &quot;距离&quot;&lt;/strong&gt;，当这个距离越大的时候，对应的 $\small -\log$ 项就会越大，对模型的惩罚就越严重。&lt;/p&gt;
&lt;h3&gt;参数更新&lt;/h3&gt;
&lt;p&gt;有了对应的模型和学习准则，我们就可以根据链式法则来进行参数更新了(忽略了聚合项)，具体过程为：&lt;/p&gt;
&lt;p&gt;$$
\small
\frac{\partial}{\partial w}L(\cdot)=
\frac{\partial}{\partial \hat{y}^{(n)}}L(\cdot) \times \frac{\partial}{\partial z}\hat{y}^{(n)} \times \frac{\partial}{\partial w}z
$$&lt;/p&gt;
&lt;p&gt;首先计算 $\small z$ 对参数 $\small w$ 的偏导数：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial}{\partial w} z&amp;#x26;=\frac{\partial }{\partial w}(w^{\top}x^{(n)}) \
&amp;#x26;=x^{(n)}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;然后计算 $\small \hat{y}^{(n)}$ 函数对 $\small z$ 的偏导数，其中 $\small z=w^{\top}x$。对其进行变形：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{alignedat}{2}
(1+e^{-z})\sigma(z)
&amp;#x26;;=; 1
&amp;#x26;\quad&amp;#x26; \leftarrow\text{\footnotesize 两边分别对 (z) 求导}\
e^{-z}(-1)\sigma(z)+\sigma&apos;(z)(1+e^{-z})
&amp;#x26;;=; 0
&amp;#x26;\quad&amp;#x26; \leftarrow\text{\footnotesize 移位}\
\sigma&apos;(z)(1+e^{-z})
&amp;#x26;;=; e^{-z}\sigma(z)
&amp;#x26;\quad&amp;#x26; \leftarrow\text{\footnotesize 两边同除 (1+e^{-z})}\
\sigma&apos;(z)
&amp;#x26;;=; [1-\sigma(z)]\sigma(z)
&amp;#x26;\quad&amp;#x26;
\end{alignedat}
$$&lt;/p&gt;
&lt;p&gt;最后计算 $\small L(\cdot)$ 对 $\small \hat{y}^{(n)}$ 偏导数：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial}{\partial\hat{y}^{(n)}} L(\cdot)&amp;#x26;=-\frac{y^{(n)}}{\hat{y^{(n)}}}\times \left[1-\frac{1-y^{(n)}}{1-\hat{y}^{(n)}}\right]\times (-1)\&amp;#x26;=-\frac{y^{(n)}}{\hat{y}^{(n)}}+\frac{1-y^{(n)}}{1-\hat{y}^{(n)}}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;将得到的偏导数乘起来：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\frac{\partial}{\partial w}L(\cdot)&amp;#x26;=\frac{\partial}{\partial \hat{y}^{(n)}}L(\cdot) \times \frac{\partial}{\partial z}\hat{y}^{(n)} \times \frac{\partial}{\partial w}z \
&amp;#x26;=\left[-\frac{y^{(n)}}{\hat{y}^{(n)}}+\frac{1-y^{(n)}}{1-\hat{y}^{(n)}}\right]\times\left[(1-\hat{y}^{(n)})\times\hat{y}^{(n)}\right]\times x \
&amp;#x26;=[\hat{y}^{(n)}-y^{(n)}]\times x^{(n)}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;采用梯度下降得到的参数更新过程为：&lt;/p&gt;
&lt;p&gt;$$
\small
w_{t+1}\leftarrow w_t - \eta [ \hat{y}^{(n)} - y ^{(n)}]\times x^{(n)}
$$&lt;/p&gt;
&lt;h2&gt;最大似然估计&lt;/h2&gt;
&lt;p&gt;最大似然估计(MLE)的目标是找到一组参数，使得观测数据 $\small D$ 出现的概率(似然)最大。具体流程为：1）定义概率模型并假设数据服从某个分布；2）构建似然函数，并转换为对数似然函数；3）由于优化问题倾向于求最小值，因此从最大化对数似然 -&gt; 最小化负对数似然。&lt;/p&gt;
&lt;p&gt;假设标签 $\small y$ 由 $\small w^{\top}x$ 加上一个高斯噪声 $\small \epsilon $ 决定：&lt;/p&gt;
&lt;p&gt;$$
\small
y=w^{\top}x+\epsilon
$$&lt;/p&gt;
&lt;p&gt;那么 $\small y$ 就服从均值为 $\small w^{\top}x$、方差为 $\small \sigma^{2}$ 的高斯分布：&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
p(D|w,\sigma^{2})&amp;#x26;=\frac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{(y-w^\top x)^2}{2\sigma^2}) \
p(D|w,\sigma^{2})&amp;#x26;=\prod_{n=1}^N\frac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{(y-w^\top x)^2}{2\sigma^2}) &amp;#x26; \leftarrow &amp;#x26; \hspace{0.1cm} \text{\footnotesize 在训练集 D 上的似然函数} \
-\log p(D|w,\sigma^{2})&amp;#x26;=\frac{1}{2}\log ({2\pi\sigma^{2}})+\frac{1}{2\sigma^{2}}\sum_{n=1}^N (y-w^\top x)^{2} &amp;#x26; \leftarrow &amp;#x26; \hspace{0.1cm} \text{\footnotesize 取负对数}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;第一项不依赖于参数 $\small w$，第二项去除 $\small 1 / \sigma^{2}$ 后就等于均方误差，因此最优参数就由最小化负对数似然得到：&lt;/p&gt;
&lt;p&gt;$$
\small
w^{*}=\arg\min\frac{1}{2}\sum_{n=1}^N(y-w^{\top}x)^2
$$&lt;/p&gt;
&lt;h2&gt;最大后验估计&lt;/h2&gt;
&lt;p&gt;MLE 的缺点是当数据比较少的时候会发生过拟合，估计的参数不准确。因此可以给参数加上 &lt;strong&gt;先验知识&lt;/strong&gt; 以适应小样本的数据集，这一过程相当于在优化目标中添加正则项。&lt;/p&gt;
&lt;p&gt;最大后验估计(MAP)的目标是最大化参数 $\small w$ 的后验概率。即看到了这组数据之后，什么样的参数看起来最可信。根据贝叶斯公式，后验概率正比于 &lt;strong&gt;似然函数与先验概率的乘积&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;$$
\small
\begin{aligned}
\max_{w}p(D|w)p(w)=\max_{w}\left[\log p(D|w)+ \log p(w)\right]
\ w^{*}=\arg\max_w\left[\underbrace {\log p\left({(x^{(n)},y^{(n)})}&lt;em&gt;{n=1}^N\mid w,\sigma^2\right)}&lt;/em&gt;{\log\text{likelihood}}+\underbrace{\log p\left(w\right)}_{\log\mathrm{prior}}\right]
\end{aligned}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\small \log p(D|w)$ 为似然函数，表示在给定参数 $\small w$ 的情况下，数据 $\small D$ 的概率分布；&lt;/li&gt;
&lt;li&gt;$\small \log p(w)$ 为先验概率分布，当选取不同先验的时候，对应的正则化也不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;假设参数遵循高斯分布，即 $\small w\sim N(0,\tau^2I)$，这代表：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型使用 $\small \ell_2$ 正则化，且参数遵循均值为 0， 方差为 $\small \tau^2$ 的多元高斯分布；&lt;/li&gt;
&lt;li&gt;$\small \tau^2I$ 是指协方差矩阵为 $\small \tau^{2}$ 的对角矩阵，即参数 $w$ 的每个维度都是独立同分布的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;代入复杂的数学推导之后，我们可以得到：&lt;/p&gt;
&lt;p&gt;$$
\small
w^{*}=\arg\min\sum_{n=1}^N(y-w^{\top}x)^2+\lambda\Vert w \Vert^2
$$&lt;/p&gt;
&lt;p&gt;这就等价于最大似然估计中求解参数的方法了，区别在于添加了正则项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若先验选择 &lt;strong&gt;高斯分布&lt;/strong&gt;，则代表 $\small \ell_2$ 正则化(2 - 范数 / 岭回归)；&lt;/li&gt;
&lt;li&gt;若先验选择 &lt;strong&gt;拉普拉斯分布&lt;/strong&gt;，则代表 $\small \ell_1$ 正则化(1 - 范数 / 套索回归)，会得到稀疏解。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;机器学习分类&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;ul&gt;
&lt;li&gt;&lt;strong&gt;分类(Classification)&lt;/strong&gt; - 预测输入样本所属的预定义类别，包括二分类、多分类；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回归(Regression)&lt;/strong&gt; - 预测与输入样本相关联的一个或多个连续数值；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;序列标注(Sequence Labeling)&lt;/strong&gt; - 为序列数据中的每一个元素分配一个特定的标签，包括命名实体识别(NER)、词性标注(POS)等，常用的模型为 BiLSTM-CRF, BERT, Transformer；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目标检测(Object Detection)&lt;/strong&gt; - 在图像中使用 BBox 定位一个或多个目标的位置，并识别出其类别，常用的模型为 YOLO、DETR、EfficientDet；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义分割(Semantic Segmentation)&lt;/strong&gt; - 为输入图像中的每一个像素分配一个类别标签，常用的模型为FCN、U-Net、DeepLab；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实例分割(Instance Segmentation)&lt;/strong&gt; - 对输入图像中的每个实例进行轮廓划分，进一步区分同一类别的不同实例，常用的模型为 Mask R-CNN。&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;&lt;strong&gt;K 均值聚类(K-Means)&lt;/strong&gt; - 通过将每个数据点分配给最近的聚类中心/均值来将数据划分为多个不同的簇；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主成分分析(PAC)&lt;/strong&gt; - 找到数据中方差最大的方向(主成分)，将数据投影到这些方向上以实现降维；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成对抗网络(GAN)&lt;/strong&gt; - 让 &quot;伪造者/生成器&quot; 和 &quot;侦探/判别器&quot; 相互博弈，从而学习创造出逼真的数据；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;扩散概率模型(DPM)&lt;/strong&gt; - 通过学习如何逐步地从纯噪声中恢复出清晰的数据，来掌握生成新数据的能力；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于流的生成模型(FGM)&lt;/strong&gt; - 学习一个精确可逆的数学变换，将随机噪声分布 &quot;扭曲&quot; 成真实的数据分布；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;变分自编码器(VAE)&lt;/strong&gt; - 将数据压缩到 &quot;潜在空间&quot; 中，再从这个空间中采样来生成多样化的数据；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对比学习(CL)&lt;/strong&gt; - 通过 &quot;拉近相似的，推开不同的&quot; 方式，让模型在没有标签的情况下学习数据的表示。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;强化学习&lt;/h3&gt;
&lt;p&gt;强化学习的核心思想是让智能体(Agent)在一个复杂的环境(Environment)中不断 &quot;试错&quot; 学习，从而学习一个最优的策略(Policy)，该策略能让智能体采取最优的动作(Action)，从而 &lt;strong&gt;最大化长期累积奖励(Reward)&lt;/strong&gt;。其不依赖 &quot;正确答案&quot; 的数据集，而是在与环境的不断交互中，通过奖励信号自我优化，最终达成目标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./intro.assets/rl.png&quot; alt=&quot;强化学习&quot;&gt;&lt;/p&gt;
&lt;h2&gt;学习理论&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PAC 学习理论 - 在多项式时间内从合理的训练数据学习到一个近似的假设；&lt;/li&gt;
&lt;li&gt;没有免费午餐定理 - 不存在一种机器学习算法适用于所有任务；&lt;/li&gt;
&lt;li&gt;奥卡姆剃刀原理 - 简单的模型泛化能力更好；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;归纳偏置&lt;/strong&gt; - 模型的先验知识。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;损失函数总结&lt;/h2&gt;
&lt;h3&gt;交叉熵&lt;/h3&gt;
&lt;p&gt;熵指的是一个概率分布本身所包含的不确定性的期望，即一个事件的发生概率低，当他真的发生的时候，带来的信息量就越大。&lt;/p&gt;
&lt;p&gt;$$
\small
H(p) = -\sum_{x}p(x)\log p(x)
$$&lt;/p&gt;
&lt;p&gt;相对熵/KL 散度指的是用一个 &quot;猜测&quot; 的概率分布 $\small q$ 来表示 &quot;真实&quot; 的概率分布 $\small q$ 时，所产生的信息损失。&lt;/p&gt;
&lt;p&gt;$$
\small
D_{\text{KL}}=\sum_{x}p(x)\frac{p(x)}{q(x)}
$$&lt;/p&gt;
&lt;p&gt;交叉熵指的是用一个 &quot;猜测&quot; 的概率分布 $\small q$ 去编码 &quot;真实&quot; 的概率分布 $\small p$ 的事件，所需要的平均编码长度。当编码长度越短，代表预测分布与真实分别越接近。&lt;/p&gt;
&lt;p&gt;$$
\small
H(p, q) = -\sum_{x}p(x)\log q(x)
$$&lt;/p&gt;
&lt;p&gt;它们三者之间的关系为 &lt;strong&gt;交叉熵=熵+相对熵&lt;/strong&gt;，指的是预测分布等于真实分布加上二者之间的差异。&lt;/p&gt;
&lt;h3&gt;二分类交叉熵&lt;/h3&gt;
&lt;p&gt;$$
\small
L=-\frac{1}{N}\sum_{n=1}^N\left[y^{(n)}\log(\hat{y}^{(n)})+(1-y^{(n)})\log(1-\hat{y}^{(n)})\right]
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当真实标签 $\small y^{(n)}$ 为独热编码的时候，损失为 $\small -\log(\hat{y}^{(n)})$，鼓励模型提高正类的预测概率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;多分类交叉熵&lt;/h3&gt;
&lt;p&gt;$$
\small
L=-\frac{1}{N}\sum_{n=1}^N\sum_{c=1}^Cy^{(n)}_c\cdot\log(\hat{y}^{(n)}_c)
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\small y^{(n)}$ 表示第 $\small n$ 个样本在类别 $\small c$ 上的真实标签，通常采用独热编码；&lt;/li&gt;
&lt;li&gt;$\small \hat{y}^{(n)}_c$ 表示模型预测第 $\small n$ 个样本属于类别 $\small c$ 的概率，采用 Softmax 函数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Focal Loss&lt;/h3&gt;
&lt;p&gt;Focal Loss 指的是动态地降低大量简单样本在损失函数中的权重，从而让模型能够更 &quot;专注&quot; 于学习那些难以分类的样本。&lt;/p&gt;
&lt;p&gt;$$
\small
L = -(1-p)^{\gamma}\log(p)
$$&lt;/p&gt;
&lt;p&gt;调制因子 $\small (1-p)^\gamma$ 的作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于简单的样本 - 此时 $\small p \rightarrow 1$，那么调制因子就会趋近于 0，从而降低了简单样本对总损失的贡献；&lt;/li&gt;
&lt;li&gt;对于困难的样本 - 此时 $\small p \rightarrow 0$，那么调制因子就会趋近于 1，从而保持了困难样本对总损失的贡献。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arthals.ink/blog/linear-regression-and-classification-problems-in-machine-learning&quot;&gt;机器学习中的线性回归与分类问题 / Arthals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nndl.github.io/&quot;&gt;神经网络与深度学习 / 邱锡鹏&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>从零开始配置 Mac</title><link>https://k1tyoo.ink/blog/initialize/mac</link><guid isPermaLink="true">https://k1tyoo.ink/blog/initialize/mac</guid><description>统一的环境配置指南~</description><pubDate>Mon, 16 Sep 2024 11:25:00 GMT</pubDate><content:encoded>&lt;h2&gt;App&lt;/h2&gt;
&lt;h3&gt;Homebrew&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt; 是一个 macOS 下的包管理器，可以通过它安装许多软件。以下是我安装的软件：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-zsh&quot;&gt;brew install --cask cursor google-chrome notion telegram warp git-credential-manager mos yesplaymusic font-maple-mono iina cherry-studio appcleaner alcove cleanshot discord forklift yaak orbstack prettyclean raycast tw93/tap/mole
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;AppStore&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bobtranslate.com/&quot;&gt;Bob&lt;/a&gt; [付费] - macOS OCR、划词翻译工具。有开源平替 &lt;a href=&quot;https://github.com/tisfeng/Easydict&quot;&gt;EasyDict&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://immersivetranslate.com/&quot;&gt;沉浸式翻译&lt;/a&gt; - 最强的网页翻译工具，也可以配合 OpenAI 等多家服务使用&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/pure-paste/id1611378436?mt=12&quot;&gt;Pure Paste&lt;/a&gt; - 剪贴板格式移除工具。或者也可以使用 ctrl + shift + v 来粘贴&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/us/app/xsearch-for-safari/id1579902068&quot;&gt;xSearch&lt;/a&gt; [付费] - 搜索引擎切换工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://magnet.crowdcafe.com/&quot;&gt;Magnet&lt;/a&gt; [付费] - 窗口排列工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://localsend.org/zh-CN&quot;&gt;LocalSend&lt;/a&gt; - 局域网文件传输工具&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Github&lt;/h3&gt;
&lt;p&gt;先放一份 Star List 在这里：&lt;a href=&quot;https://github.com/stars/k1tyoodev/lists/mac&quot;&gt;K1tyoo / Mac&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Sequel-Ace/Sequel-Ace&quot;&gt;Sequel Ace&lt;/a&gt; - MySQL 管理工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://iina.io/&quot;&gt;IINA&lt;/a&gt; - macOS 视频播放器&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/upscayl/upscayl&quot;&gt;Upscayl&lt;/a&gt; - macOS AI 图片放大工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/CherryHQ/cherry-studio&quot;&gt;Cherry Studio&lt;/a&gt; - 多平台 LLM 客户端&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/superhighfives/pika&quot;&gt;Pika&lt;/a&gt; - macOS 颜色选取工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pakerwreah/Calendr&quot;&gt;Calendr&lt;/a&gt; - macOS 菜单栏日历管理工具&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt; - 最好的 IDE&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cursor.com/&quot;&gt;Cursor&lt;/a&gt; - 基于 VS Code 开源代码的 AI IDE&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://warp.dev/&quot;&gt;Warp&lt;/a&gt; - AI 智能终端&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.raycast.com/&quot;&gt;Raycast&lt;/a&gt; - macOS 快捷启动工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ezip.awehunt.com&quot;&gt;MacZip&lt;/a&gt; - 压缩解压工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.com/intl/zh-CN/chrome/&quot;&gt;Chrome&lt;/a&gt; - 最多人使用的浏览器&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yaak.app/&quot;&gt;Yaak&lt;/a&gt; - 优秀设计的 API 调试工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rightfontapp.com/&quot;&gt;RightFont&lt;/a&gt; [付费] - 优秀设计的字体管理工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://surge.mitsea.com/overview&quot;&gt;Surge&lt;/a&gt; [付费] - macOS 网络调试工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mihomo-party-org/mihomo-party&quot;&gt;Clash Party&lt;/a&gt; - 优秀设计的 Clash 客户端&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailscale.com/&quot;&gt;Tailscale&lt;/a&gt; - 让多个设备处于同一局域网内&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://screen.studio/&quot;&gt;Screen Studio&lt;/a&gt; [付费] - 优秀设计的录屏软件，也可使用免费平替 &lt;a href=&quot;https://www.loom.com/products/mac-screen-recorder&quot;&gt;Loom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://orbstack.dev/&quot;&gt;Orb Stack&lt;/a&gt; - macOS 容器管理工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/qier222/YesPlayMusic&quot;&gt;YesPlayMusic&lt;/a&gt; - 优秀设计的网易云播放器&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cursor&lt;/h2&gt;
&lt;h3&gt;主题 &amp;#x26; 图标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cursor Dark&lt;/li&gt;
&lt;li&gt;Symbols&lt;/li&gt;
&lt;li&gt;Carbon Product Icons&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;其他&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ruff - 基于 Rust 编写的 Python Linter &amp;#x26; Formatter&lt;/li&gt;
&lt;li&gt;Slidev - 幻灯片制作工具&lt;/li&gt;
&lt;li&gt;Error Lens - 代码错误美化&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CLI&lt;/h2&gt;
&lt;p&gt;先放一份 Star List 在这里：&lt;a href=&quot;https://github.com/stars/k1tyoodev/lists/tools&quot;&gt;K1tyoo / Tools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我使用 &lt;a href=&quot;https://www.zsh.org/&quot;&gt;ZSH&lt;/a&gt; 作为默认的 Shell，配合 &lt;a href=&quot;https://ohmyz.sh/&quot;&gt;Oh My ZSH&lt;/a&gt; 来管理配置。 部分 CLI 工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sharkdp/bat&quot;&gt;bat&lt;/a&gt; - 支持语法高亮的 &lt;code&gt;cat&lt;/code&gt; 平替&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sharkdp/fd&quot;&gt;fd&lt;/a&gt; - 简单、快速、友好的 &lt;code&gt;find&lt;/code&gt; 平替&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ajeetdsouza/zoxide&quot;&gt;zoxide&lt;/a&gt; - 目录导航工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aristocratos/btop&quot;&gt;btop&lt;/a&gt; - 资源监控工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tldr-pages/tldr&quot;&gt;tldr&lt;/a&gt; - 命令行工具的使用指南&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tmux/tmux&quot;&gt;tmux&lt;/a&gt; - 终端多窗口管理工具，较 pm2 相比，可以在启动后仍然进行交互操作&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cli/cli#installation&quot;&gt;gh&lt;/a&gt; - GitHub CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Python 包管理器&lt;/h3&gt;
&lt;p&gt;我使用 &lt;a href=&quot;https://docs.astral.sh/uv/&quot;&gt;uv&lt;/a&gt; 来管理 Python 项目，它是一个用 Rust 编写的包与项目管理器。&lt;/p&gt;
&lt;h3&gt;Node 管理器&lt;/h3&gt;
&lt;p&gt;我使用 &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;nvm&lt;/a&gt; 来管理 Node.js 版本环境。将如下命令追加到 &lt;code&gt;~/.zshrc&lt;/code&gt; 进行还源。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-zsh&quot;&gt;export NVM_NODEJS_ORG_MIRROR=http://npm.taobao.org/mirrors/node
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Font&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/subframe7536/maple-font&quot;&gt;Maple Mono&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>