必知必會:基于Transformer 的預訓練語言模型如何區分文本位置(sinusoidal位置編碼、原理和詳細推導)

預訓練位置編碼

基于Transformer 的預訓練語言模型如何區分文本位置?

基于 Transformer 的預訓練語言模型主要通過位置編碼來區分文本位置。Transformer 核心的自注意力機制本身并不考慮詞的順序,它對輸入序列的處理是與位置無關的。在 query 和 key 的矩陣乘法之后,計算出當前 query 與所有 key 的相關性得分,經過 softmax 運算后得到一個表示相關性的概率分布,分布中的每一個元素都叫作“注意力分數”。自注意力機制已經喪失了表示詞的位置信息的能力,所計算的注意力分數僅僅是表示相關性大小的標量。換句話說,把任意兩個詞的位置相互調換,它們之間的注意力分數是一樣的。

位置信息在各類自然語言處理任務中都很重要,尤其是在漢語中,順序等位置信息對于語義理解十分關鍵。因此,為了使 Transformer 模型能夠區分詞的順序,我們需要給模型添加位置信息,這就是要在 Transformer 模型中增加位置編碼的原因。經典的位置編碼主要分為兩種,分別是絕對位置編碼和相對位置編碼

絕對位置編碼的主要思想是建模文本中每個詞的位置信息,并將位置信息融入模型的輸入中。以下是兩種具有代表性的絕對位置編碼方法。

  • *第一種是 BERT 所用的訓練式絕對位置編碼。該編碼方法可以將文本的位置信息編碼成大小為 seq_len×hidden_size 的可訓練參數,并隨著模型的訓練不斷更新,其中,seq_len 表示模型輸入文本的最大長度,hidden_size 表示位置向量的編碼維度。訓練式絕對位置編碼的一個顯著缺點是無法外推,即當輸入到模型中的文本長度超過 seq_len 時,模型無法為超長的文本提供有意義的位置編碼。

  • *第二種是 Transformer 所用的 sinusoidal 位置編碼。如下述公式所示:
    {pk,2i=sin?(k/10?0002i/d)pk,2i+1=cos?(k/10?0002i/d) \begin{cases} p_{k,2i} = \sin(k / 10\ 000^{2i/d}) \\ p_{k,2i+1} = \cos(k / 10\ 000^{2i/d}) \end{cases} {pk,2i?=sin(k/10?0002i/d)pk,2i+1?=cos(k/10?0002i/d)?

對于位置 kkk,利用三角函數將文本的位置信息編碼為維度大小是 ddd 的位置向量 p\boldsymbol{p}p,其中,iii 表示位置向量中的第 iii 維,位置向量 p\boldsymbol{p}p 在模型的訓練過程中不參與梯度更新。

在 Transformer 的開創性論文 “Attention Is All You Need” 中,作者給出了采用三角函數 sin?\sinsincos?\coscos 的兩個原因。如下述公式所示,

  • 第一個原因是,在位置 kkk上,對于任意的位置偏移 koffsetk_{\text{offset}}koffset?,位置 k+koffsetk+k_{\text{offset}}k+koffset? 上的位置編碼 p(k+koffset)\boldsymbol{p}(k+k_{\text{offset}})p(k+koffset?) 均可以表示成位置 kkk 和位置 koffsetk_{\text{offset}}koffset? 的線性向量組合,這使得模型可以輕松學習到相對位置信息:
    cos?(k+koffset)=cos?k?cos?koffset?sin?k?sin?koffset\cos(k + k_{\text{offset}}) = \cos k \cdot \cos k_{\text{offset}} - \sin k \cdot \sin k_{\text{offset}}cos(k+koffset?)=cosk?coskoffset??sink?sinkoffset?

  • 第二個原因是,sin?\sinsin 函數與 cos?\coscos 函數的值域穩定在固定區間,這意味著無論編碼的文本長度是 5 還是 500,位置向量中的取值均在 [?1,1][-1,1][?1,1] 之間。輸出值域的穩定有助于模型的穩定訓練。

要理解位置編碼后詞向量矩陣的計算,需從位置編碼的公式矩陣逐元素相加兩方面分析,以下分步拆解:

以一個簡單的例子來說明位置編碼的計算過程:假如我們輸入的是一個長度為 4 的句子"I like to code",我們可以得到下面的詞向量矩陣 x\rm xx ,其中每一行代表的就是一個詞向量, x0=[0.1,0.2,0.3,0.4]\rm x_0=[0.1,0.2,0.3,0.4]x0?=[0.1,0.2,0.3,0.4] 對應的就是“I”的詞向量,它的pos就是為0,以此類推,第二行代表的是“like”的詞向量,它的pos就是1:

x=[0.10.20.30.40.20.30.40.50.30.40.50.60.40.50.60.7] \rm x = \begin{bmatrix} 0.1 & 0.2 & 0.3 & 0.4 \\ 0.2 & 0.3 & 0.4 & 0.5 \\ 0.3 & 0.4 & 0.5 & 0.6 \\ 0.4 & 0.5 & 0.6 & 0.7 \end{bmatrix} x=?0.10.20.30.4?0.20.30.40.5?0.30.40.50.6?0.40.50.60.7??

?則經過位置編碼后的詞向量為:

xPE=[0.10.20.30.40.20.30.40.50.30.40.50.60.40.50.60.7]+[sin?(0100000)cos?(0100000)sin?(0100002/4)cos?(0100002/4)sin?(1100000)cos?(1100000)sin?(1100002/4)cos?(1100002/4)sin?(2100000)cos?(2100000)sin?(2100002/4)cos?(2100002/4)sin?(3100000)cos?(3100000)sin?(3100002/4)cos?(3100002/4)]=[0.11.20.31.41.0410.840.411.491.209?0.0160.521.590.541?0.4890.8951.655] \rm x_{PE} = \begin{bmatrix} 0.1 & 0.2 & 0.3 & 0.4 \\ 0.2 & 0.3 & 0.4 & 0.5 \\ 0.3 & 0.4 & 0.5 & 0.6 \\ 0.4 & 0.5 & 0.6 & 0.7 \end{bmatrix} + \begin{bmatrix} \sin(\frac{0}{10000^0}) & \cos(\frac{0}{10000^0}) & \sin(\frac{0}{10000^{2/4}}) & \cos(\frac{0}{10000^{2/4}}) \\ \sin(\frac{1}{10000^0}) & \cos(\frac{1}{10000^0}) & \sin(\frac{1}{10000^{2/4}}) & \cos(\frac{1}{10000^{2/4}}) \\ \sin(\frac{2}{10000^0}) & \cos(\frac{2}{10000^0}) & \sin(\frac{2}{10000^{2/4}}) & \cos(\frac{2}{10000^{2/4}}) \\ \sin(\frac{3}{10000^0}) & \cos(\frac{3}{10000^0}) & \sin(\frac{3}{10000^{2/4}}) & \cos(\frac{3}{10000^{2/4}}) \end{bmatrix} = \begin{bmatrix} 0.1 & 1.2 & 0.3 & 1.4 \\ 1.041 & 0.84 & 0.41 & 1.49 \\ 1.209 & -0.016 & 0.52 & 1.59 \\ 0.541 & -0.489 & 0.895 & 1.655 \end{bmatrix} xPE?=?0.10.20.30.4?0.20.30.40.5?0.30.40.50.6?0.40.50.60.7??+?sin(1000000?)sin(1000001?)sin(1000002?)sin(1000003?)?cos(1000000?)cos(1000001?)cos(1000002?)cos(1000003?)?sin(100002/40?)sin(100002/41?)sin(100002/42?)sin(100002/43?)?cos(100002/40?)cos(100002/41?)cos(100002/42?)cos(100002/43?)??=?0.11.0411.2090.541?1.20.84?0.016?0.489?0.30.410.520.895?1.41.491.591.655??

詳細講解

Transformer中,位置編碼(Positional Encoding)的公式為:
PE(pos,2i)=sin?(pos100002i/dmodel)PE(pos,2i+1)=cos?(pos100002i/dmodel) \text{PE}_{(\text{pos}, 2i)} = \sin\left( \frac{\text{pos}}{10000^{2i/d_{\text{model}}}} \right) \\ \text{PE}_{(\text{pos}, 2i+1)} = \cos\left( \frac{\text{pos}}{10000^{2i/d_{\text{model}}}} \right) PE(pos,2i)?=sin(100002i/dmodel?pos?)PE(pos,2i+1)?=cos(100002i/dmodel?pos?)
其中:

  • pos\text{pos}pos:詞在序列中的位置(從0開始);
  • iii:詞向量的維度索引(從0開始);
  • dmodeld_{\text{model}}dmodel?:詞向量的維度(示例中詞向量是4維,所以 dmodel=4d_{\text{model}}=4dmodel?=4)。

位置編碼矩陣的計算(逐行、逐列拆解)

示例中句子長度為4(詞的位置 pos=0,1,2,3\text{pos}=0,1,2,3pos=0,1,2,3),詞向量維度 dmodel=4d_{\text{model}}=4dmodel?=4。我們需要為每個位置 pos\text{pos}pos 生成一個4維的位置編碼向量,最終組成4×4的位置編碼矩陣,再與原始詞向量矩陣逐元素相加。

步驟1:計算位置編碼矩陣的每個元素

以“位置 pos=0\text{pos}=0pos=0(對應單詞"I")”的4維位置編碼為例,逐維度(i=0,1,2,3i=0,1,2,3i=0,1,2,3)計算:

  • 維度 i=0i=0i=0
    代入公式,2i=02i = 02i=0,所以用 sin?\sinsin 公式:
    PE(0,0)=sin?(0100000/4)=sin?(0)=0 \text{PE}_{(0, 0)} = \sin\left( \frac{0}{10000^{0/4}} \right) = \sin(0) = 0 PE(0,0)?=sin(100000/40?)=sin(0)=0

  • 維度 i=1i=1i=1
    2i=22i = 22i=2,但 2i+1=12i+1 = 12i+1=1,所以用 cos?\coscos 公式:
    PE(0,1)=cos?(0100002/4)=cos?(0)=1 \text{PE}_{(0, 1)} = \cos\left( \frac{0}{10000^{2/4}} \right) = \cos(0) = 1 PE(0,1)?=cos(100002/40?)=cos(0)=1

  • 維度 i=2i=2i=2
    2i=22i = 22i=2,用 sin?\sinsin 公式:
    PE(0,2)=sin?(0100004/4)=sin?(0)=0 \text{PE}_{(0, 2)} = \sin\left( \frac{0}{10000^{4/4}} \right) = \sin(0) = 0 PE(0,2)?=sin(100004/40?)=sin(0)=0

  • 維度 i=3i=3i=3
    2i+1=32i+1 = 32i+1=3,用 cos?\coscos 公式:
    PE(0,3)=cos?(0100006/4)=cos?(0)=1 \text{PE}_{(0, 3)} = \cos\left( \frac{0}{10000^{6/4}} \right) = \cos(0) = 1 PE(0,3)?=cos(100006/40?)=cos(0)=1

因此,pos=0\text{pos}=0pos=0 的位置編碼向量[0,1,0,1][0, 1, 0, 1][0,1,0,1]

步驟2:同理計算其他位置的編碼向量
  • pos=1\text{pos}=1pos=1(對應單詞"like")
    逐維度計算后,位置編碼向量為:
    [sin?(1100000),cos?(1100000),sin?(1100002/4),cos?(1100002/4)]≈[0.841,0.540,0.841,0.540] \left[ \sin\left( \frac{1}{10000^0} \right), \cos\left( \frac{1}{10000^0} \right), \sin\left( \frac{1}{10000^{2/4}} \right), \cos\left( \frac{1}{10000^{2/4}} \right) \right] \approx [0.841, 0.540, 0.841, 0.540] [sin(1000001?),cos(1000001?),sin(100002/41?),cos(100002/41?)][0.841,0.540,0.841,0.540]

  • pos=2\text{pos}=2pos=2(對應單詞"to")
    位置編碼向量為:
    [sin?(2100000),cos?(2100000),sin?(2100002/4),cos?(2100002/4)]≈[0.909,?0.416,0.909,?0.416] \left[ \sin\left( \frac{2}{10000^0} \right), \cos\left( \frac{2}{10000^0} \right), \sin\left( \frac{2}{10000^{2/4}} \right), \cos\left( \frac{2}{10000^{2/4}} \right) \right] \approx [0.909, -0.416, 0.909, -0.416] [sin(1000002?),cos(1000002?),sin(100002/42?),cos(100002/42?)][0.909,?0.416,0.909,?0.416]

  • pos=3\text{pos}=3pos=3(對應單詞"code")
    位置編碼向量為:
    [sin?(3100000),cos?(3100000),sin?(3100002/4),cos?(3100002/4)]≈[0.141,?0.989,0.141,?0.989] \left[ \sin\left( \frac{3}{10000^0} \right), \cos\left( \frac{3}{10000^0} \right), \sin\left( \frac{3}{10000^{2/4}} \right), \cos\left( \frac{3}{10000^{2/4}} \right) \right] \approx [0.141, -0.989, 0.141, -0.989] [sin(1000003?),cos(1000003?),sin(100002/43?),cos(100002/43?)][0.141,?0.989,0.141,?0.989]

步驟3:組合成“位置編碼矩陣”

將4個位置的編碼向量按行排列,得到4×4的位置編碼矩陣
[01010.8410.5400.8410.5400.909?0.4160.909?0.4160.141?0.9890.141?0.989] \left[ \begin{array}{cccc} 0 & 1 & 0 & 1 \\ 0.841 & 0.540 & 0.841 & 0.540 \\ 0.909 & -0.416 & 0.909 & -0.416 \\ 0.141 & -0.989 & 0.141 & -0.989 \\ \end{array} \right] ?00.8410.9090.141?10.540?0.416?0.989?00.8410.9090.141?10.540?0.416?0.989??

三、原始詞向量與位置編碼“逐元素相加”

原始詞向量矩陣 x\text{x}x 是:
x=[0.10.20.30.40.20.30.40.50.30.40.50.60.40.50.60.7] \text{x} = \left[ \begin{array}{cccc} 0.1 & 0.2 & 0.3 & 0.4 \\ 0.2 & 0.3 & 0.4 & 0.5 \\ 0.3 & 0.4 & 0.5 & 0.6 \\ 0.4 & 0.5 & 0.6 & 0.7 \\ \end{array} \right] x=?0.10.20.30.4?0.20.30.40.5?0.30.40.50.6?0.40.50.60.7??

位置編碼矩陣與 x\text{x}x 逐元素相加(即每個位置的詞向量 + 對應位置的編碼向量),以第一行為例:

  • 原始第一行:[0.1,0.2,0.3,0.4][0.1, 0.2, 0.3, 0.4][0.1,0.2,0.3,0.4]
  • 位置編碼第一行:[0,1,0,1][0, 1, 0, 1][0,1,0,1]
  • 相加后第一行:[0.1+0,0.2+1,0.3+0,0.4+1]=[0.1,1.2,0.3,1.4][0.1+0, 0.2+1, 0.3+0, 0.4+1] = [0.1, 1.2, 0.3, 1.4][0.1+0,0.2+1,0.3+0,0.4+1]=[0.1,1.2,0.3,1.4]

其余情況相同,以此類推

  • 實現代碼:
import numpy as np
import matplotlib.pyplot as plt
def PositionEncoding(seq_len, d_model, n=10000):P = np.zeros((seq_len, d_model))for k in range(seq_len):for i in np.arange(int(d_model/2)):denominator = np.power(n, 2*i/d_model)P[k, 2*i] = np.sin(k/denominator)P[k, 2*i+1] = np.cos(k/denominator)return PP = PositionEncoding(seq_len=4, d_model=4, n=1000)
print(P)[[ 0.          1.          0.          1.        ][ 0.84147098  0.54030231  0.03161751  0.99950004][ 0.90929743 -0.41614684  0.0632034   0.99800067][ 0.14112001 -0.9899925   0.09472609  0.99550337]]

其中參數n的作用是控制位置編碼中正弦/余弦函數的周期變化速率,具體來說:

  1. n是一個縮放因子,默認值通常設為10000(如原Transformer論文中所示)
  2. 在計算時,它通過np.power(n, 2*i/d_model)影響函數的周期
  3. 不同的i(維度索引)會得到不同周期的正弦/余弦函數,周期范圍從2π*n
  4. n值越大,不同維度之間的周期差異越顯著

n被設為100,這會使得位置編碼的周期變化比默認值10000更快。通過這種方式,模型能夠區分序列中不同位置的元素,即使它們在詞嵌入上是相同的。

n較小時(如100),位置編碼的數值變化會更劇烈;而當n較大時(如10000),數值變化會更平緩,能更好地處理長序列。

這樣的位置編碼主要有兩個好處:

  1. 使 PE 能夠適應比訓練集里面所有句子更長的句子,假設訓練集里面最長的句子是有 30 個單詞,突然來了一個長度為 31 的句子,則使用公式計算的方法可以計算出第 31 位的 Embedding。
  2. 可以讓模型容易地計算出相對位置,對于固定長度的間距 k,PE(pos+k) 可以用 PE(pos) 計算得到。因為 Sin(A+B) = Sin(A)Cos(B) + Cos(A)Sin(B), Cos(A+B) = Cos(A)Cos(B) - Sin(A)Sin(B)。

進一步推理:

更多原理性知識見前置知識模塊

可以通過嚴謹的數學推導證明該編碼方式的優越性。原始的 Transformer Embedding 可以表示為:

f(??,xm,??,xn,??)=f(??,xn,??,xm,??) \begin{equation}f(\cdots,\boldsymbol{x}_m,\cdots,\boldsymbol{x}_n,\cdots)=f(\cdots,\boldsymbol{x}_n,\cdots,\boldsymbol{x}_m,\cdots)\end{equation} f(?,xm?,?,xn?,?)=f(?,xn?,?,xm?,?)??

很明顯,這樣的函數是不具有不對稱性的,也就是無法表征相對位置信息。我們想要得到這樣一種編碼方式:

f~(??,xm,??,xn,??)=f(??,xm+pm,??,xn+pn,??) \begin{equation}\tilde{f}(\cdots,\boldsymbol{x}_m,\cdots,\boldsymbol{x}_n,\cdots)=f(\cdots,\boldsymbol{x}_m + \boldsymbol{p}_m,\cdots,\boldsymbol{x}_n + \boldsymbol{p}_n,\cdots)\end{equation} f~?(?,xm?,?,xn?,?)=f(?,xm?+pm?,?,xn?+pn?,?)??

這里加上的 pmp_mpm?pnp_npn? 就是位置編碼。接下來我們將 f(...,xm+pm,...,xn+pn)f(...,x_m+p_m,...,x_n+p_n)f(...,xm?+pm?,...,xn?+pn?) 在 m,n 兩個位置上做泰勒展開:

f~≈f+pm??f?xm+pn??f?xn+12pm??2f?xm2pm+12pn??2f?xn2pn+pm??2f?xm?xnpn?pm?Hpn \begin{equation}\tilde{f}\approx f + \boldsymbol{p}_m^{\top} \frac{\partial f}{\partial \boldsymbol{x}_m} + \boldsymbol{p}_n^{\top} \frac{\partial f}{\partial \boldsymbol{x}_n} + \frac{1}{2}\boldsymbol{p}_m^{\top} \frac{\partial^2 f}{\partial \boldsymbol{x}_m^2}\boldsymbol{p}_m + \frac{1}{2}\boldsymbol{p}_n^{\top} \frac{\partial^2 f}{\partial \boldsymbol{x}_n^2}\boldsymbol{p}_n + \underbrace{\boldsymbol{p}_m^{\top} \frac{\partial^2 f}{\partial \boldsymbol{x}_m \partial \boldsymbol{x}_n}\boldsymbol{p}_n}_{\boldsymbol{p}_m^{\top} \boldsymbol{\mathcal{H}} \boldsymbol{p}_n}\end{equation} f~?f+pm???xm??f?+pn???xn??f?+21?pm???xm2??2f?pm?+21?pn???xn2??2f?pn?+pm??Hpn?pm???xm??xn??2f?pn?????

可以看到第1項與位置無關,2~5項僅依賴單一位置,第6項(f 分別對 m、n 求偏導)與兩個位置有關,所以我們希望第六項( pmTHpnp_m^THp_npmT?Hpn? )表達相對位置信息,即求一個函數 g 使得:

pmTHpn=g(m?n) p_m^THp_n = g(m-n) pmT?Hpn?=g(m?n)

我們假設 HHH 是一個單位矩陣,則:

pmTHpn=pmTpn=?pm,pn?=g(m?n) p_m^THp_n = p_m^Tp_n = \langle\boldsymbol{p}_m, \boldsymbol{p}_n\rangle = g(m-n) pmT?Hpn?=pmT?pn?=?pm?,pn??=g(m?n)

通過將向量 [x,y] 視為復數 x+yi,基于復數的運算法則構建方程:

?pm,pn?=Re[pmpn?] \begin{equation}\langle\boldsymbol{p}_m, \boldsymbol{p}_n\rangle = \text{Re}[\boldsymbol{p}_m \boldsymbol{p}_n^*]\end{equation} ?pm?,pn??=Re[pm?pn??]??

再假設存在復數 qm?nq_{m-n}qm?n? 使得:

pmpn?=qm?n \begin{equation}\boldsymbol{p}_m \boldsymbol{p}_n^* = \boldsymbol{q}_{m-n}\end{equation} pm?pn??=qm?n???

使用復數的指數形式求解這個方程,得到二維情形下位置編碼的解:

pm=eimθ?pm=(cos?mθsin?mθ) \begin{equation}\boldsymbol{p}_m = e^{\text{i}m\theta}\quad\Leftrightarrow\quad \boldsymbol{p}_m=\begin{pmatrix}\cos m\theta \\ \sin m\theta\end{pmatrix}\end{equation} pm?=eimθ?pm?=(cosmθsinmθ?)??

由于內積滿足線性疊加性,所以更高維的偶數維位置編碼,我們可以表示為多個二維位置編碼的組合:

pm=(eimθ0eimθ1?eimθd/2?1)?pm=(cos?mθ0sin?mθ0cos?mθ1sin?mθ1?cos?mθd/2?1sin?mθd/2?1) \begin{equation}\boldsymbol{p}_m = \begin{pmatrix}e^{\text{i}m\theta_0} \\ e^{\text{i}m\theta_1} \\ \vdots \\ e^{\text{i}m\theta_{d/2-1}}\end{pmatrix}\quad\Leftrightarrow\quad \boldsymbol{p}_m=\begin{pmatrix}\cos m\theta_0 \\ \sin m\theta_0 \\ \cos m\theta_1 \\ \sin m\theta_1 \\ \vdots \\ \cos m\theta_{d/2-1} \\ \sin m\theta_{d/2-1} \end{pmatrix}\end{equation} pm?=?eimθ0?eimθ1??eimθd/2?1????pm?=?cosmθ0?sinmθ0?cosmθ1?sinmθ1??cosmθd/2?1?sinmθd/2?1?????

再取 θi=10000?2i/d\theta_i = 10000^{-2i/d}θi?=10000?2i/d(該形式可以使得隨著|m?n|的增大,?pm,pn?有著趨于零的趨勢,這一點可以通過對位置編碼做積分來證明,而 base 取為 10000 是實驗結果),就得到了上文的編碼方式。

HHH 不是一個單位矩陣時,因為模型的 Embedding 層所形成的 d 維向量之間任意兩個維度的相關性比較小,滿足一定的解耦性,我們可以將其視作對角矩陣,那么使用上述編碼:

pm?Hpn=∑i=1d/2H2i,2icos?mθicos?nθi+H2i+1,2i+1sin?mθisin?nθi \begin{equation}\boldsymbol{p}_m^{\top} \boldsymbol{\mathcal{H}} \boldsymbol{p}_n=\sum_{i=1}^{d/2} \boldsymbol{\mathcal{H}}_{2i,2i} \cos m\theta_i \cos n\theta_i + \boldsymbol{\mathcal{H}}_{2i+1,2i+1} \sin m\theta_i \sin n\theta_i\end{equation} pm??Hpn?=i=1d/2?H2i,2i?cosmθi?cosnθi?+H2i+1,2i+1?sinmθi?sinnθi???

通過積化和差:

∑i=1d/212(H2i,2i+H2i+1,2i+1)cos?(m?n)θi+12(H2i,2i?H2i+1,2i+1)cos?(m+n)θi \begin{equation}\sum_{i=1}^{d/2} \frac{1}{2}\left(\boldsymbol{\mathcal{H}}_{2i,2i} + \boldsymbol{\mathcal{H}}_{2i+1,2i+1}\right) \cos (m-n)\theta_i + \frac{1}{2}\left(\boldsymbol{\mathcal{H}}_{2i,2i} - \boldsymbol{\mathcal{H}}_{2i+1,2i+1}\right) \cos (m+n)\theta_i \end{equation} i=1d/2?21?(H2i,2i?+H2i+1,2i+1?)cos(m?n)θi?+21?(H2i,2i??H2i+1,2i+1?)cos(m+n)θi???

說明該編碼仍然可以表示相對位置。

上述?編碼結果,如圖所示:

在這里插入圖片描述

前置知識:泰勒展開(Taylor Expansion)

要理解泰勒展開(Taylor Expansion),核心是解決一個問題:如何用“多項式”近似“復雜函數”?比如用簡單的多項式去逼近sin(x)、e^x這類無法用四則運算直接計算的函數,這在數學分析、工程計算、機器學習(如神經網絡激活函數近似)中都有重要用途。

  • 本質思想:“局部線性化”的延伸
    函數在某點(比如x?)的切線(一次多項式)可以近似該點附近的函數值(局部線性化)。但切線的近似精度很低,離x?越遠誤差越大。
    泰勒展開的思路是:用更高次的多項式(比如二次、三次、n次)替代切線,通過匹配函數在x?點的“函數值”“一階導數”“二階導數”……“n階導數”,讓多項式與原函數在x?附近盡可能重合,從而提升近似精度

  • 泰勒展開公式
    對于一個在x?點“足夠光滑”(即n階導數存在)的函數f(x),其在x?點的n階泰勒多項式(泰勒展開的核心表達式)為:
    f(x)≈Pn(x)=f(x0)+f′(x0)(x?x0)+f′′(x0)2!(x?x0)2+f′′′(x0)3!(x?x0)3+?+f(n)(x0)n!(x?x0)n f(x) \approx P_n(x) = f(x_0) + f'(x_0)(x - x_0) + \frac{f''(x_0)}{2!}(x - x_0)^2 + \frac{f'''(x_0)}{3!}(x - x_0)^3 + \dots + \frac{f^{(n)}(x_0)}{n!}(x - x_0)^n f(x)Pn?(x)=f(x0?)+f(x0?)(x?x0?)+2!f′′(x0?)?(x?x0?)2+3!f′′′(x0?)?(x?x0?)3+?+n!f(n)(x0?)?(x?x0?)n
    當n→∞時,若誤差項(余項)趨近于0,則P?(x)會精確等于f(x),此時稱為泰勒級數

公式中各部分的含義:

  • x?:展開的“中心點”(通常選易計算的點,如x?=0,此時稱為“麥克勞林展開”);
  • f(x?):函數在x?點的函數值(保證多項式與原函數在x?點“重合”);
  • f’(x?)(x-x?):一階導數項(保證多項式與原函數在x?點“斜率相同”,即切線方向一致);
  • f’'(x?)/2! · (x-x?)2:二階導數項(保證多項式與原函數在x?點“曲率相同”,即彎曲方向一致);
  • 更高次項:進一步匹配函數的“高階彎曲特性”,讓近似更精準;
  • 1/n!:階乘分母是“歸一化因子”,用于抵消高階導數帶來的數值放大(比如n階導數可能很大,除以n!后能讓各項貢獻更均衡)。
簡單例子:e^x的麥克勞林展開

選擇最經典的例子——指數函數f(x)=ex,展開中心點x?=0(麥克勞林展開),因為ex的各階導數非常簡單,便于計算。

  • 步驟1:計算f(x)=e^x在x?=0處的各階導數
    ex的一個特殊性質是:**任意階導數都等于自身**,即f(k)(x)=ex(k=0,1,2,…,f(0)(x)表示原函數)。
    因此,在x?=0處,所有導數的值都為:f(k)(0)=e0=1。

  • 步驟2:代入泰勒展開公式
    將f(k)(0)=1、x?=0代入公式,得到ex的麥克勞林展開式:
    ex≈1+x+x22!+x33!+x44!+?+xnn! e^x \approx 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \frac{x^4}{4!} + \dots + \frac{x^n}{n!} ex1+x+2!x2?+3!x3?+4!x4?+?+n!xn?

  • 步驟3:用具體數值驗證近似效果
    我們用x=1(計算e^1≈2.71828)來驗證不同階數多項式的近似精度:

  • 0階多項式(只保留常數項):P?(1)=1 → 誤差=2.71828-1=1.71828(誤差很大);
  • 1階多項式(保留到x項):P?(1)=1+1=2 → 誤差=0.71828(誤差減小);
  • 2階多項式(保留到x2/2!):P?(1)=1+1+1/2=2.5 → 誤差=0.21828(誤差進一步減小);
  • 3階多項式(保留到x3/6):P?(1)=1+1+0.5+1/6≈2.66667 → 誤差≈0.05161;
  • 4階多項式(保留到x?/24):P?(1)=2.66667 + 1/24≈2.70833 → 誤差≈0.00995;
  • 5階多項式(保留到x?/120):P?(1)=2.70833 + 1/120≈2.71667 → 誤差≈0.00161;
  • 10階多項式:P??(1)≈2.71828 → 誤差幾乎為0!

前置概念:多變量函數的泰勒展開核心思想

單變量泰勒展開是“匹配單個變量的各階導數”,而多變量泰勒展開的核心是:
對需要偏移的變量(此處為 ( x_m ) 和 ( x_n )),同時匹配它們的“函數值”“一階偏導數”“二階混合偏導數”……“k階混合偏導數”,讓多項式與原函數在“原位置 ( (x_m, x_n) )”附近盡可能重合,從而近似偏移后的函數值 ( f(\dots, x_m+p_m, \dots, x_n+p_n) )。

為簡化表述,我們先定義“簡化函數”:固定除 ( x_m ) 和 ( x_n ) 外的所有變量,將函數記為 二元函數
F(u,v)=f(…,u,…,v,…?) F(u, v) = f(\dots, u, \dots, v, \dots) F(u,v)=f(,u,,v,)
其中 ( u = x_m )(原第m個變量)、( v = x_n )(原第n個變量),偏移后的函數值即為 ( F(u + p_m, v + p_n) )。

我們的目標就是對 二元函數 ( F(u, v) ) 在點 ( (u_0, v_0) = (x_m, x_n) ) 處做泰勒展開,最終再還原回原函數的表述。

二元函數的泰勒展開公式(核心推導)

對于二元函數 ( F(u, v) ),若在 ( (u_0, v_0) ) 處“足夠光滑”(各階混合偏導數存在),其 k階泰勒多項式(近似偏移后的函數值 ( F(u_0+p_m, v_0+p_n) ))的通用形式為:
F(u0+pm,v0+pn)≈∑k=0K1k!(pm???u+pn???v)kF(u0,v0) F(u_0 + p_m, v_0 + p_n) \approx \sum_{k=0}^K \frac{1}{k!} \left( p_m \cdot \frac{\partial}{\partial u} + p_n \cdot \frac{\partial}{\partial v} \right)^k F(u_0, v_0) F(u0?+pm?,v0?+pn?)k=0K?k!1?(pm???u??+pn???v??)kF(u0?,v0?)

公式中關鍵符號的含義:

  • ( k ):泰勒展開的“階數”(k=0為常數項,k=1為一階偏導數項,k=2為二階混合偏導數項,以此類推);
  • ( \frac{\partial}{\partial u} ) / ( \frac{\partial}{\partial v} ):對變量 ( u )(原 ( x_m ))、( v )(原 ( x_n ))的一階偏導數算子(固定其他變量,僅對單個變量求導);
  • ( \left( p_m \cdot \frac{\partial}{\partial u} + p_n \cdot \frac{\partial}{\partial v} \right)^k ):k階偏導數算子展開(類似二項式定理展開,會產生“純u偏導”“純v偏導”“混合u-v偏導”項);
  • ( \frac{1}{k!} ):階乘歸一化因子(抵消高階偏導數的數值放大,保證各項貢獻均衡)。
分階展開:從低階到高階,直觀理解

為了更清晰,我們按“階數”逐步展開公式,最終還原回原函數 ( f ) 的表述(將 ( u_0=x_m )、( v_0=x_n )、( F ) 換回 ( f ),偏導數算子對應原變量 ( x_m )、( x_n ))。

1. *0階展開(常數項,最粗糙近似)

k=0時,算子項 ( \left( p_m \frac{\partial}{\partial u} + p_n \frac{\partial}{\partial v} \right)^0 = 1 )(任何算子的0次冪為“恒等算子”,即不改變函數),因此:
f(…,xm+pm,…,xn+pn)≈f(…,xm,…,xn,…?) f(\dots, x_m+p_m, \dots, x_n+p_n) \approx f(\dots, x_m, \dots, x_n, \dots) f(,xm?+pm?,,xn?+pn?)f(,xm?,,xn?,)
含義:完全忽略偏移 ( p_m )、( p_n ),直接用原位置的函數值近似偏移后的值——誤差最大,但最簡單。

2. 1階展開(線性項,局部線性近似)

k=1時,算子項展開為 ( p_m \frac{\partial}{\partial u} + p_n \frac{\partial}{\partial v} ),因此:
f(…,xm+pm,…,xn+pn)≈f(…,xm,…,xn,…?)+pm??f?xm(…,xm,…,xn,…?)+pn??f?xn(…,xm,…,xn,…?) \begin{align*} f(\dots, x_m+p_m, \dots, x_n+p_n) &\approx f(\dots, x_m, \dots, x_n, \dots) + \\ &p_m \cdot \frac{\partial f}{\partial x_m}(\dots, x_m, \dots, x_n, \dots) + \\ &p_n \cdot \frac{\partial f}{\partial x_n}(\dots, x_m, \dots, x_n, \dots) \end{align*} f(,xm?+pm?,,xn?+pn?)?f(,xm?,,xn?,)+pm???xm??f?(,xm?,,xn?,)+pn???xn??f?(,xm?,,xn?,)?
符號說明:( \frac{\partial f}{\partial x_m} ) 表示“固定其他變量,僅對第m個變量 ( x_m ) 求一階偏導數”,反映 ( x_m ) 變化對 ( f ) 的“線性影響速率”;同理 ( \frac{\partial f}{\partial x_n} ) 反映 ( x_n ) 的線性影響速率。

含義:用“平面”(二元函數的“切線平面”)近似偏移后的函數值,考慮了兩個變量的“獨立線性貢獻”——誤差比0階小,適用于偏移量 ( p_m )、( p_n ) 很小的場景。

3. 2階展開(二次項,考慮曲率和交互作用)

k=2時,算子項按二項式定理展開為 ( p_m^2 \frac{\partial^2}{\partial u^2} + 2p_m p_n \frac{\partial^2}{\partial u \partial v} + p_n^2 \frac{\partial^2}{\partial v^2} ),因此:
f(…,xm+pm,…,xn+pn)≈0階項+1階項+12![pm2??2f?xm2+2pmpn??2f?xm?xn+pn2??2f?xn2] \begin{align*} f(\dots, x_m+p_m, \dots, x_n+p_n) &\approx 0階項 + 1階項 + \\ &\frac{1}{2!} \left[ p_m^2 \cdot \frac{\partial^2 f}{\partial x_m^2} + 2p_m p_n \cdot \frac{\partial^2 f}{\partial x_m \partial x_n} + p_n^2 \cdot \frac{\partial^2 f}{\partial x_n^2} \right] \end{align*} f(,xm?+pm?,,xn?+pn?)?0階項+1階項+2!1?[pm2???xm2??2f?+2pm?pn???xm??xn??2f?+pn2???xn2??2f?]?
符號說明

  • ( \frac{\partial^2 f}{\partial x_m^2} ):對 ( x_m ) 的“二階純偏導數”,反映 ( x_m ) 變化對 ( f ) 的“曲率影響”(比如變量 ( x_m ) 增加時,( f ) 的增長速率是加快還是減慢);
  • ( \frac{\partial^2 f}{\partial x_n^2} ):對 ( x_n ) 的二階純偏導數,含義同上;
  • ( \frac{\partial^2 f}{\partial x_m \partial x_n} ):“混合偏導數”,反映 ( x_m ) 和 ( x_n ) 的“交互影響”(比如 ( x_m ) 增加時,( x_n ) 對 ( f ) 的影響是否會變化)。

含義:用“二次曲面”近似函數,不僅考慮了線性貢獻,還加入了“曲率”和“變量交互作用”——近似精度顯著提升,適用于偏移量稍大或需要更高精度的場景。

4. 高階展開(k≥3)

k≥3時,會產生更高階的混合偏導數項(如 ( p_m^3 \frac{\partial^3 f}{\partial x_m^3} )、( p_m^2 p_n \frac{\partial^3 f}{\partial x_m^2 \partial x_n} ) 等),形式更復雜,但核心邏輯不變:通過匹配更高階的偏導數,進一步減小近似誤差

當 ( k \to \infty ) 且余項趨近于0時,泰勒多項式會精確等于原函數,此時稱為“泰勒級數”。

簡單例子:用具體函數驗證

假設原函數為 二元二次函數 ( f(x_m, x_n) = x_m^2 + 2x_m x_n + 3x_n^2 )(固定其他變量,僅關注 ( x_m ) 和 ( x_n )),我們要近似偏移后的函數值 ( f(x_m + p_m, x_n + p_n) ),并與“直接計算結果”對比,驗證泰勒展開的正確性。

步驟1:直接計算偏移后的函數值(真實值)

f(xm+pm,xn+pn)=(xm+pm)2+2(xm+pm)(xn+pn)+3(xn+pn)2=xm2+2xmpm+pm2+2xmxn+2xmpn+2xnpm+2pmpn+3xn2+6xnpn+3pn2 \begin{align*} f(x_m+p_m, x_n+p_n) &= (x_m+p_m)^2 + 2(x_m+p_m)(x_n+p_n) + 3(x_n+p_n)^2 \\ &= x_m^2 + 2x_m p_m + p_m^2 + 2x_m x_n + 2x_m p_n + 2x_n p_m + 2p_m p_n + 3x_n^2 + 6x_n p_n + 3p_n^2 \end{align*} f(xm?+pm?,xn?+pn?)?=(xm?+pm?)2+2(xm?+pm?)(xn?+pn?)+3(xn?+pn?)2=xm2?+2xm?pm?+pm2?+2xm?xn?+2xm?pn?+2xn?pm?+2pm?pn?+3xn2?+6xn?pn?+3pn2??

步驟2:用2階泰勒展開計算(近似值)

首先計算原函數在 ( (x_m, x_n) ) 處的各階偏導數:

  • 0階項:( f(x_m, x_n) = x_m^2 + 2x_m x_n + 3x_n^2 );
  • 1階偏導數:( \frac{\partial f}{\partial x_m} = 2x_m + 2x_n ),( \frac{\partial f}{\partial x_n} = 2x_m + 6x_n );
  • 2階偏導數:( \frac{\partial^2 f}{\partial x_m^2} = 2 ),( \frac{\partial^2 f}{\partial x_n^2} = 6 ),( \frac{\partial^2 f}{\partial x_m \partial x_n} = 2 );
  • 3階及以上偏導數:均為0(因為原函數是二次函數,高階導數為0)。

代入2階泰勒展開公式:
近似值=0階項+1階項+12![pm2?2+2pmpn?2+pn2?6]=(xm2+2xmxn+3xn2)+[pm(2xm+2xn)+pn(2xm+6xn)]+12[2pm2+4pmpn+6pn2]=xm2+2xmxn+3xn2+2xmpm+2xnpm+2xmpn+6xnpn+pm2+2pmpn+3pn2 \begin{align*} \text{近似值} &= 0階項 + 1階項 + \frac{1}{2!}[p_m^2 \cdot 2 + 2p_m p_n \cdot 2 + p_n^2 \cdot 6] \\ &= (x_m^2 + 2x_m x_n + 3x_n^2) + [p_m(2x_m+2x_n) + p_n(2x_m+6x_n)] + \frac{1}{2}[2p_m^2 + 4p_m p_n + 6p_n^2] \\ &= x_m^2 + 2x_m x_n + 3x_n^2 + 2x_m p_m + 2x_n p_m + 2x_m p_n + 6x_n p_n + p_m^2 + 2p_m p_n + 3p_n^2 \end{align*} 近似值?=0階項+1階項+2!1?[pm2??2+2pm?pn??2+pn2??6]=(xm2?+2xm?xn?+3xn2?)+[pm?(2xm?+2xn?)+pn?(2xm?+6xn?)]+21?[2pm2?+4pm?pn?+6pn2?]=xm2?+2xm?xn?+3xn2?+2xm?pm?+2xn?pm?+2xm?pn?+6xn?pn?+pm2?+2pm?pn?+3pn2??

可以發現:2階泰勒展開的近似值與直接計算的真實值完全相等
原因是原函數是“二次函數”,而2階泰勒展開已經包含了所有“二次項”,高階項(k≥3)為0,因此沒有誤差——這也體現了泰勒展開的本質:對“k次多項式函數”,k階泰勒展開可完全精確還原函數。

相對位置編碼

相對位置編碼的主要思想是修改自注意力機制,在對兩個位置i和j上的詞進行自注意力運算的時候,將兩個位置的相對距離i-j考慮進來,使得進行自注意力運算之后的結果中包含相對位置信息。在具體實現上,論文“Self-Attention with Relative Position Representations”中給出了實現相對位置編碼方案的框架,后續諸多相對位置編碼的設計思路均遵循此框架。
Transformer對i和j這兩個位置進行自注意力運算的公式如下:
{ai,j=softmax(qikjT)oi=∑jai,jvj \left\{ \begin{aligned} a_{i,j} &=\text{softmax}\left( q_i k_j^{\text{T}} \right) \\ o_i &= \sum_j a_{i,j} v_j \end{aligned} \right. ????ai,j?oi??=softmax(qi?kjT?)=j?ai,j?vj??
其中,qiq_iqi?表示位置iii上的查詢矩陣,kjk_jkj?表示位置jjj上的鍵矩陣,vjv_jvj?表示位置jjj上的值矩陣,ai,ja_{i,j}ai,j?表示位置iii上的查詢矩陣與位置jjj上的鍵矩陣的相關性得分,oio_ioi?是考慮了位置iii和位置jjj上兩個詞之間相關性的表征,其缺少位置iii和位置jjj之間的距離信息。為了將位置iii和位置jjj之間的相對距離信息融入 oio_ioi? 中,作者給出了以下計算方式(具體推導過程見原論文):

oi=∑jai,j(xjWV+Ri,jV)o_i = \sum_j a_{i,j} \left( x_j W_V + R_{i,j}^V \right)oi?=j?ai,j?(xj?WV?+Ri,jV?)

其中,xjx_jxj? 是位置 jjj 上的詞向量,WVW_VWV? 是自注意力在構建查詢矩陣時隨機初始化的一個權重矩陣,其隨著模型的訓練不斷更新。Ri,jVR_{i,j}^VRi,jV? 是一個依賴相對位置信息 i?ji-ji?j 的矩陣,其取值可以由三角函數計算得出,也可以作為可訓練的參數在訓練過程中不斷調整。后續無論是 XLNet、T5、DeBERTa,還是 RoPE 和 ALiBi,它們均圍繞對 qikjTq_i k_j^\text{T}qi?kjT? 的展開式進行修改。它們不僅可以將相對位置信息 i?ji-ji?j 融入自注意力的計算過程中,還在提升訓練效率、增強模型外推能力、融入絕對位置信息等方面給出了各自的方案。

更多位置編碼面試問題

在面試中,關于 Transformer 預訓練模型中的位置編碼(Positional Encoding) 是一個高頻且深入的話題,尤其在考察對 Transformer 架構理解的深度時。以下是可能被問到的相關面試問題,按難度和類別進行分類整理:


🔹 一、基礎概念類問題

  1. 為什么 Transformer 需要位置編碼?

    提示:自注意力機制本身是“位置無關”的(permutation-equivariant),無法捕捉序列順序信息。

  2. 位置編碼的核心作用是什么?

給序列中的每個位置賦予獨特的 “位置標識”,讓模型能夠區分不同位置的 token,從而學習到序列的順序依賴關系。

  1. 原始 Transformer 中使用的是哪種位置編碼?它是如何設計的?

    答案:正弦和余弦函數組合的固定位置編碼(sinusoidal positional encoding)。① 不同位置有不同編碼;② 編碼值應能反映位置間的相對距離(如位置 k 和 k+1 的差異應小于 k 和 k+100);③ 對任意長度序列通用(尤其是長序列)

  2. 請寫出 sinusoidal 位置編碼的公式。

    PE(pos,2i)=sin?(pos100002i/d),PE(pos,2i+1)=cos?(pos100002i/d) PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right), \quad PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right) PE(pos,2i)?=sin(100002i/dpos?),PE(pos,2i+1)?=cos(100002i/dpos?)
    其中 pos 是位置索引,i 是維度索引,d 是 embedding 維度。

  3. 位置編碼加在哪兒?是加在詞向量上嗎?

    是的,位置編碼加在輸入嵌入(token embeddings)上,在送入第一層 encoder/decoder 之前。將位置編碼與詞嵌入直接相加(element-wise addition),兩者維度均為dmodel,相加后作為 Transformer 的輸入


🔹 二、設計原理與動機類問題

  1. 為什么使用正弦函數?有什么好處?

    • 可以讓模型學習到相對位置信息(因為 sin?(a+b)\sin(a+b)sin(a+b) 可以用 sin?a,cos?a\sin a, \cos asina,cosa 表示)
    • 能夠外推到比訓練時更長的序列(理論上)① 天然滿足 “不同位置有不同編碼”;② 能通過三角函數的周期性反映相對位置(如sin(a+b)可由sina,cosa,sinb,cosb線性表示);③ 對長序列友好(無需隨序列長度重新訓練)
  2. 位置編碼為什么能表示相對位置?

    利用三角恒等式:sin?(ω(pos+k))\sin(\omega (pos + k))sin(ω(pos+k))cos?(ω(pos+k))\cos(\omega (pos + k))cos(ω(pos+k)) 可以表示為 sin?(ωpos)\sin(\omega pos)sin(ωpos)cos?(ωpos)\cos(\omega pos)cos(ωpos) 的線性組合,因此模型可以通過權重學習相對偏移 kkk

  3. 為什么選擇 100001000010000 這個常數?

    為了讓不同頻率的位置編碼覆蓋從短距離到非常長距離的周期變化,適合大多數自然語言任務的序列長度。

  4. 位置編碼是可學習的還是固定的?兩者有何優劣?

    • 原始 Transformer 使用固定編碼。
    • BERT 等預訓練模型使用可學習的位置嵌入(learned positional embeddings)。

    對比:

    • 固定:無需訓練,可外推;
    • 可學習:更靈活,但受限于最大長度。

🔹 三、變體與改進類問題(進階)

  1. 除了正弦余弦編碼,還有哪些常用的位置編碼方法?

(考察知識廣度:① 可學習位置編碼(Learned Positional Embedding):隨機初始化參數,隨模型一起訓練;② 相對位置編碼(Relative Position Encoding):直接建模位置間的相對距離;③ 旋轉位置編碼(RoPE):通過旋轉矩陣將絕對位置轉化為相對位置信息(如 LLaMA、GPT 等模型使用)。)

  1. BERT 是如何處理位置編碼的?和原始 Transformer 有何不同?

    BERT 使用可學習的一維位置嵌入,每個位置對應一個向量,通過訓練得到。

  2. ALiBi(Attention with Linear Biases)是如何替代位置編碼的?

    不顯式添加位置編碼,而是在注意力分數上加上與相對距離成線性的偏置項:$ \text{bias} = -\alpha \cdot |i-j| $,其中 α\alphaα 是每個頭不同的斜率。

  3. RoPE(Rotary Position Embedding)的工作原理是什么?為何被廣泛采用(如 LLaMA、ChatGLM)?

    將位置信息通過旋轉矩陣融入 query 和 key 向量中,使得相對位置關系自然體現在點積注意力中,支持更好的外推性和長序列建模。

  4. 什么是絕對位置編碼 vs 相對位置編碼?各自的優缺點?

    • 絕對:每個位置一個編碼(如 BERT),簡單但難外推;
    • 相對:關注 token 之間的相對距離(如 Transformer-XL, DeBERTa),更適合長序列和遷移。

🔹 四、實際應用與限制類問題

  1. 如果輸入序列超過模型允許的最大長度,位置編碼會出問題嗎?

    是的。對于可學習的位置編碼,超出部分沒有定義;對于固定編碼(如 RoPE),可通過插值等方式外推。

  2. 如何讓模型支持更長的上下文(比如從 512 擴展到 2048)?位置編碼方面有哪些方法?

    • 位置插值(Position Interpolation)
    • 動態縮放(NTK-aware scaling)
    • 使用支持外推的編碼方式(如 ALiBi、RoPE)
    • 可學習編碼重新初始化并微調
  3. 位置編碼會影響模型的泛化能力嗎?

    會。錯誤的位置編碼設計可能導致模型無法理解順序、難以遷移或外推。

  4. 位置編碼是否需要歸一化?為什么?

(考察細節處理:通常不需要額外歸一化,因正弦余弦編碼的值范圍固定在 [-1,1],與詞嵌入(通常經 LayerNorm 處理)的尺度兼容;若為可學習編碼,可能需通過初始化控制尺度,避免與詞嵌入差異過大。

  1. 如何驗證位置編碼的有效性?

(考察實驗思維:① 對比 “有無位置編碼” 的模型性能;② 分析模型對序列順序敏感的任務(如語序判斷、問答中的位置依賴)的表現;③ 可視化位置編碼的相似度矩陣,驗證相鄰位置的編碼是否更相似。)

  1. 在多語言模型中,位置編碼是否需要針對不同語言調整?

(考察跨語言適配:通常不需要,因位置編碼建模的是 “序列順序”,與語言無關;但需保證編碼對不同語言的序列長度都有良好泛化性。)

  1. 位置編碼在 Encoder 和 Decoder 中是否有區別?

(考察結構理解:在原始 Transformer 中,Encoder 和 Decoder 使用相同的位置編碼;但部分改進模型中,Decoder 可能采用特殊編碼(如考慮輸出序列的自回歸特性)。)

  1. 為什么位置編碼通常加在詞嵌入之后,而不是作為額外輸入?

(考察設計權衡:直接相加可復用模型的輸入維度,無需增加參數或修改網絡結構,且能讓位置信息與語義信息在底層就融合,更符合 “位置影響語義理解” 的邏輯。)


🔹 五、開放性 / 設計題(高階)

  1. 如果你要設計一個支持無限長度文本的模型,你會如何設計位置編碼?

    考察點:是否了解外推性、相對位置、循環編碼、稀疏注意力配合等。

  2. 能否將位置編碼放在網絡中間層而不是輸入層?有沒有相關工作?

    有研究嘗試(如 DeepNet 中的想法),但主流仍放在輸入側。中間加位置編碼可能破壞深層表示結構,需謹慎設計。

  3. 視覺 Transformer(ViT)中的位置編碼和 NLP 中有何異同?

    ViT 通常使用可學習的 1D 或 2D 位置編碼(考慮圖像空間結構),有時也探索無位置編碼的方法(如 iGPT)。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96276.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96276.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96276.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis key過期后會立馬刪除嗎

Redis 的 Key 過期后不會立即被刪除。Redis 采用了一種結合 ?惰性刪除 (Lazy Expiration)?? 和 ?定期刪除 (Periodic Expiration)?? 的策略來管理過期 Key 的回收,這是為了在內存管理、性能和 CPU 開銷之間取得平衡。📌 Redis 過期 Key 刪除的兩種…

關于 React 19 的四種組件通信方法

注意:使用的是UI庫是 antd-mobile1.父子級組件通信父組件單向數據流:數據從父組件流向子組件。支持多種數據類型:字符串、數字、對象、數組、函數等。只讀性:子組件不能直接修改 props 中的數據。import { useState } from react …

OC-單例模式

文章目錄單例模式定義特點使用原因缺點模式介紹懶漢模式同步鎖實現dispatch_once餓漢模式實現總結懶漢模式優點缺點餓漢模式優點缺點單例模式 定義 單例模式,簡單的說就是一個類始終只對應同一個對象,每次獲取這個類的對象獲得的都是同一個實例 如果一…

[論文閱讀] 算法 | 抗量子+緊湊!SM3-OTS:基于國產哈希算法的一次簽名新方案

抗量子緊湊!SM3-OTS:基于國產哈希算法的一次簽名新方案 論文信息信息類別具體內容論文原標題SM3-OTS: 基于國密算法SM3的緊湊型后量子一次簽名方案主要作者楊亞濤、殷方銳、陳亮宇、潘登研究機構1. 北京電子科技學院 電子與通信工程系(北京 1…

C語言-指針用法概述

目錄 1.指針基礎概念 2. 指針與數組 3. 指針作為函數參數 4. 動態內存分配 5. 指針的高級用法 6. 常見錯誤與注意事項 7. 指針數組 vs. 數組指針 8.總結與建議 本文主要作為指針用法的復習,會對指針的大致用法進行舉例和概述。 1.指針基礎概念 ?什…

Java調用Whisper和Vosk語音識別(ASR)模型,實現高效實時語音識別(附源碼)

簡介 語音識別(Automatic Speech Recognition, ASR)是將人類的語音信號自動轉換為對應文字的技術,它使計算機能夠“聽懂”人說的話,是人機語音交互的核心技術,廣泛應用于智能助手、語音輸入、客服系統等場景。 現在我…

第3周 機器學習課堂記錄

1.學習問題的分類有監督的學習分類回歸無監督學習聚類密度估計:確定輸入空間中的數據的分布可視化:把高位空間中的數據投影到二維或三維空間強化學習不給定最優輸出的示例,而是通過試錯發現最優輸出2.泛化versus過度擬合背景引入:…

消息隊列(MQ)高級特性深度剖析:詳解RabbitMQ與Kafka

一、引言:為什么需要關注高級特性? 在現代分布式系統架構中,消息隊列(Message Queue)已成為不可或缺的核心組件。初級使用消息隊列可能只需幾行代碼就能實現基本功能,但要真正發揮其在大規模生產環境中的威…

【GPT入門】第65課 vllm指定其他卡運行的方法,解決單卡CUDA不足的問題

【GPT入門】第65課 vllm指定其他卡運行的方法,解決單卡CUDA不足的問題1.原理說明:2.實踐1.原理 要將 vllm 部署在第二張 GPU 卡上(設備編號為 1),只需在命令前添加 CUDA_VISIBLE_DE…

Spring Boot Actuator自定義指標與監控實踐指南

Spring Boot Actuator自定義指標與監控實踐指南 本篇文章以生產環境實戰經驗為主線,結合某電商系統的業務場景,講解如何在Spring Boot Actuator中添加并暴露自定義指標,并使用Prometheus和Grafana進行完整的監控與告警配置。 一、業務場景描述…

Vue報錯<template v-for=“option in cardOptions“ :key=“option.value“>

在Vue項目中遇到報錯&#xff0c;原因是模板中使用了<template>標簽內的v-for指令&#xff0c;而當前Vue版本不支持此用法。解決方案是移除<template>標簽&#xff0c;直接在<el-option>上使用v-for。同時優化計算屬性cardOptions&#xff0c;使其能夠兼容歷…

人工智能學習:Transformer結構中的規范化層(層歸一化)

Transformer結構中的規范化層(層歸一化) 一、規范化層(層歸一化)介紹 概念 層歸一化(Layer Normalization) 是一種用于提高深度神經網絡訓練穩定性和加速收斂的技術,廣泛應用于現代深度學習模型中,尤其是在Transformer等序列建模網絡中。它通過對每一層的輸出進行歸一化…

盼之代售 最新版 decode__1174

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 逆向分析 部分python代碼 cp1 execj…

Transformer系列 | Pytorch復現Transformer

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 一、Transformer和Seq2Seq 在之前的博客中我們學習了Seq2Seq(深度學習系列 | Seq2Seq端到端翻譯模型)&#xff0c;知曉了Attention為RNN帶來的優點。那么有沒有…

【MySQL】常用SQL語句

介紹常用的DDL語句、DML語句基本語法分號結尾使用空格和縮進不區分大小寫--或#注釋單行內容 /*注釋多行內容*/DDL數據定義語句&#xff1a;定義數據庫、表、字段一、操作庫-- 創建庫create database db1;-- 創建庫是否存在&#xff0c;不存在則創建create database if not exi…

云手機就是虛擬機嗎?

云手機并非等同于虛擬機&#xff0c;盡管二者存在一定相似性&#xff0c;但有著諸多區別&#xff0c;以下從多個方面來分析&#xff1a;云手機是一種基于云計算技術&#xff0c;將云端服務器虛擬化為手機設備&#xff0c;用戶能通過網絡遠程操控的虛擬手機服務&#xff0c;它從…

準確--Nginx 1.28.0 安裝與配置流程

Nginx 1.28.0 安裝與配置流程 1. 下載與解壓 cd ~ wget http://nginx.org/download/nginx-1.28.0.tar.gz tar -zxvf nginx-1.28.0.tar.gz cd nginx-1.28.02. 配置編譯參數 ./configure \--prefix/home/ynnewweb/nginx \--with-http_ssl_module \--with-http_gzip_static_module…

無標記點動捕新范式:Xsens系統助力人形機器人實現毫米級動作復刻

Xsen搭載Manus數據手套在機器人操作與機器學習中的應用當前&#xff0c;人形機器人正加速向工業裝配、家庭陪護、倉儲物流等場景滲透&#xff0c;而 “如何讓機器人的動作既符合人類運動規律&#xff0c;又能實現高精度執行” 成為制約其落地的核心瓶頸。Xsens 高精度全身動捕系…

mysql57超管root忘記密碼怎么辦

目錄 背景 1.首先停止數據庫 2.使用免密模式啟動 3.修改密碼 3.1刷新權限配置 3.2修改密碼 4.殺掉mysql 5.重新正常啟動mysql 6.查看mysql狀態 7.驗證 7.1首先服務器本地驗證 7.2遠程驗證 背景 數據庫密碼忘記了,急的抓耳撓腮,怎么也想不起來,于是就開始重置吧 1.…

RESTful API:@RequestParam與@PathVariable實戰對比

RequestParam vs PathVariable 在刪除和查找操作中的使用差異 在項目實戰中&#xff0c;選擇使用 RequestParam 還是 PathVariable 來接收ID參數&#xff0c;通常基于以下幾個考慮因素&#xff1a; 1. RESTful API 設計原則 查找操作使用 PathVariable GetMapping("/depts…