搜广推校招面经五十四

美团推荐算法

一、手撕Transformer的位置编码

1.1. 位置编码的作用

Transformer 模型没有显式的序列信息(如 RNN 的循环结构),因此需要通过位置编码(Positional Encoding)为输入序列中的每个位置添加位置信息。位置编码的作用是:

  • 提供序列位置信息:帮助模型理解输入序列中元素的顺序。
  • 保持唯一性和连续性:确保每个位置的位置编码是唯一的,且相邻位置的位置编码是连续的。

1.2. 位置编码公式

Transformer 使用正弦和余弦函数生成位置编码,公式如下:
P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i d model ) P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i d model ) PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) \\ \ \\ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) PE(pos,2i)=sin(10000dmodel2ipos) PE(pos,2i+1)=cos(10000dmodel2ipos)
其中:

  • p o s pos pos:位置索引(从 0 开始)。
  • i i i:维度索引(从 0 到 ( \frac{d_{\text{model}}}{2} - 1$)。
  • d model d_{\text{model}} dmodel:模型的嵌入维度。

1.3. PyTorch 实现

以下是使用 PyTorch 实现位置编码的代码:

import torch
import torch.nn as nnclass PositionalEncoding(nn.Module):def __init__(self, d_model, max_len=5000):"""初始化位置编码:param d_model: 嵌入维度:param max_len: 最大序列长度"""super(PositionalEncoding, self).__init__()# 初始化位置编码矩阵pe = torch.zeros(max_len, d_model)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)  # (max_len, 1)div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-torch.log(torch.tensor(10000.0)) / d_model))  # (d_model / 2)# 计算位置编码pe[:, 0::2] = torch.sin(position * div_term)  # 偶数位置使用正弦pe[:, 1::2] = torch.cos(position * div_term)  # 奇数位置使用余弦# 注册为缓冲区(不参与训练)self.register_buffer('pe', pe.unsqueeze(0))  # (1, max_len, d_model)def forward(self, x):"""前向传播:param x: 输入张量,形状为 (batch_size, seq_len, d_model):return: 添加位置编码后的张量,形状为 (batch_size, seq_len, d_model)"""x = x + self.pe[:, :x.size(1)]  # 添加位置编码return x# 示例
d_model = 512  # 嵌入维度
max_len = 50   # 最大序列长度
batch_size = 10  # 批量大小
seq_len = 20     # 序列长度# 创建位置编码层
pe = PositionalEncoding(d_model, max_len)# 随机生成输入张量
x = torch.randn(batch_size, seq_len, d_model)# 添加位置编码
x_with_pe = pe(x)
print(x_with_pe.shape)  # 输出: torch.Size([10, 20, 512])

二、为什么 Multi-Head Attention 没有改变 QKV 计算的参数量但对效果有提升?

2.1. Multi-Head Attention 的基本原理

Multi-Head Attention 是 Transformer 模型的核心组件之一,其核心思想是通过多个注意力头(Attention Head)并行计算注意力,然后将结果拼接起来。具体步骤如下:

  1. 线性变换:将输入 Q 、 K 、 V Q、K、V QKV 分别通过线性变换生成多个头的 Q i 、 K i 、 V i Q_i、K_i、V_i QiKiVi
  2. 并行计算:每个头独立计算注意力分数。
  3. 拼接和线性变换:将多个头的输出拼接起来,并通过线性变换得到最终输出。

2.2. 效果提升的原因

尽管参数量没有增加,但多头注意力对效果的提升主要来自以下几个方面:

(1)并行计算

  • 多个头可以并行计算注意力,捕捉输入序列中不同位置的不同特征。每个头可以关注不同的子空间,从而增强模型的表达能力。

(2)多视角学习

  • 每个头可以学习到不同的注意力模式(如局部依赖、全局依赖等)。通过拼接多个头的输出,模型可以综合多个视角的信息,提升泛化能力。

(3)特征多样性

  • 多头注意力可以捕捉输入序列中不同层次的特征(如语法、语义等)。这种多样性有助于模型更好地理解复杂的序列数据。

(4)计算效率

  • 虽然参数量没有增加,但多头注意力通过并行计算提高了计算效率。每个头的维度减小,减少了计算复杂度。

三、Word2Vec 的原理及损失函数定义

Word2Vec 是一种用于学习词向量的模型,其核心思想是通过上下文预测目标词(Skip-gram)或通过目标词预测上下文(CBOW)。Word2Vec 的目标是将每个词映射到一个低维稠密向量空间中,使得语义相似的词在向量空间中距离较近。

(1)Skip-gram 模型

  • 目标:给定一个中心词,预测其上下文词。
  • 输入:中心词。
  • 输出:上下文词的概率分布。

(2)CBOW 模型

  • 目标:给定上下文词,预测中心词。
  • 输入:上下文词。
  • 输出:中心词的概率分布。

3.2. Word2Vec 的损失函数

Word2Vec 的损失函数通常使用 负对数似然损失(Negative Log-Likelihood Loss),具体定义如下:

(1)Skip-gram 的损失函数

对于 Skip-gram 模型,损失函数定义为:
L = − 1 T ∑ t = 1 T ∑ − c ≤ j ≤ c , j ≠ 0 log ⁡ p ( w t + j ∣ w t ) L = -\frac{1}{T} \sum_{t=1}^{T} \sum_{-c \leq j \leq c, j \neq 0} \log p(w_{t+j} | w_t) L=T1t=1Tcjc,j=0logp(wt+jwt)
其中:

  • T T T:语料库中的总词数。
  • c c c:上下文窗口大小。
  • w t w_t wt:中心词。
  • w t + j w_{t+j} wt+j:上下文词。
  • p ( w t + j ∣ w t ) p(w_{t+j} | w_t) p(wt+jwt):给定中心词 w t w_t wt 时,上下文词 w t + j w_{t+j} wt+j 的条件概率。

(2)CBOW 的损失函数

对于 CBOW 模型,损失函数定义为:
L = − 1 T ∑ t = 1 T log ⁡ p ( w t ∣ w t − c , … , w t − 1 , w t + 1 , … , w t + c ) L = -\frac{1}{T} \sum_{t=1}^{T} \log p(w_t | w_{t-c}, \dots, w_{t-1}, w_{t+1}, \dots, w_{t+c}) L=T1t=1Tlogp(wtwtc,,wt1,wt+1,,wt+c)
其中:

  • T T T:语料库中的总词数。
  • c c c:上下文窗口大小。
  • w t w_t wt:中心词。
  • w t − c , … , w t + c w_{t-c}, \dots, w_{t+c} wtc,,wt+c:上下文词。
  • p ( w t ∣ w t − c , … , w t + c ) p(w_t | w_{t-c}, \dots, w_{t+c}) p(wtwtc,,wt+c):给定上下文词时,中心词 w t w_t wt 的条件概率。

(3)条件概率的计算

条件概率 p ( w O ∣ w I ) p(w_O | w_I) p(wOwI) 通过 Softmax 函数计算:
p ( w O ∣ w I ) = exp ⁡ ( v w O T v w I ) ∑ w = 1 V exp ⁡ ( v w T v w I ) p(w_O | w_I) = \frac{\exp(v_{w_O}^T v_{w_I})}{\sum_{w=1}^{V} \exp(v_w^T v_{w_I})} p(wOwI)=w=1Vexp(vwTvwI)exp(vwOTvwI)
其中:

  • v w I v_{w_I} vwI:输入词 w I w_I wI 的向量表示。
  • v w O v_{w_O} vwO:输出词 w O w_O wO 的向量表示。
  • V V V:词汇表大小。

3. 负采样(Negative Sampling)

由于 Softmax 的计算复杂度较高(与词汇表大小 V V V 成正比),Word2Vec 通常使用负采样(Negative Sampling)来近似损失函数。负采样的损失函数定义为:
L = − log ⁡ σ ( v w O T v w I ) − ∑ i = 1 k log ⁡ σ ( − v w i T v w I ) L = -\log \sigma(v_{w_O}^T v_{w_I}) - \sum_{i=1}^{k} \log \sigma(-v_{w_i}^T v_{w_I}) L=logσ(vwOTvwI)i=1klogσ(vwiTvwI)
其中:

  • σ \sigma σ:Sigmoid 函数。
  • k k k:负样本的数量。
  • w i w_i wi:负样本词。

四、为什么可以通过负采样近似 Softmax?

4.1. Softmax 的计算复杂度问题

Softmax 函数的计算复杂度为 O ( V ) O(V) O(V),其中 V V V 是词汇表的大小。对于大规模词汇表(如数百万词),Softmax 的计算成本非常高,主要体现在:

  • 计算指数:需要对每个词计算指数。
  • 归一化:需要对所有词的指数求和,然后归一化。

4.2. 负采样的基本思想

负采样(Negative Sampling)是一种近似 Softmax 的方法,通过采样少量负样本来替代全词汇表的计算。其核心思想是:

  • 正样本:目标词(实际出现在上下文中的词)。
  • 负样本:随机采样的非目标词(未出现在上下文中的词)。
  • 目标:最大化正样本的概率,最小化负样本的概率。

4.3. 负采样的数学原理

(1)Softmax 的原始形式

Softmax 的条件概率定义为:
p ( w O ∣ w I ) = exp ⁡ ( v w O T v w I ) ∑ w = 1 V exp ⁡ ( v w T v w I ) p(w_O | w_I) = \frac{\exp(v_{w_O}^T v_{w_I})}{\sum_{w=1}^{V} \exp(v_w^T v_{w_I})} p(wOwI)=w=1Vexp(vwTvwI)exp(vwOTvwI)
其中:

  • v w I v_{w_I} vwI:输入词 w I w_I wI的向量表示。
  • v w O v_{w_O} vwO:输出词 w O w_O wO 的向量表示。
  • V V V:词汇表大小。

(2)负采样的近似形式

负采样通过采样少量负样本 w i w_i wi 来近似 Softmax 的分母。具体步骤如下:

  1. 正样本:计算正样本的概率:
    σ ( v w O T v w I ) \sigma(v_{w_O}^T v_{w_I}) σ(vwOTvwI)
    其中 σ \sigma σ是 Sigmoid 函数。
  2. 负样本:计算负样本的概率:
    σ ( − v w i T v w I ) \sigma(-v_{w_i}^T v_{w_I}) σ(vwiTvwI)
  3. 损失函数:将正样本和负样本的概率结合起来,定义损失函数:
    L = − log ⁡ σ ( v w O T v w I ) − ∑ i = 1 k log ⁡ σ ( − v w i T v w I ) L = -\log \sigma(v_{w_O}^T v_{w_I}) - \sum_{i=1}^{k} \log \sigma(-v_{w_i}^T v_{w_I}) L=logσ(vwOTvwI)i=1klogσ(vwiTvwI)
    其中 k k k 是负样本的数量。

(3)为什么可以近似?

  • 分母的近似:Softmax 的分母是对所有词的指数求和,计算复杂度高。负采样通过采样少量负样本,近似计算分母(但是牺牲精度)。

五、召回的评价指标

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/72697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫【爬虫库urllib】

我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 urllib介绍 Urllib是Python自带的标准库,无须安装,直接引用即可。 Urllib是一个收集几个模块来使用URL的软件包,大致具备以下功能。 ● urlli…

LabVIEW棉花穴播器排种自动监测系统

一、项目背景与行业痛点 1. 农业需求驱动 我国棉花主产区,种植面积常年超250万公顷,传统人工播种存在两大核心问题: 效率瓶颈:人均日播种面积不足0.5公顷,难以匹配规模化种植需求; 精度缺陷:人…

解决diffusers加载stablediffusion模型,输入prompt总是报错token数超出clip最大长度限制

1. StableDiffusion1.5 在加载huggingface中的扩散模型时,输入prompt总是会被报错超过clip的最大长度限制。 解决方案:使用compel库 from diffusers import AutoPipelineForText2Image import torch import pdb from compel import Compeldevice torc…

jmeter配件元素

jmeter配件元素 CSV Data Set Config名词解释测试场景Recycle on EOF:False配置测试结果 Recycle on EOF:True配置测试结果 Sharing mode:All Threads配置测试结果 Sharing mode:Current thread group配置测试结果 Sharing mode:Current thread配置测试结果 HTTP Header Manage…

Navicat SqlServer 设置自增主键

Navicat是一款优秀的数据库管理工具&#xff0c;可以连接很多类型的数据库。使用它可以极大的提高工作效率。 Navicat 不能设置SqlServer自增字段&#xff0c;只能通过sql语句来实现 建表时设置 create table <表名> ( <字段1-主键> int identity (1,1) primar…

Elasticsearch搜索引擎 3(DSL)

Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;语句来定义查询条件&#xff0c;其JavaAPI就是在组织DSL条件。 1.DSL查询 叶子查询&#xff08;Leaf query clauses&#xff09;&#xff1a;在特定的字段里查询特定值&#xff0c;属于简单…

final 在 java 中有什么作用?

final 在 java 中有什么作用&#xff1f; 修饰变量 修饰基本数据类型变量&#xff1a; 当用final修饰基本数据类型变量时&#xff0c;该变量就变成了常量&#xff0c;其值在初始化后不能被改变。 final int num 10; // num 20; // 这行代码会导致编译错误&#xff0c;因…

Dubbo/Hession2序列化Immutable类型的集合异常问题

问题排查 根据堆栈信息可见&#xff0c;dubbo使用默认的hession2进行序列化时出现了异常&#xff0c;异常堆栈根原因为&#xff1a;null array 位于java.util.CollSer#readResolve方法中&#xff0c;即在序列化集合时&#xff0c;集合数组为空。 向上追溯jdk.internal.ref…

目标检测任务,如何区分两个相近似的目标

首先&#xff0c;要了解清楚检测的场景下&#xff0c;肉眼能否区分出目标的差异性。 如果可以区分&#xff0c;那观察数据周围背景的差异是否较大&#xff0c;可以先通过添加样本来提升模型的检测精度。添加样本时一定要注意&#xff0c;样本标注的准确性&#xff0c;样本的丰…

Java面试黄金宝典1

1. 8 种基本数据类型 整数类型 byte&#xff1a; 它是最小的整数类型&#xff0c;占用 1 个字节&#xff08;8 位&#xff09;。在一些对内存使用要求极高的场景&#xff0c;比如嵌入式系统开发、数据传输时对数据量有严格限制的情况&#xff0c;会使用 byte 类型。例如&#x…

OSGEarth

OSGEarth 基于 OpenSceneGraph 构建的一个扩展库&#xff0c;专门用于地球科学和地理信息系统&#xff08;GIS&#xff09;数据的可视化。它允许开发者创建逼真的三维地球模型&#xff0c;并在其上展示各种地理空间数据。 高端一点的表述 基于三维引擎osg开发的三维数字地球…

Word 小黑第34套

对应大猫34 设置第二页水印&#xff0c;取消第一页的&#xff1a;取消第二页页眉链接&#xff0c;删除第一张水印图片&#xff08;delete&#xff09; 调整水印图片&#xff1a;点开页眉页脚 双击图片 可以调整 邮件合并 -创建标签 横标签数3 竖标签5 表布局 -查看网格线 插…

2.5.1 io_uring

文章目录 2.5.1 io_uring1. 对比1. select、poll、epoll 对比表格2. 关键特性说明&#xff1a;3. 应用场景 2. 异步io1. 频繁copy2. 如何做到线程安全 3. io_uring1. 实现2. 关键点&#xff1a;3. 问题1. Reactor 与 Proactor 的三点不同2. epoll 与 io_uring 的区别 2.5.1 io_…

K8S学习之基础三十六:node-exporter部署

Prometheus v2.2.1 ​ 编写yaml文件&#xff0c;包含创建ns、configmap、deployment、service # 创建monitoring空间 vi prometheus-ns.yaml apiVersion: v1 kind: Namespace metadata:name: monitoring# 创建SA并绑定权限 kubectl create serviceaccount monitor -n monito…

为什么“连接断开可能导致锁未释放”

目录 两种典型场景可能导致锁未及时释放1. **数据库未及时检测到连接断开**2. **应用程序未正确处理事务** 为什么说“可能因连接断开导致死锁”&#xff1f;如何避免此类问题&#xff1f;总结 在大多数数据库实现中&#xff0c;如果持有锁的连接&#xff08;或会话&#xff09…

【实战指南】基于DevExpress轻量化主题实现WPF应用性能升级

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

【C++多线程】C++异步线程池提交任务的写法和解释

// 提交任务到线程池 template<class F, class... Args> auto ThreadPool::enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {using return_type typename std::result_of<F(Args...)>…

CSS 属性选择器详解

CSS 属性选择器详解 引言 CSS(层叠样式表)是网页设计中的重要组成部分,它用于控制网页元素的样式和布局。属性选择器是CSS选择器的一种,它允许开发者根据元素的特定属性来选择和样式化元素。本文将详细讲解CSS属性选择器的概念、语法以及常用属性选择器的使用方法。 一、…

二维前缀矩阵

1.大衣的旅行 #include<bits/stdc.h> #define int long long using namespace std; int t; int n,m,k; bool check(int mid,vector<vector<int>>pre,vector<vector<int>>a) {for(int i1; i<n; i){for(int j1; j<m; j){//枚举以老师房间为…

python-leetcode 56.电话号码的字母组合

题目&#xff1a; 给定一个仅包含数字的2-9的字符串&#xff0c;返回所有它可能表示的字母组合&#xff0c;答案可以按任意顺序返回 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;&#xff0c;注意1不对应任何字母 方法一&#xff1a;深度优先搜索&#x…