Transformer step by step--Positional Embedding 和 Word Embedding

Transformer step by step往期文章:

Transformer step by step--层归一化和批量归一化 

要把Transformer中的Embedding说清楚,那就要说清楚Positional EmbeddingWord Embedding。至于为什么有这两个Embedding,我们不妨看一眼Transformer的结构图。

从上图可以看到,我们的输入需要在Input EmbeddingPositional Encoding的共同作用下才会分别输入给EncoderDecoder,所以我们就分别介绍一下怎么样进行Input EmbeddingPositional Encoding

同时为了帮助大家更好地理解这两种Embedding方式,我们这里生成一个自己的迷你数据集。

import tiktoken
import torch
import torch.nn as nn
encoding = tiktoken.get_encoding("cl100k_base") #导入openai的开源tokenizer库
context_length = 4 #选取4个token
batch = 4 # 批处理大小
example_text1 = "I am now writing an example to show the usage of word embedding."
example_text2 = "I am now writing an sentence to show the usage of another word embedding."
total_text = example_text1 + example_text2 #形成总数据集
tokenize_text = encoding.encode(total_text) #进行tokenize
tokenize_text = torch.tensor(tokenize_text, dtype=torch.long) #这里转换成tentor是因为后续我们要用pytorch的框架
idxs = torch.randint(low = 0,high = len(tokenize_text) - context_length,size = (batch,))#这里我们随机选batch个id
x_batch = torch.stack([tokenize_text[idx:idx + context_length] for idx in idxs]) #根据id和context_length抽取训练数据

一、Word Embedding

这里的Word Embedding就是论文中提到的Input Embedding。我们在之前的文章中已经介绍使用tokenizer将原始的文本信息转换为数字,便于输入进模型。 可是使用tokenizer有一个问题,这个问题就是我们虽然用不同的ID表示了不同的子词,但是这些ID所能蕴含的语义信息非常有限,比如dog和dogs这两个单词语义非常相近,但很有可能它们的ID相隔非常远,所以为了更好地体现不同单词之间的语义关系,我们将每个ID通过Word Embedding的方式变为一个向量。

这里的实现在Pytorch框架之下变得非常简单,只需要一行代码就可以搞定,但是我们这里还是详细对代码的参数进行一些讲解。

max_token_value = tokenize_text.max().item()
d_model = 16
input_embedding_lookup_table = nn.Embedding(max_token_value + 1, d_model)
x_batch_embedding = input_embedding_lookup_table(x_batch)
print(max_token_value)
#
40188

这里的第一、二行我们一起讲:

max_token_value = tokenize_text.max().item()是取出当前token中ID最大的那个数。

input_embedding_lookup_table = nn.Embedding(max_token_value + 1, d_model)是根据最大的ID去构建Embedding层。

首先第一个问题,nn.Embedding的两个参数是什么意思?

首先第一个参数我们这里使用的是 max_token_value + 1,这个是用来表示我们词汇库的最大长度。那这里可能又有一个新的问题,就是我们上面的句子,算上标点符号一共也就十几个词,为什么我们这里要用40188+1作为这个词汇库的最大长度呢?这是因为我们这里用的tokenizer是openai的第三方库,这个库在做tokenize的时候对应着大量的原始文本,而我们example_text中的文本在经过tokenize之后,最大的token ID对应的是这个库中的原始文本的40188。那么这里还有第二个问题,这里返回的是40188,我们为什么要加上1呢?因为tokenize之后的ID是从0开始算的,也就是说40188对应的词汇表的最大长度应该是40189。

第二个参数我们使用的是d_model,这个参数会好理解一些。我们之前说过,一个ID没有什么语义信息,但变成向量之后就可以通过余弦相似度计算两个向量之间的相关性。那么这里的一个问题就在于,我用多少维的向量去表示呢?d_model这个参数就是来解决这个事情,我们想让ID变成多少维的向量,就把d_model设置成多少。

那么第三行,就是我们讲原来形状为4 * 4的x_batch变为了4 * 4 * 16 的x_batch_embedding。后面多出来的16就是我们自己设置的嵌入的维度。

二、Positional Embedding

总体来说,word_embedding还是比较通俗易懂的,接下来我们根据论文当中的公式去写一下Positional Encoding,也就是Positional Embedding(同一个意思)。

这里我们解释一下这两行公式啥意思,Positional Embedding简单来说,就是给每个token分配一个位置信息,因为 𝑠𝑒𝑙𝑓 - 𝑎𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛 本身无法判断不同token所在的位置。PE对应Positional Encoding的缩写,括号中的pos对应我们设置的context length的长度,2i对应嵌入维度中的偶数维度,2i+1对应嵌入维度中的奇数维度。

接下来我们就来实现一下相关的代码:

positional_encoding = torch.zeros(context_length, d_model) #首先初始化一个和token形状大小一样的positional encoding
positional = torch.arange(0, context_length).float().unsqueeze(1) #按照我们设置的context length去初始化position
_2i = torch.arange(0, d_model, 2) # 这里用生成d_model/2的步长,因为sin和cos两个加起来就变成了d_model
positional_encoding[:, 0::2] = torch.sin(torch.exp(positional/10000**(_2i/d_model))) #按照公式写一遍
positional_encoding[:, 1::2] = torch.cos(torch.exp(positional/10000**(_2i/d_model)))
positional_encoding = positional_encoding.squeeze(0).expand(batch, -1, -1) #最终根据batch的数量对维度进行扩充
input_x = x_batch_embedding + positional_encoding # 将word embedding和positional embedding相加得到模型的输入
print(positional_encoding.shape)
print(input_x.shape)
##
torch.Size([4, 4, 16]) 
torch.Size([4, 4, 16]) 

到这里,我们也就完成了两个embedding操作。

知乎原文链接:安全验证 - 知乎知乎,中文互联网高质量的问答社区和创作者聚集的原创内容平台,于 2011 年 1 月正式上线,以「让人们更好的分享知识、经验和见解,找到自己的解答」为品牌使命。知乎凭借认真、专业、友善的社区氛围、独特的产品机制以及结构化和易获得的优质内容,聚集了中文互联网科技、商业、影视、时尚、文化等领域最具创造力的人群,已成为综合性、全品类、在诸多领域具有关键影响力的知识分享社区和创作者聚集的原创内容平台,建立起了以社区驱动的内容变现商业模式。icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/691169616

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

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

相关文章

Hadoop之路

hadoop更适合在liunx环境下运行,会节省后期很多麻烦,而用虚拟器就太占主机内存了,因此后面我们将把hadoop安装到wsl后进行学习,后续学习的环境是Ubuntu-16.04 (windows上如何安装wsl) 千万强调,有的命令一…

【24年物联网华为杯】赛题分析与初步计划

赛事介绍 官网链接:2024 年全国大学生物联网设计竞赛 (sjtu.edu.cn) 含金量:属于A类赛事 (注意:很多搜索结果的序号是按照选入时间排列的,与含金量无关,华为杯是23年选入的) Kimi Chat: 全国…

JavaScript创建和填充数组的更多方法

空数组fill()方法创建并填充数组 ● 我们之前创建数组的方式都是手动去创建去一个数据,例如 console.log([1, 2, 3, 4, 5, 6, 7]);● 当然我们也可以使用Array对象来构造数组 console.log([1, 2, 3, 4, 5, 6, 7]); console.log(new Array(1, 2, 3, 4, 5, 6, 7));…

Java毕业设计 基于SpringBoot vue城镇保障性住房管理系统

Java毕业设计 基于SpringBoot vue城镇保障性住房管理系统 SpringBoot 城镇保障性住房管理系统 功能介绍 首页 图片轮播 房源信息 房源详情 申请房源 公示信息 公示详情 登录注册 个人中心 留言反馈 后台管理 登录 个人中心 修改密码 个人信息 用户管理 房屋类型 房源信息管理…

【算法基础实验】图论-UnionFind连通性检测之quick-find

Union-Find连通性检测之quick-find 理论基础 在图论和计算机科学中,Union-Find 或并查集是一种用于处理一组元素分成的多个不相交集合(即连通分量)的情况,并能快速回答这组元素中任意两个元素是否在同一集合中的问题。Union-Fin…

【React】Sigma.js框架网络图-入门篇(2)

通过《【React】Sigma.js框架网络图-入门篇》有了基本认识 由于上一篇直接给出了基本代码示例,可能看着比较复杂也不知道是啥意思; 今天从理论入手重新认识下! 一、基本认识 首先,我们先了解下基础术语: 图(Graph)&…

随笔 | 宿舍矛盾

室友A:睡觉时间比较早 室友B:睡觉时间比较晚,起床时间也晚 室友C:睡的晚,起的早 我:睡的时间随机,起的较早 事件1: 某一个星期四的中午,我正在听歌。室友C跟我说:我们去打扫卫生吧。于是&am…

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架,用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式,并且可以轻松添加新的输出格式。 CppTest下载地址:下载地址1  下载地址2 下面结合实例分析下CppTest如…

【Linux网络】FTP服务

目录 一、FTP简介 1.FTP-文件传输协议 2.FTP的两种模式 二、安装配置FTP 1.安装环境 2.对文件的操作 3.切换目录 4.设置匿名用户 5.图形化界面登录 6.白名单与黑名单 重点与难点 一、FTP简介 1.FTP-文件传输协议 FTP是FileTransferProtocol(文件传输协…

【论文笔记 | 异步联邦】PORT:How Asynchronous can Federated Learning Be?

1. 论文信息 How Asynchronous can Federated Learning Be?2022 IEEE/ACM 30th International Symposium on Quality of Service (IWQoS). IEEE, 2022,不属于ccf认定 2. introduction 2.1. 背景: 现有的异步FL文献中设计的启发式方法都只反映设计空…

php反序列化字符串逃逸

字符串逃逸 字符串逃逸是通过改变序列化字符串的长度造成的php反序列化漏洞 一般是因为替换函数使得字符串长度发生变化,不论变长还是变短,原理都大致相同 在学习之前,要先了解序列化字符串的结构,在了解结构的基础上才能更好理解…

ASP.NET某企业信息管理系统的设计与实现

摘 要 信息管理系统就是我们常说的MIS(Management Information System),它是一个计算机软硬件资源以及数据库的人-机系统。经过对题目和内容的分析,选用了Microsoft公司的ASP.NET开发工具,由于它提供了用于从数据库中访问数据的强大工具集,使用它可以建立开发比较完善的数据库…

汽车底盘域的学习笔记

前言:底盘域分为传统车型底盘域和新能源车型底盘域(新能源系统又可以分为纯电和混动车型,有时间可以再研究一下) 1:传统车型底盘域 细分的话可以分为四个子系统 传动系统 行驶系统 转向系统 制动系统 1.1传动系…

第29天:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作

第二十九天 一、JS技术-DOM树操作及安全隐患 1.DOM:文档操作对象 获取HTML代码中函数的值,可以操作网页代码内容,实现自主或用户交互动作反馈 安全问题:本身的前端代码通过DOM技术实现代码的更新修改,但是更新修改如…

鸿蒙APP开发页面组件之间的属性关系

我们将对于多页面以及更多有趣的功能展开叙述,这次我们对于 HarmonyOS 的很多有趣常用组件并引出一些其他概念以及解决方案、页面跳转传值、生命周期、启动模式(UiAbility),样式的书写、状态管理以及动画等方面进行探讨 页面之间…

Web前端一套全部清晰 ③ day2 HTML 标签综合案例

别让平淡生活&#xff0c;耗尽所有向往 —— 24.4.26 综合案例 —— 一切都会好的 网页制作思路&#xff1a;从上到下&#xff0c;先整体到局部&#xff0c;逐步分析制作 分析内容 ——> 写代码 ——>保存——>刷新浏览器&#xff0c;看效果 <!DOCTYPE html> &l…

OSPF域间路由

注&#xff1a;区域&#xff08;area&#xff09;是以接口进行划分的 描述&#xff1a; R1的g0/0/1接口属于area 0 √ R1属于区域0和区域1 1.设计原则 1、OSPF区域的设计原则&#xff1a; 骨干区域有且只能存在一个 非骨干区域必须和骨干区域相连 多区域时&#…

SystemUI KeyButtonView setDarkIntensity 解析

继承自 ImageView KeyButtonDrawable intensity为0时按键颜色为白色。 intensity为1时黑色为的调用堆栈&#xff1a; java.lang.NullPointerException: Attempt to invoke virtual method int java.lang.String.length() on a null object referenceat com.android.systemui.…

【JAVA】UDP与TCP套接字编程

目录 一、UDP数据报套接字编程 1、DatagramSocket API 2、DatagramPacket API 3、InetSocketAddress API 4、示例一 5、示例二 二、TCP流套接字编程 1、ServerSocket API 2、Socket API 3、TCP中的长短连接 4、示例一 5、示例二 一、UDP数据报套接字编程 1、Datag…

施耐德 Unity Pro 编程软件导入导出变量

适用范围 施耐德中高端PLC&#xff0c;使用的编程软件为 UnityPro &#xff08;最新版更名为 Ecostructure Control Expert&#xff09; 中端 PLC&#xff1a;Premium&#xff0c;M340高端 PLC&#xff1a;Quantum&#xff0c;M580 导出/导入变量 导出变量可导出【变量和 FB…