瓴岳科技:风控算法实习生
一、介绍GBDT
见【搜广推校招面经二十七】
二、有哪些位置编码的形式
位置编码(Positional Encoding)是Transformer等模型中用于引入序列中位置信息的一种机制,因为Transformer本身是没有位置信息的(不像RNN那样是按顺序处理的)。
2.1. 正弦-余弦位置编码(Sinusoidal Positional Encoding)
这是 Transformer 原论文中使用的形式。
对于位置 pos
和维度 i
:
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 ( 2 i / d m o d e l ) ) P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 ( 2 i / d m o d e l ) ) PE(pos, 2i) = sin(pos / 10000^(2i/d_model)) \\ \ \\ PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model)) PE(pos,2i)=sin(pos/10000(2i/dmodel)) PE(pos,2i+1)=cos(pos/10000(2i/dmodel))
pos
:表示位置i
:表示维度的索引d_model
:词向量维度
特点:
- 不需要学习参数(固定的)
- 任意长度可扩展
- 可以捕捉相对位置关系
2.2. 可学习的位置编码(Learnable Positional Embedding)
每个位置都有一个可训练的向量:
PositionEmbedding = Embedding(position_id)
特点:
- 简单高效,通常效果不错
- 无法外推到未见过的位置(例如训练最多512,测试用1024就不行)
2.3. 相对位置编码(Relative Positional Encoding)
重点建模“位置之间的相对关系”,例如 Transformer-XL、T5、DeBERTa 中使用。
特点:
- 更强的泛化能力
- 更适合语言任务(理解“前后”关系)
2.4. 旋转位置编码(RoPE, Rotary Positional Encoding)
应用于 GPT-NeoX、LLaMA、ChatGLM 等。
思路是:将位置信息嵌入到 Self-Attention 中的 q
和 k
中,通过旋转操作。
特点:
- 易于实现
- 支持更长的上下文扩展
2.5. 2D 或高维位置编码
用于图像(ViT)、音频或视频等任务。
- 2D Sinusoidal Encoding:分别对行、列使用正弦编码再拼接
- 2D Learnable Embedding:行和列方向各自 embedding,再拼接或相加
2.6. 总结
编码方式 | 是否可学习 | 是否支持任意长度 | 是否捕捉相对位置 | 适用场景 |
---|---|---|---|---|
Sinusoidal | ❌ | ✅ | ⚠️间接 | NLP基本任务 |
Learnable | ✅ | ❌ | ❌ | 短文本、常规分类任务 |
Relative | ✅ | ✅ | ✅ | 文本生成、问答等 |
RoPE | ✅ | ✅ | ✅ | 大模型、长文本 |
2D/3D Pos Encoding | ✅/❌ | ✅ | ✅/❌ | 图像、音频、视频 |
三、旋转位置编码和三角函数位置编码的具体区别?
位置编码的目标是给序列中的每个位置引入位置信息。而,RoPE 和 Sinusoidal 都基于三角函数,但实现思路和应用方式不同。
3.1. 三角函数位置编码(Sinusoidal Positional Encoding)
原理:
对每个位置 pos
和维度 i
,用如下公式生成编码:
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 ( 2 i / d m o d e l ) ) P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 ( 2 i / d m o d e l ) ) PE(pos, 2i) = sin(pos / 10000^(2i/d_model)) \\ \ \\ PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model)) PE(pos,2i)=sin(pos/10000(2i/dmodel)) PE(pos,2i+1)=cos(pos/10000(2i/dmodel))
特点:
- 编码是 固定的,不可学习
- 通过不同频率的三角函数编码不同位置
- 编码加入方式:加到输入 token embedding 上
优点:
- 可推广到任意长度
- 保留位置间的距离信息
缺点:
- 不易直接捕捉相对位置关系
- 加法形式限制了表达能力
3.2. 旋转位置编码(Rotary Positional Encoding, RoPE)
原理:
将三角函数的位置编码融入 Attention 计算中的 q
和 k
,通过将其旋转一定角度来表达不同位置。
令二维向量 [x₁, x₂]
通过如下旋转矩阵得到位置编码后的值:
R o P E ( x 1 , x 2 , θ ) = [ x 1 ∗ c o s ( θ ) − x 2 ∗ s i n ( θ ) , x 1 ∗ s i n ( θ ) + x 2 ∗ c o s ( θ ) ] RoPE(x₁, x₂, θ) = [x₁*cos(θ) - x₂*sin(θ), x₁*sin(θ) + x₂*cos(θ)] RoPE(x1,x2,θ)=[x1∗cos(θ)−x2∗sin(θ),x1∗sin(θ)+x2∗cos(θ)]
即把三角函数用作向量旋转操作。
应用方式:
- 不再是加到输入 embedding 上
- 而是作用在 self-attention 的
q
和k
上,编码随位置旋转
特点:
- 编码是可推广的
- 可以自然地表达相对位置差异
- 更适合大模型、长文本
3.3. 对比总结
对比维度 | Sinusoidal Position Encoding | Rotary Position Encoding (RoPE) |
---|---|---|
基础原理 | 不同频率的 sin/cos 函数编码 | 三角函数表示向量旋转 |
是否可学习 | 否 | 否(但可与可学习结合) |
应用位置 | 加到 token embedding 上 | 应用于 attention 中的 q 和 k |
相对位置表达 | 间接表达 | 直接编码相对位置 |
扩展性 | 任意长度 | 任意长度(RoPE 在 GPT 系列中表现优越) |
使用场景 | 原始 Transformer, ViT 等 | GPT-NeoX, LLaMA, ChatGLM 等大模型 |
四、3. 无重复字符的最长子串(力扣hot100_滑动窗口)
- 思路1:
滑动窗口,站在每个右端点,如果当前串内有重复的字符。依次移除左端点的 - 代码:
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:ans = left = 0cnt = defaultdict(int) # 维护从下标 left 到下标 right 的字符及其出现次数for right, c in enumerate(s):cnt[c] += 1while cnt[c] > 1: # 窗口内有重复字母cnt[s[left]] -= 1 # 移除窗口左端点字母left += 1 # 缩小窗口ans = max(ans, right - left + 1) # 更新窗口长度最大值return ans
- 思路2:
依次遍历s,不是重复字符直接加入并计算长度,遇到重复字符,那么当前字符要退出到上一个重复位置。列表可采用 list.index(i),找到i字符在列表中的位置。 - 代码:
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:tmp_s = []max_len = 0for i in s:if i not in tmp_s:tmp_s.append(i)max_len = max(max_len, len(tmp_s))else:index = tmp_s.index(i) tmp_s = tmp_s[index+1:]tmp_s.append(i)return max_len