【AI知识片段】Transformer模型中的位置编码

news/2024/7/8 4:39:37 标签: 人工智能

1.什么是位置编码

 位置编码描述序列中实体的位置或位置,以便为每个位置分配唯一的表示形式。单个数字(如索引值)不用于表示项目在转换器模型中的位置的原因有很多。对于长序列,索引的量级可能会变大。如果将索引值归一化为介于 0 和 1 之间,则可能会对可变长度序列产生问题,因为它们的归一化方式会有所不同。

转换器使用智能位置编码方案,其中每个位置/索引都映射到一个向量。因此,位置编码层的输出是一个矩阵,其中矩阵的每一行表示序列的一个编码对象,该序列与其位置信息相加。仅对位置信息进行编码的矩阵示例如下图所示。

2.位置编码的原理

三角正弦函数的回顾

函数的范围是 [-1,+1]。该波形的频率是在一秒钟内完成的周期数。波长是波形重复的距离。不同波形的波长和频率如下所示:

 Transformer中的位置编码

假设您有一个长度 L 的输入序列,并且需要 对象在此序列中的位置。位置编码由不同频率的正弦和余弦函数给出:

  • k:对象在输入序列中的位置,0<=k<L/2
  • d: 输出嵌入空间的维度
  • P(k,j): 位置函数,用于映射输入序列中k处的元素到位置矩阵的(k,j)处
  • n:用户定义的标量,由 Attention Is All You Need 的作者设置为 10,000。
  • i: 用于映射到列索引,0<=i<d/2,单个值i映射到正弦和余弦函数

 为了理解上面的表达式,让我们以 n=100 和 d=4 的短语“I am a robot”为例。 下表显示了该短语的位置编码矩阵。 事实上,位置编码矩阵对于任何 n=100 和 d=4 的四字母短语都是相同的。

 

3.代码实现位置编码矩阵

import numpy as np
import matplotlib.pyplot as plt

def getPositionEncoding(seq_len, d, n=10000):
    P = np.zeros((seq_len, d))
    for k in range(seq_len):
        for i in np.arange(int(d/2)):
            denominator = np.power(n, 2*i/d)
            P[k, 2*i] = np.sin(k/denominator)
            P[k, 2*i+1] = np.cos(k/denominator)
    return P

P = getPositionEncoding(seq_len=4, d=4, n=100)
print(P)

 结果

[[ 0.          1.          0.          1.        ]
 [ 0.84147098  0.54030231  0.09983342  0.99500417]
 [ 0.90929743 -0.41614684  0.19866933  0.98006658]
 [ 0.14112001 -0.9899925   0.29552021  0.95533649]]

4.理解并可视化位置编码矩阵

 要理解位置编码,让我们从查看 n=10,000 和 d=512 的不同位置的正弦波开始。

def plotSinusoid(k, d=512, n=10000):
    x = np.arange(0, 100, 1)
    denominator = np.power(n, 2*x/d)
    y = np.sin(k/denominator)
    plt.plot(x, y)
    plt.title('k = ' + str(k))

fig = plt.figure(figsize=(15, 4))    
for i in range(4):
    plt.subplot(141 + i)
    plotSinusoid(i*4)

下图是上面代码的输出:

 可以看到每个位置对应于不同的正弦曲线,它将单个位置编码为向量。 如果仔细观察位置编码函数,你会发现固定i时对应的波长:

因此,正弦曲线的波长形成几何级数。并且从2Π到2Πn变化, 位置编码方案具有许多优点。

  • 正弦和余弦函数的值在 [-1, 1] 内,这使位置编码矩阵的值保持在归一化范围内。
  • 由于每个位置的正弦曲线都不同,因此你可以采用独特的方式对每个位置进行编码。
  • 有一种方法可以测量或量化不同位置之间的相似性,从而使你能够对单词的相对位置进行编码。

可视化位置矩阵

 让我们在更大的值上可视化位置矩阵。使用库中的 matplotlib Python matshow() 方法。按照原始论文中所做的设置 n=10,000,您将得到以下内容:

P = getPositionEncoding(seq_len=100, d=512, n=10000)
cax = plt.matshow(P)
plt.gcf().colorbar(cax)

位置编码层位置向量单词编码相加,并为后续层输出此矩阵。整个过程如下所示。 

 

参考链接

 A Gentle Introduction to Positional Encoding in Transformer Models, Part 1 - MachineLearningMastery.com


http://www.niftyadmin.cn/n/5339499.html

相关文章

双通道5V高细分步进电机——GC6129,可替代MS41929,具有低噪声、低振动的特点

GC6129是双通道5V低电压步进电机驱动器&#xff0c;具有低噪声、低振动的特点&#xff0c;特别适用于相机的变焦和对焦系统&#xff0c;万向节和其他精密&#xff0c;低噪声STM控制系统。该芯片为每个通道集成了256微步驱动器带SPI接口&#xff0c;用户可以方便地调整驱动器的参…

【 CSS 】基础 2

“生活就像骑自行车&#xff0c;想要保持平衡&#xff0c;就得不断前行。” - 阿尔伯特爱因斯坦 CSS 基础 2 1. emmet 语法 1.1 简介 Emmet语法的前身是 Zen coding&#xff0c;它使用缩写&#xff0c;来提高 HTML / CSS 的编写速度&#xff0c; VSCode 内部已经集成该语法。…

本地仓库如何与远程仓库进行关联

目录 设置Git 全局设置: 创建一个远程仓库 创建本地仓库 连接远程仓库 查看远程仓库origin的关联信息 查看所有远程仓库 切换远程仓库 设置Git 全局设置: git config --global user.name "your name" git config --global user.email "your email163.co…

使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook&#xff0c;并结合cpolar内网穿透…

uniapp页面跳转的几种方式 以及举例(2)

又来混时长 嫖流量卷了 一,uni.navigateTo(OBJECT) 保留当前页面&#xff0c;跳转到应用内的某个页面&#xff0c;使用uni.navigateBack可以返回到原页面。 // 1.不传参 uni.navigateTo({url:./home/index }); // 2.传参字符串 uni.navigateTo({url:./home/index?title${tit…

Spring-简介

在向读者描述Spring时&#xff0c;笔者不打算从某处粘贴一段常见的概念性文字糊弄完本专栏的第一篇文章&#xff0c;而是用易于理解的话向读者指出几个重点。 &#xff08;1&#xff09;是框架。何谓框架&#xff1f;就像搭房子一样&#xff0c;框架就如同是墙体结构&#xff…

Opencv小项目——手势数字刷TIKTOK

​ 写在前面&#xff1a; 很久没更新了&#xff0c;之前的实习的记录也算是烂尾了&#xff0c;但是好在自己的实习记录还是有的&#xff0c;最近也忙碌了很多&#xff0c;终于放假了&#xff0c;今天下午正好没事&#xff0c;闲来无事就随便做个小玩意吧。 思来想去&#xff…

04.Timer应用

Timer应用与源码 1.Timer介绍 java.util包下提供了对定时任务的支持&#xff0c;在JDK很早的版本就支持了&#xff0c;但是由于一些问题被逐渐淘汰了&#xff0c;现在建议使用ScheduledThreadPoolExecutor来代替Timer 2.Timer使用Demo /*** description: 测试Timer* author…