-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
52 lines (24 loc) · 44.4 KB
/
search.xml
File metadata and controls
52 lines (24 loc) · 44.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Transformer和多头注意力机制</title>
<link href="/2024/12/10/Transformer%E5%92%8C%E5%A4%9A%E5%A4%B4%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6/"/>
<url>/2024/12/10/Transformer%E5%92%8C%E5%A4%9A%E5%A4%B4%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6/</url>
<content type="html"><![CDATA[<h1 id="多头自注意力机制与Transformer"><a href="#多头自注意力机制与Transformer" class="headerlink" title="多头自注意力机制与Transformer"></a>多头自注意力机制与Transformer</h1><p>2024.12.06整理</p><h4 id="自注意力机制(计算过程见:https-zhuanlan-zhihu-com-p-338817680-3-2节与3-3节)"><a href="#自注意力机制(计算过程见:https-zhuanlan-zhihu-com-p-338817680-3-2节与3-3节)" class="headerlink" title="自注意力机制(计算过程见:https://zhuanlan.zhihu.com/p/338817680 3.2节与3.3节)"></a>自注意力机制(计算过程见:<a href="https://zhuanlan.zhihu.com/p/338817680" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/338817680</a> 3.2节与3.3节)</h4><p>有$M$个特征(或者单词) (又叫seq_len: 句子长度,即单词数量)</p><p>每个单词用一个$d$维向量表示,记作矩阵<script type="math/tex">X_{M*d}</script>,矩阵有$M$行,<strong>每行对应一个特征/单词</strong>,每行是$d$维。</p><p>Self-Attention 的输入是矩阵$X$,则可以使用线性变换矩阵$W_Q,W_K,W_V$计算得到$Q,K,V$矩阵。</p><p>$W_Q,W_K,W_V$的维度是<script type="math/tex">d*d^{\prime}</script>,得到的$Q,K,V$矩阵的维度是<script type="math/tex">M*d'</script>。 <strong>$X, Q, K, V$的每一行都对应一个单词。</strong></p><p>矩阵乘法:</p><p>$Q=X×W_Q$</p><p>$K=X×W_K$</p><p>$V=X×W_V$</p><p>然后计算$Score(Q,K^T)$,即矩阵相乘$QK^T$,维度是$M*M$,元素$a_{ij}$代表第$i$个单词和第$j$个单词之间的关联程度(attention强度/权重/attention系数/相似性)。</p><p>(为了防止$a_{ij}$过大,所有的$a_{ij}$都要除以$\sqrt{d’}$)</p><p>再对$QK^T$的每一行做$softmax$,使得每行各元素之和都为1.</p><p>得到新的维度为$M*M$的矩阵$softmax(QK^T)$。</p><p>再和矩阵$V$进行元素相乘,得到最终的输出矩阵$Z$,$Z=softmax(QK^T) × V$ </p><p>$Z$的维度是$M*d’$</p><p><strong>矩阵$X,V,Z$的每一行都是对每个单词的向量表示,都有$M$行,因此该过程简单来讲就是$X→V→Z$,</strong></p><p>得到最终的矩阵$Z$,<font color='red'>$Z$的每行是作为对每个单词的新向量表示。</font></p><font color='red'>每个单词的新向量,都是融合了其它单词信息的新向量。而$X$的每行是没有融合其他单词信息的旧向量。</font><p>计算公式写成:</p><p>自注意力机制的输出为矩阵$Z$:</p><script type="math/tex; mode=display">Z=Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d'}})V</script><h4 id="多头自注意力机制"><a href="#多头自注意力机制" class="headerlink" title="多头自注意力机制"></a>多头自注意力机制</h4><p>(一组头:就是一组$Q \ K \ V$矩阵,多头有多组$Q \ K \ V$矩阵,从而得到不同的输出矩阵$Z_i$)</p><p>【不同的头又叫不同的“子空间”,<strong>头=子空间</strong>,可理解为不同的<strong>角度</strong>】</p><p>【如果想从多个角度看,可以用多个头,即换不同的矩阵$W_Q,W_K,W_V$得到不同的$Q,K,V$,然后得到不同的输出矩阵$Z_i$】</p><p>多头自注意力机制<strong>Multi-Head Attention</strong>,是由多个自注意力机制<strong>Self-Attention</strong>组成的。</p><p>Multi-Head Attention 包含多个 Self-Attention 层,</p><p>首先将输入<strong>X</strong>分别传递到 h 个不同的 Self-Attention 中,计算得到 h 个输出矩阵<strong>$Z_i$</strong>。</p><p>比如当 h=8 时,此时会得到 8 个输出矩阵<strong>$Z_i$</strong>。</p><p>得到 8 个输出矩阵$Z_1$~$Z_8$之后,Multi-Head Attention 将它们拼接在一起 <strong>(Concat)</strong>,然后传入一个<strong>Linear</strong>层,得到 Multi-Head Attention 最终的输出<strong>Z</strong>。</p><p>(每个$Z_i$的维度是<script type="math/tex">M*d'</script>,与$X$的维度不同;<strong>而多头自注意力机制的最终输出$Z$的维度是<script type="math/tex">M*d</script>,与$X$的维度相同</strong>。)</p><h4 id="三种注意力机制(Encoder一种,Decoder两种)"><a href="#三种注意力机制(Encoder一种,Decoder两种)" class="headerlink" title="三种注意力机制(Encoder一种,Decoder两种)"></a>三种注意力机制(Encoder一种,Decoder两种)</h4><p>Encoder块的数量,Decoder块的数量:N_e N_d 是超参数,可设置</p><p><img src="https://picx.zhimg.com/70/v2-7be8fe269991a236f000168291481c8b_1440w.image?source=172ae18b&biz_tag=Post" alt="Transformer模型详解(图解最完整版)"></p><p>Encoder一种:每个Encoder块里面有,缩放点积自注意力</p><p>第一个Encoder块的输入:源序列<script type="math/tex">X_{M*d}</script> ,算出当前Encoder块的Q K V,输出是<script type="math/tex">Z_{M*d}</script></p><p>第2~n个Encoder块的输入:上一个Encoder块的输出<script type="math/tex">Z_{M*d}</script>,算出当前Encoder块的Q K V,再输出新的<script type="math/tex">Z_{M*d}</script></p><p>第n个Encoder块的输出:编码信息矩阵C,维度也是<script type="math/tex">C_{M*d}</script></p><p>Decoder两种:每个Decoder块里面有,掩码自注意力机制,交叉注意力机制</p><p>第一个Decoder块的输入:<strong>目标序列<script type="math/tex">X^{goal}_{M*d}</script></strong> 【不是源序列<script type="math/tex">X_{M*d}</script>】和C,输出是<script type="math/tex">Z_{M*d}</script></p><p>第2~n个Decoder块的输入:上一个Decoder块的输出<script type="math/tex">Z_{M*d}</script>和C,再输出新的<script type="math/tex">Z_{M*d}</script></p><p>第n个Decoder块的输出:<script type="math/tex">Z^{final}_{M*d}</script></p><h5 id="后续过程:"><a href="#后续过程:" class="headerlink" title="后续过程:"></a>后续过程:</h5><p>将<script type="math/tex">Z^{final}_{M*d}</script>通过一个线性层(<code>Linear</code>),维度从 <code>[M, d]</code> 变为 <code>[M, vocab_size]</code>。(M个单词,每个单词有vocab_size种可能)</p><p>现在,我们得到了一个矩阵,可以称为 <code>Logits</code>。它的每一行(共M行)对应目标序列中的一个位置,每一行的向量(长度为 <code>vocab_size</code>)代表了在该位置词汇表中所有单词的得分(logits)</p><p>对 <code>Logits</code> 矩阵的<strong>每一行</strong>独立地进行 Softmax 操作,得到 <code>Probs</code>矩阵,维度是<code>[M, vocab_size]</code>,但现在每一行都变成了一个概率分布(该行所有元素之和为1)。</p><p>对于 <code>Probs</code> 矩阵的<strong>每一行</strong>(即目标序列的每一个位置),选择概率值最大的那个元素所在的列索引。</p><p>得到一个包含 M 个索引值的向量,形状为 <code>[M]</code>。每个索引值对应词汇表中的一个单词。</p><p>将这 M 个索引值通过一个<strong>查找表</strong>,映射回词汇表中对应的实际单词。</p><p><strong>最终输出:</strong> 得到一个由 M 个单词组成的序列,这就是模型生成的整个目标句子(例如翻译结果)。</p><p><strong>上面是非自回归的过程!!Decoder在训练时是非自回归</strong>,推理时是自回归。</p><p>推理时:</p><div class="table-container"><table><thead><tr><th style="text-align:left"></th><th style="text-align:left"><strong> Encoder(编码器侧)</strong></th><th><strong>Decoder(解码器侧)</strong></th></tr></thead><tbody><tr><td style="text-align:left"><strong>运行次数</strong></td><td style="text-align:left"><strong>只运行1次</strong></td><td><strong>运行M次</strong>(循环生成目标序列的每一个词)</td></tr><tr><td style="text-align:left"><strong>输入</strong></td><td style="text-align:left">完整的源序列 <code>[M_src, d]</code></td><td>不断增长的目标序列:<code>[1, d]</code> -> <code>[2, d]</code> -> … -> <code>[M, d]</code></td></tr><tr><td style="text-align:left"><strong>输出</strong></td><td style="text-align:left">编码信息 <code>C [M_src, d]</code></td><td>下一个词的概率分布 <code>[vocab_size]</code></td></tr><tr><td style="text-align:left"><strong>工作状态</strong></td><td style="text-align:left"><strong>提前完成,结果被缓存</strong></td><td><strong>循环工作,串行生成</strong></td></tr></tbody></table></div><p>输入Encoder的源序列:可以理解为输入进LLM的prompt。</p><p>输入Decoder的目标序列:</p><ul><li><strong>训练时【非自回归】:</strong> 第一个Decoder块的输入是完整的<strong>目标序列</strong> <code>X_goal [M, d]</code>(并使用掩码确保并行计算时不泄露未来信息)。</li><li><strong>推理时【自回归】:</strong> 第一个Decoder块的输入是起始符 <code>[<sos>]</code>,形状为 <code>[1, d]</code>。<strong>每次生成一个新词,就将其拼接到当前输入序列的末尾</strong>,输入长度从 <code>[1, d]</code> -> <code>[2, d]</code> -> … -> <code>[M, d]</code>,逐步增加,直到生成结束符。</li></ul><div class="table-container"><table><thead><tr><th style="text-align:left">训练时(非自回归)</th><th style="text-align:left">推理时(自回归)</th></tr></thead><tbody><tr><td style="text-align:left">一次处理整个序列 <code>[T, d_model]</code></td><td style="text-align:left">逐步生成,每次只处理到当前序列 <code>[当前长度, d_model]</code></td></tr><tr><td style="text-align:left">线性层输出 <code>[T, vocab_size]</code></td><td style="text-align:left"><strong>每次只取最后一个向量</strong>,维度是 <code>[vocab_size]</code></td></tr><tr><td style="text-align:left">得到T个概率分布,<strong>一次性</strong>选出T个词</td><td style="text-align:left">得到<strong>1个</strong>概率分布,<strong>只选1个</strong>词,然后循环</td></tr></tbody></table></div><p>所以,<strong>Decoder在每一步只生成一个词</strong>。它利用<strong>整个已生成的序列</strong>作为上下文,但只输出<strong>下一个词</strong>的概率分布。</p><div class="table-container"><table><thead><tr><th style="text-align:left">特性</th><th style="text-align:left"><strong>训练 (Training)</strong></th><th style="text-align:left"><strong>推理 (Inference)</strong></th></tr></thead><tbody><tr><td style="text-align:left"><strong>模式</strong></td><td style="text-align:left"><strong>非自回归 (Parallel)</strong></td><td style="text-align:left"><strong>自回归 (Sequential)</strong></td></tr><tr><td style="text-align:left"><strong>输入</strong></td><td style="text-align:left">完整的目标序列(右移一位)</td><td style="text-align:left">模型自己之前生成的结果</td></tr><tr><td style="text-align:left"><strong>输出</strong></td><td style="text-align:left">整个序列的概率分布 <code>[T, vocab_size]</code></td><td style="text-align:left">下一个词的概率分布 <code>[vocab_size]</code>维向量</td></tr><tr><td style="text-align:left"><strong>速度</strong></td><td style="text-align:left"><strong>快</strong>(并行计算)</td><td style="text-align:left"><strong>慢</strong>(串行计算)</td></tr><tr><td style="text-align:left"><strong>关键</strong></td><td style="text-align:left">使用<strong>掩码</strong>和<strong>教师强制</strong></td><td style="text-align:left">使用<strong>自回归</strong>循环生成</td></tr></tbody></table></div><p><strong>掩码自注意力机制 的 输入输出 和 缩放点积自注意力 是一样的</strong>,唯一区别就是在计算得到的Q*K^T上面,加了掩码,(计算softmax之前)。</p><p><strong>交叉自注意力机制:</strong></p><p>当前Decoder块的Q用上一个Decoder块的输出<script type="math/tex">Z_{M*d}</script>计算得到。</p><p>当前Decoder块的K V用C计算得到。</p><h4 id="什么是多头,以及其他网络结构细节"><a href="#什么是多头,以及其他网络结构细节" class="headerlink" title="什么是多头,以及其他网络结构细节"></a>什么是多头,以及其他网络结构细节</h4><p><img src="https://pic2.zhimg.com/v2-f6380627207ff4d1e72addfafeaff0bb_r.jpg" alt="img"></p><h4 id="多头注意力的意思:"><a href="#多头注意力的意思:" class="headerlink" title="多头注意力的意思:"></a>多头注意力的意思:</h4><p>一个head=一个(Q,K,V) </p><p><strong>多头=多个并行的(Q,K,V)</strong></p><h5 id="单头的情况:"><a href="#单头的情况:" class="headerlink" title="单头的情况:"></a>单头的情况:</h5><p>有<script type="math/tex">M</script>个特征(或者单词) (又叫seq_len: 句子长度,即单词数量)</p><p>每个单词用一个$d$维向量表示,记作矩阵<script type="math/tex">X_{M*d}</script>,矩阵有$M$行,<strong>每行对应一个特征/单词</strong>,每行是$d$维。</p><p>Self-Attention 的输入是矩阵$X$,则可以使用线性变换矩阵$W_Q,W_K,W_V$计算得到$Q,K,V$矩阵。</p><p>$W_Q,W_K,W_V$的维度是<script type="math/tex">d*d</script>,得到的$Q,K,V$矩阵的维度是<script type="math/tex">M*d</script>。 <strong>$X, Q, K, V$的每一行都对应一个单词。</strong></p><p>矩阵乘法:</p><script type="math/tex; mode=display">Q=X×W_Q</script><p>$K=X×W_K$</p><p>$V=X×W_V$</p><p>然后计算$Score(Q,K^T)$,即矩阵相乘$QK^T$,维度是$M*M$,元素$a_{ij}$代表第$i$个单词和第$j$个单词之间的关联程度(attention强度/权重/attention系数/相似性)。</p><p>(为了防止$a_{ij}$过大,所有的$a_{ij}$都要除以$\sqrt{d}$)</p><p>再对$QK^T$的每一行做$softmax$,使得每行各元素之和都为1.</p><p>得到新的维度为$M*M$的矩阵$softmax(QK^T)$。</p><p>再和矩阵$V$进行元素相乘,得到最终的输出矩阵$Z$,$Z=softmax(QK^T) × V$ </p><p>$Z$的维度是$M*d$</p><h5 id="多头的情况:【变化:单个注意力机制-→-多头注意力机制】"><a href="#多头的情况:【变化:单个注意力机制-→-多头注意力机制】" class="headerlink" title="多头的情况:【变化:单个注意力机制 → 多头注意力机制】"></a>多头的情况:【变化:单个注意力机制 → 多头注意力机制】</h5><p>将原始的 <code>d</code> 维特征空间分割成 <code>h</code> 个头,这 <code>h</code> 个头可以完全并行地计算自注意力。</p><p>注意:<strong>不是直接对输入矩阵 X 进行划分!!并不是划分输入 <code>X</code>(比如把 <code>(M, d)</code> 的矩阵切成 <code>h</code> 个 <code>(M, d/h)</code> 的矩阵)</strong>。</p><p><strong>而是把完整的X ∈R^[M,d] 都输入到并行的h个头中。</strong></p><p>比如有h个头,是并行的,即h组(Q,K,V):</p><p>对于每一个头 <code>i</code> (i from 1 to h),我们都有其对应的查询(Q)、键(K)、值(V)的线性变换投影矩阵:</p><ul><li><script type="math/tex; mode=display">W_Q^i ∈ ℝ^(d × d_Q)</script></li><li><script type="math/tex; mode=display">W_K^i ∈ ℝ^(d × d_K)</script></li><li><script type="math/tex; mode=display">W_V^i ∈ ℝ^(d × d_V)</script></li></ul><p>对于每个头,我们独立地进行线性投影:</p><ul><li><script type="math/tex; mode=display">Q^i = X · W_Q^i → 维度: (M, d_Q)</script></li><li><script type="math/tex; mode=display">K^i = X · W_K^i → 维度: (M, d_K)</script></li><li><script type="math/tex; mode=display">V^i = X · W_V^i → 维度: (M, d_V)</script></li></ul><p><strong>注意:有<script type="math/tex">d_Q=d_K=d_V=d/h</script></strong></p><p>比如d=512,有h=8个头,则每个头内部的<script type="math/tex">d_Q=d_K=d_V=512/8=64</script></p><p>之后一步步计算,每个头的输出$Z^i$的维度是<script type="math/tex">M*d_V</script></p><p>h个头,得到h个维度为<script type="math/tex">M*d_V</script>的<script type="math/tex">Z^i</script>,接下来:</p><p>①将这 <code>h</code> 个头的输出 <strong>拼接</strong> 起来。(<script type="math/tex">d_V*h=d</script>)</p><p>h个<script type="math/tex">Z^i</script>拼接,得到最终的Z,维度为<script type="math/tex">M*d</script></p><p>②线性投影:</p><p>将拼接后的结果 <code>Z</code> 通过一个<strong>可学习的线性变换</strong> <code>W^O</code></p><ul><li><strong>操作</strong>: <code>Output = Z · W^O</code></li><li><strong>参数矩阵 <code>W^O</code> 的维度</strong>: <code>(h * d_v, d)</code> 也就是 <code>(d, d)</code>(因为 <code>h * d_v = d</code>)。</li><li><strong>输出维度</strong>: <code>(M, d) · (d, d) = (M, d)</code></li></ul><p><strong>这一步的目的是让模型自由地学习和融合来自所有头的信息。</strong></p><p>最终,该多头注意力的输出是<script type="math/tex">MultiHeadOutput_{M*d}</script>,维度和输入<script type="math/tex">X_{M*d}</script>是一样的。</p><p>(<script type="math/tex">MultiHeadOutput_{M*d}</script>就是我上文【三种注意力机制(Encoder一种,Decoder两种)】中的<script type="math/tex">Z_{M*d}</script>)</p><h5 id="注意力后的Feed-Forward层:"><a href="#注意力后的Feed-Forward层:" class="headerlink" title="注意力后的Feed Forward层:"></a>注意力后的Feed Forward层:</h5><p>FFN对注意力层的输出 <code>Z</code>(维度 <code>(M, d)</code>)进行两步操作。</p><p>输出是<script type="math/tex">FFN(Z) = max(0, Z W_1 + b_1) W_2 + b_2</script>。</p><p>FFN(Z) 的维度仍然是 <code>(M, d)</code></p><ul><li><code>W_1</code> 是一个 <code>(d, d_ff)</code> 的矩阵,<code>b_1</code> 是维度 <code>d_ff</code> 的向量。</li><li><code>W_2</code> 是一个 <code>(d_ff, d)</code> 的矩阵,<code>b_2</code> 是维度 <code>d</code> 的向量。</li></ul><p><strong>d_ff > d,即先升维再降维。</strong></p><p><em>ReLU激活函数 (<code>max(0, x)</code>) 提供了至关重要的非线性变换能力。</em></p><p><strong>FFN就是一个“升维 → 非线性激活 → 降维”的处理过程。</strong></p><h5 id="注意力后面的Add-amp-Norm-和Feed-Forward后面的Add-amp-Norm:"><a href="#注意力后面的Add-amp-Norm-和Feed-Forward后面的Add-amp-Norm:" class="headerlink" title="注意力后面的Add & Norm 和Feed Forward后面的Add & Norm:"></a>注意力后面的Add & Norm 和Feed Forward后面的Add & Norm:</h5><p>Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:</p><p><img src="https://pic1.zhimg.com/v2-a4b35db50f882522ee52f61ddd411a5a_1440w.jpg" alt="img"></p><p>其中 <strong>X</strong>表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(<strong>X</strong>) 和 FeedForward(<strong>X</strong>) <strong>表示注意力机制,和FFN的输出 (输出与输入 X 维度是一样的,都是M*d,所以可以相加)。</strong></p><p><strong>Add</strong>指 <strong>X</strong>+MultiHeadAttention(<strong>X</strong>),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到。</p><p><strong>Norm</strong>指 Layer Normalization,通常用于 RNN 结构。</p><h1 id="Transformer其他细节:"><a href="#Transformer其他细节:" class="headerlink" title="Transformer其他细节:"></a>Transformer其他细节:</h1><p>见下面,写的易懂,要多看!</p><p><a href="https://zhuanlan.zhihu.com/p/338817680" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/338817680</a></p><p>补充笔记:</p><p>Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding!</p><p>$PE_{pos,2i},PE_{pos,2i+1}$,这里的$2i,2i+1$是维度索引,即分量,是在计算奇数编号和偶数编号的<strong>分量</strong>的值。</p><h5 id="层归一化(Layer-Normalization)和批归一化(Batch-Normalization,BN)的区别:"><a href="#层归一化(Layer-Normalization)和批归一化(Batch-Normalization,BN)的区别:" class="headerlink" title="层归一化(Layer Normalization)和批归一化(Batch Normalization,BN)的区别:"></a>层归一化(Layer Normalization)和批归一化(Batch Normalization,BN)的区别:</h5><p>假设输入矩阵为$X_{n*d}$,</p><p>n 是批量大小(batch size),代表有n个单词/物品,<strong>一行对应一个</strong>;</p><p>d 是每个单词/物品的特征数量。</p><p>Layer Normalization 的步骤如下:</p><ol><li><p><strong>计算均值</strong>: <strong>对每个样本(行)</strong>计算特征的均值。对于第$i$个样本$\mathbf{x}_i = (x_{i1}, x_{i2}, …, x_{id})$,均值是:</p><script type="math/tex; mode=display">\mu_i = \frac{1}{d} \sum_{j=1}^{d} x_{ij}</script></li><li><p><strong>计算方差</strong>: 对每个样本计算特征的方差:</p><script type="math/tex; mode=display">\sigma_i^2 = \frac{1}{d} \sum_{j=1}^{d} (x_{ij} - \mu_i)^2</script></li><li><p><strong>归一化</strong>: 使用均值和方差对每个特征进行归一化:</p><script type="math/tex; mode=display">\hat{x}_{ij} = \frac{x_{ij} - \mu_i}{\sqrt{\sigma_i^2 + \epsilon}}</script><p>其中 $\epsilon$ 是一个非常小的常数,用于防止除零错误。</p></li><li><p><strong>缩放和平移</strong>: 在归一化后,Layer Normalization 会引入两个可学习的参数 $\gamma$ 和 $\beta$,分别用于缩放和平移。最终输出是:</p><script type="math/tex; mode=display">y_{ij} = \gamma_j \hat{x}_{ij} + \beta_j</script><p>其中 $\gamma_j$ 和 $\beta_j$是为每个特征(每个列)学习到的参数。</p></li></ol><p>总结:</p><p>Layer Normalization 对每个样本的特征进行归一化。</p><p>它不像 Batch Normalization 依赖于批量数$n$,而是<strong>对每个样本单独归一化</strong>,适用于处理序列数据(如RNN、Transformer等),尤其在批量大小较小或单个样本处理时。</p><p>批归一化的步骤:</p><ol><li><p><strong>计算批次均值</strong>: 对整个批次的<strong>每个特征维度(列)</strong>计算均值,即计算<strong>每一列(特征)在批次中所有样本的均值</strong>。对于第$j$个特征维度,它的批次均值是:</p><script type="math/tex; mode=display">\mu_j = \frac{1}{n} \sum_{i=1}^{n} x_{ij}</script><p>其中,$x_{ij}$是第 $i$个样本在第$j$个特征维度上的值。</p></li><li><p><strong>计算批次方差</strong>: 对整个批次的每个特征维度(列)计算方差,即计算每一列(特征)在批次中所有样本的方差。对于第$j$个特征维度,它的批次方差是:</p><script type="math/tex; mode=display">\sigma_j^2 = \frac{1}{n} \sum_{i=1}^{n} (x_{ij} - \mu_j)^2</script><p>这里的$\sigma_j^2$是第$j$个特征维度在批次中的方差。</p></li><li><p><strong>归一化</strong>: 使用计算得到的均值$\mu_j$和方差 $\sigma_j^2$对每个样本的每个特征进行归一化处理。对于第$i$个样本在第$j$个特征维度上的归一化值:</p><script type="math/tex; mode=display">\hat{x}_{ij} = \frac{x_{ij} - \mu_j}{\sqrt{\sigma_j^2 + \epsilon}}</script><p>这里$\epsilon$ 是一个很小的常数,用来防止方差为零时出现除零错误。</p></li><li><p><strong>缩放和平移(可选)</strong>: 批归一化通常会引入两个可学习的参数:$\gamma_j$和$\beta_j$,分别用于缩放和偏移归一化后的值。这样做的目的是让网络有更大的表达能力,因为在训练过程中,经过归一化的输出可以通过这些参数重新调整回原始尺度。</p><script type="math/tex; mode=display">y_{ij} = \gamma_j \hat{x}_{ij} + \beta_j</script><p>其中,$\gamma_j$是缩放因子,$\beta_j$是偏移因子,通常会初始化为1和0。</p></li></ol><p>批归一化通常在卷积神经网络(CNN)和全连接层网络(FCN)中使用。</p><p><strong>层归一化</strong>:是在每个样本的特征维度上进行归一化,每个样本独立归一化。<strong>每行进行归一化、</strong></p><p><strong>批归一化</strong>:是在整个批次上对每个特征维度进行归一化,考虑了批次中的所有样本。<strong>每列进行归一化。</strong></p><p>每个Decoder Block:</p><ul><li>包含两个 Multi-Head Attention 层。</li><li>第一个 Multi-Head Attention 层采用了 Masked 操作:<ul><li>在计算得到$QK^T$,对$QK^T$的每一行做$softmax$之前,</li><li>先使用<strong>Mask</strong>矩阵,将$QK^T$变成<strong>Mask</strong> $QK^T$,</li><li>再对<strong>Mask</strong> $QK^T$的每一行做$softmax$。</li></ul></li><li>第二个 Multi-Head Attention 层的<strong>K, V</strong>矩阵使用 Encoder 的<strong>编码信息矩阵C</strong>进行计算得出,而<strong>Q</strong>使用上一个 Decoder block 的输出计算得出。</li></ul><p>Encoder和Decoder的输入输出:</p><p>Encoder的输入:源文本的单词表示矩阵$X_{n,d}$, 如“我 有 一只 猫”,共4个单词</p><p>Encoder的输出:信息编码矩阵$C_{n,d}$,<strong>与$X$的维度一致</strong>,<script type="math/tex">(n=seq\_len,d=emd\_size)</script></p><p>Decoder的输入:目标文本的单词表示矩阵$X_{n,d}$,如”<Begin> I have a cat”,共5个单词</p><p>(Encoder的输出矩阵$C$会输入到Decoder的第二个$Multi-Head \ Attention$中)</p><p>Decoder的输出:预测的单词序列,如“I have a cat <end>”。</p>]]></content>
</entry>
<entry>
<title>博客搭建记录_20241208</title>
<link href="/2024/12/09/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95-20241208/"/>
<url>/2024/12/09/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95-20241208/</url>
<content type="html"><![CDATA[<p>2024.12.08下午,终于决定建个博客,12.09初步弄好了。</p><h1 id="2024-12-08-博客搭建记录整理"><a href="#2024-12-08-博客搭建记录整理" class="headerlink" title="2024.12.08 博客搭建记录整理"></a>2024.12.08 博客搭建记录整理</h1><p>方案:github pages + hexo</p><h4 id="步骤:"><a href="#步骤:" class="headerlink" title="步骤:"></a>步骤:</h4><p>0.Github上新建<code>用户名.github.io</code>仓库</p><p>1.安装Git,生成SSH,添加到Github的SSH keys</p><p>2.安装node.js和npm</p><p>2.5 修改npm资源获取地址</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm config set registry http://registry.npm.taobao.org</span><br></pre></td></tr></table></figure><p>3.安装hexo</p><p>4.后续步骤见:<a href="https://blog.csdn.net/weixin_44763569/article/details/106435118" target="_blank" rel="noopener">https://blog.csdn.net/weixin_44763569/article/details/106435118</a></p><p>5.主题选择:<a href="https://hexo.io/themes/" target="_blank" rel="noopener">https://hexo.io/themes/</a></p><p>我选的是<code>A-Snail</code>主题,安装教程/【配置】见:<a href="https://github.com/dusign/hexo-theme-snail" target="_blank" rel="noopener">https://github.com/dusign/hexo-theme-snail</a></p><p>6.修改<code>F:\myBlog_241208\blog\_csonfig.yml</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">...</span></span><br><span class="line"><span class="comment"># Extensions</span></span><br><span class="line"><span class="comment">## Plugins: https://hexo.io/plugins/</span></span><br><span class="line"><span class="comment">## Themes: https://hexo.io/themes/</span></span><br><span class="line"><span class="attr">theme:</span> <span class="string">snail</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="comment"># Deployment</span></span><br><span class="line"><span class="comment">## Docs: https://hexo.io/docs/deployment.html</span></span><br><span class="line"><span class="attr">deploy:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line"> <span class="attr">repo:</span> <span class="string">git@github.com:Dowerinne/Dowerinne.github.io.git</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">main</span></span><br></pre></td></tr></table></figure><p>7.<code>npm install hexo-deployer-git --save</code></p><p>8.<code>npm install hexo-util@1.9.1</code> 【重要,必须指定成这个版本,防报错】</p><p>9.修改引擎bug,修改文件<code>/node_modules\kramed\lib\rules\inline.js</code>中<code>escape</code>和<code>em</code>两行,具体修改如下,源自<a href="https://www.jianshu.com/p/9b9c241146bc" target="_blank" rel="noopener">https://www.jianshu.com/p/9b9c241146bc</a></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,</span><br><span class="line"> escape: /^\\([`*\[\]()#$+\-.!_>])/,</span><br><span class="line"> </span><br><span class="line">// em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,</span><br><span class="line"> em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,</span><br></pre></td></tr></table></figure><p>我的本地文件夹:<code>F:\myBlog_241208\blog</code>,在该目录下打开<code>cmd 或 Git Bash</code>输入命令。</p><h4 id="A-Snail主题安装与配置"><a href="#A-Snail主题安装与配置" class="headerlink" title="A-Snail主题安装与配置"></a><code>A-Snail</code>主题安装与配置</h4><p><a href="https://github.com/dusign/hexo-theme-snail" target="_blank" rel="noopener">https://github.com/dusign/hexo-theme-snail</a></p><p>安装:见Quick Start一节,先后安装了Theme,Mathjax,WordCount</p><p>配置:见Configuration一节【重要】,是修改<code>F:\myBlog_241208\blog\_config.yml</code>。 <font color='red'>未完待续,继续弄</font></p><h4 id="配置记录:"><a href="#配置记录:" class="headerlink" title="配置记录:"></a>配置记录:</h4><h5 id="1-修改header-img:图片放入img-文件夹中。"><a href="#1-修改header-img:图片放入img-文件夹中。" class="headerlink" title="1.修改header_img:图片放入img/文件夹中。"></a>1.修改header_img:图片放入<code>img/</code>文件夹中。</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># Site settings</span><br><span class="line">SEOTitle: Dowerinne's blog</span><br><span class="line">email: </span><br><span class="line">description: "A hexo theme"</span><br><span class="line">keyword: "hexo-theme-snail"</span><br><span class="line">header-img: img/header_img/sunset.jpg</span><br><span class="line">signature: false #show signature</span><br><span class="line">signature-img: img/signature/dusign.png</span><br></pre></td></tr></table></figure><p>注意这里的<code>img/</code>文件夹是<code>F:\myBlog_241208\blog\source\img</code>,并不是<code>F:\myBlog_241208\blog\img</code>!!</p><h5 id="2-每篇文章的header-img:"><a href="#2-每篇文章的header-img:" class="headerlink" title="2.每篇文章的header_img:"></a>2.每篇文章的header_img:</h5><p>图片是放在<code>F:\myBlog_241208\blog\source\img</code>文件夹中!</p><p>修改每个md文件最上方的<code>header-img: ../../../../img/default.jpg</code>,把default.jpg换成目标图片即可。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">路径解释:../../../../img/wallpaper_01.jpg</span><br><span class="line">并不是从md当前的位置出发 F:\myBlog_241208\blog\source\_posts,</span><br><span class="line">而是从这个位置出发:F:\myBlog_241208\blog\public\2024\12\09\博客搭建记录-20241208</span><br><span class="line"></span><br><span class="line">其他md以此类推。</span><br></pre></td></tr></table></figure><p>但是修改的时候,图片还是要放在<code>F:\myBlog_241208\blog\source\img</code>文件夹中,</p><p>而不是放到<code>F:\myBlog_241208\blog\public\img</code>里面。</p><h5 id="3-LaTeX-MarkDown数学公式相关:"><a href="#3-LaTeX-MarkDown数学公式相关:" class="headerlink" title="3.LaTeX/MarkDown数学公式相关:"></a>3.LaTeX/MarkDown数学公式相关:</h5><p>①如果md文档里有数学公式需要渲染,文档最上面加上<code>mathjax: true</code>,例如:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">title: Transformer和多头注意力机制</span><br><span class="line">......</span><br><span class="line">date: 2024-12-10 23:16:05</span><br><span class="line">mathjax: true</span><br><span class="line">......</span><br></pre></td></tr></table></figure><p>②所有的公式都要用两层<code>$</code>套起来,</p><p>而不是只有一层<code>$</code></p><p>因为如果一层$里面有星号*,而同一行又有加粗字体<code>**...**</code>,页面上渲染会有问题!!</p><p>或者是直接插入公式块。</p><p>③尖括号的渲染问题:如果想在文档中显示尖括号,即< 和 >,写成<code>&lt;</code>和<code>&gt;</code></p><h5 id="4-检查node-js,npm,hexo是否安装成功:"><a href="#4-检查node-js,npm,hexo是否安装成功:" class="headerlink" title="4.检查node.js,npm,hexo是否安装成功:"></a>4.检查node.js,npm,hexo是否安装成功:</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">打开cmd,输入:</span><br><span class="line">node -v</span><br><span class="line">npm -v</span><br><span class="line">hexo -v</span><br></pre></td></tr></table></figure><p>如果显示“不是内部或外部命令,也不是可运行的程序或批处理文件”:</p><p>解决方法一:看环境变量是否配置成功,</p><p>用户变量的<code>Path</code>中应该含有<code>C:\Users\ZhuRuida\AppData\Roaming\npm</code></p><p>系统变量的<code>Path</code>中应该含有<code>D:\nodejs</code></p><p>解决方法二:</p><p>重新安装node.js和npm:运行node-v22.12.0-x64.msi,安装路径还是选择<code>D:\nodejs</code>即可。<br>重新安装hexo:命令行输入<code>npm i hexo-cli -g</code>即可,<br>其他不用动。</p><h5 id="5-页面的微小改动:"><a href="#5-页面的微小改动:" class="headerlink" title="5.页面的微小改动:"></a>5.页面的微小改动:</h5><p>底端:修改 <code>F:\myBlog_241208\blog\themes\snail\layout\_partial\footer.ejs</code> 的90,91,95行。</p><p>标签页icon:修改<code>F:\myBlog_241208\blog\themes\snail\layout\_partial\head.ejs</code>的15行。</p><p>右上角导航栏:在<code>blog\source</code>目录下删去<code>categories</code>文件夹。</p><p>有两套独立的分类:Tags和Categories,只有第一种就够了。</p><h4 id="6-页面背景颜色修改:"><a href="#6-页面背景颜色修改:" class="headerlink" title="6.页面背景颜色修改:"></a>6.<font color='orange'>页面背景颜色修改</font>:</h4><p>修改F:\myBlog_241208\blog\themes\snail\source\css\dusign-light.css的第61行:</p><p>删去该行:默认白色</p><p>其他护眼颜色:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">#ede9e1 Zotero中的米色</span><br><span class="line">极浅灰:#f5f5f5 / #fafafa</span><br><span class="line">豆沙绿(经典护眼色):#cce8cf / #d1e8d9</span><br><span class="line">更浅的薄荷绿:#e8f5e9 / #f0f9f1</span><br><span class="line">灰绿调:#e0ebe0</span><br><span class="line">淡天蓝:#e8f4f8 / #ecf5ff</span><br><span class="line">灰蓝:#e3e8f0</span><br><span class="line">经典“眼睛舒适蓝”:#e6f0ff(非常淡)</span><br></pre></td></tr></table></figure><h4 id="7-评论区设置:【貌似无法删评,评论是永久的】"><a href="#7-评论区设置:【貌似无法删评,评论是永久的】" class="headerlink" title="7.评论区设置:【貌似无法删评,评论是永久的】"></a>7.评论区设置:【貌似无法删评,评论是永久的】</h4><p>参考:</p><p><a href="https://github.com/dusign/hexo-theme-snail" target="_blank" rel="noopener">https://github.com/dusign/hexo-theme-snail</a> Configuration的 Comment<br><a href="https://blog.csdn.net/ddxygq/article/details/86499623" target="_blank" rel="noopener">https://blog.csdn.net/ddxygq/article/details/86499623</a></p><p>步骤:</p><p><a href="https://github.com/settings/applications/new" target="_blank" rel="noopener">Register a new OAuth app</a></p><p><img src="image-20251217105040701.png" alt="image-20251217105040701"></p><p>新页面有:Client ID、Client secrets</p><p>修改<code>F:\myBlog_241208\blog\_config.yml</code>:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">comment:</span><br><span class="line"> gitment:</span><br><span class="line"> enable: true</span><br><span class="line"> owner: Dowerinne</span><br><span class="line"> repo: Dowerinne.github.io</span><br><span class="line"> client_id: [新页面的Client ID]</span><br><span class="line"> client_secret: [Client secrets]</span><br></pre></td></tr></table></figure><p>初始化评论:<br>每一篇博文都需要单独初始化:点进去页面,登录我的Dowerinne账号,点下面蓝色的<font color='blue'>Initialize Comments</font>。</p><p>报错:我第一次登录时,卡在logging in的位置,解决方案:<a href="https://saltyfishyjk.github.io/2022/04/12/Gitment%E8%AF%84%E8%AE%BA%E5%8C%BA%E9%85%8D%E7%BD%AE%E4%B8%8E%E4%BD%BF%E7%94%A8/#Part-2-%E4%BD%BF%E7%94%A8Gitment" target="_blank" rel="noopener">卡在logging in的位置解决方案</a></p><p>(我登录自己的号评论,有这个问题,别人登录别人的号评论就没事。)</p><h4 id="8-如何插入本地图片"><a href="#8-如何插入本地图片" class="headerlink" title="8.如何插入本地图片"></a>8.如何插入本地图片</h4><p>先安装<a href="https://github.com/yiyungent/hexo-asset-img/blob/main/README_zh.md" target="_blank" rel="noopener">hexo-asset-img</a></p><p>cmd中:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">F:\myBlog_241208\blog>npm install hexo-asset-img --save</span><br></pre></td></tr></table></figure><p>举个例子:<br>1.2024-12-09-博客搭建记录-20241208.md的本地图片,默认在<code>F:\myBlog_241208\blog\source\_posts\2024-12-09-博客搭建记录-20241208.assets</code>中;<br>2.把里面的图片,复制到<code>F:\myBlog_241208\blog\source\_posts\2024-12-09-博客搭建记录-20241208</code>中。<br>3.md中,修改图片路径:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">原先:</span><br><span class="line">(./2024-12-09-博客搭建记录-20241208.assets/image-20251217105040701.png)</span><br><span class="line"></span><br><span class="line">改成:</span><br><span class="line">(2024-12-09-博客搭建记录-20241208/image-20251217105040701.png)</span><br></pre></td></tr></table></figure><p>即可在网页中正确渲染。</p><h4 id="hexo命令整理:【待补充继续学习】-https-hexo-io"><a href="#hexo命令整理:【待补充继续学习】-https-hexo-io" class="headerlink" title="hexo命令整理:【待补充继续学习】 https://hexo.io/"></a>hexo命令整理:【<font color='red'>待补充继续学习</font>】 <a href="https://hexo.io/" target="_blank" rel="noopener">https://hexo.io/</a></h4><p>1.<code>hexo new <articlename></code>:新建一篇博文,存放在<code>F:\myBlog_241208\blog\source\_posts\<articlename>.md</code>,都是markdown格式,用typora书写。</p><blockquote><p>所有博文都在<code>F:\myBlog_241208\blog\source\_posts\</code>目录下。</p></blockquote><p>2.发布/修改博文or修改配置后更新:<code>hexo clean</code> <code>hexo g -d</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hexo clean</span><br><span class="line">hexo g</span><br><span class="line">hexo d</span><br></pre></td></tr></table></figure><p>如果有报错,重新输入一遍命令,就没报错了。</p><p>3.本地查看页面效果:<code>hexo server</code>,浏览器中再打开<code>localhost:4000</code></p><h4 id="补充教程(供参考):"><a href="#补充教程(供参考):" class="headerlink" title="补充教程(供参考):"></a>补充教程(供参考):</h4><p><a href="https://saltyfishyjk.github.io/2022/01/28/Hexo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E5%9B%9E%E9%A1%BE%E6%A6%82%E8%A7%88/" target="_blank" rel="noopener">Hexo博客搭建回顾概览</a></p><h4 id="过程中遇到的一些错误的解决方案:"><a href="#过程中遇到的一些错误的解决方案:" class="headerlink" title="过程中遇到的一些错误的解决方案:"></a>过程中遇到的一些错误的解决方案:</h4><p><a href="https://blog.csdn.net/hannikan/article/details/120838724" target="_blank" rel="noopener">npm : 无法加载文件 D:\nodejs\npm.ps1</a></p><p><a href="https://juejin.cn/post/7151669178381008910" target="_blank" rel="noopener">hexo : 无法加载文件\AppData\Roaming\npm\hexo.ps1</a></p><p><a href="https://blog.csdn.net/2301_81265915/article/details/144092365" target="_blank" rel="noopener">解决 git 报错 “fatal: unable to access ‘https://github.com/…/.git‘: Recv failure Connection was reset</a></p>]]></content>
<tags>
<tag> HexoBlog </tag>
</tags>
</entry>
<entry>
<title>hello-blog</title>
<link href="/2024/12/09/hello-blog/"/>
<url>/2024/12/09/hello-blog/</url>
<content type="html"><![CDATA[<p>2024.12.09 test</p><p>2024.02.05 Test,重新安装了Node.js,npm和hexo,<code>F:\myBlog_241208</code>文件夹原封不动,看是否能行。</p>]]></content>
</entry>
</search>