我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Pytorch从0实现Transformer的实践

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Pytorch从0实现Transformer的实践

摘要

With the continuous development of time series prediction, Transformer-like models have gradually replaced traditional models in the fields of CV and NLP by virtue of their powerful advantages. Among them, the Informer is far superior to the traditional RNN model in long-term prediction, and the Swin Transformer is significantly stronger than the traditional CNN model in image recognition. A deep grasp of Transformer has become an inevitable requirement in the field of artificial intelligence. This article will use the Pytorch framework to implement the position encoding, multi-head attention mechanism, self-mask, causal mask and other functions in Transformer, and build a Transformer network from 0.

随着时序预测的不断发展,Transformer类模型凭借强大的优势,在CV、NLP领域逐渐取代传统模型。其中Informer在长时序预测上远超传统的RNN模型,Swin Transformer在图像识别上明显强于传统的CNN模型。深层次掌握Transformer已经成为从事人工智能领域的必然要求。本文将用Pytorch框架,实现Transformer中的位置编码、多头注意力机制、自掩码、因果掩码等功能,从0搭建一个Transformer网络。

一、构造数据

1.1 句子长度

# 关于word embedding,以序列建模为例
# 输入句子有两个,第一个长度为2,第二个长度为4
class="lazy" data-src_len = torch.tensor([2, 4]).to(torch.int32)
# 目标句子有两个。第一个长度为4, 第二个长度为3
tgt_len = torch.tensor([4, 3]).to(torch.int32)
print(class="lazy" data-src_len)
print(tgt_len)

输入句子(class="lazy" data-src_len)有两个,第一个长度为2,第二个长度为4
目标句子(tgt_len)有两个。第一个长度为4, 第二个长度为3

1.2 生成句子

用随机数生成句子,用0填充空白位置,保持所有句子长度一致

class="lazy" data-src_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, max_num_class="lazy" data-src_words, (L, )), (0, max(class="lazy" data-src_len)-L)), 0) for L in class="lazy" data-src_len])
tgt_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, max_num_tgt_words, (L, )), (0, max(tgt_len)-L)), 0) for L in tgt_len])
print(class="lazy" data-src_seq)
print(tgt_seq)

class="lazy" data-src_seq为输入的两个句子,tgt_seq为输出的两个句子。
为什么句子是数字?在做中英文翻译时,每个中文或英文对应的也是一个数字,只有这样才便于处理。

1.3 生成字典

在该字典中,总共有8个字(行),每个字对应8维向量(做了简化了的)。注意在实际应用中,应当有几十万个字,每个字可能有512个维度。

# 构造word embedding
class="lazy" data-src_embedding_table = nn.Embedding(9, model_dim)
tgt_embedding_table = nn.Embedding(9, model_dim)
# 输入单词的字典
print(class="lazy" data-src_embedding_table)
# 目标单词的字典
print(tgt_embedding_table)

字典中,需要留一个维度给class token,故是9行。

1.4 得到向量化的句子

通过字典取出1.2中得到的句子

# 得到向量化的句子
class="lazy" data-src_embedding = class="lazy" data-src_embedding_table(class="lazy" data-src_seq)
tgt_embedding = tgt_embedding_table(tgt_seq)
print(class="lazy" data-src_embedding)
print(tgt_embedding)

该阶段总程序

import torch
# 句子长度
class="lazy" data-src_len = torch.tensor([2, 4]).to(torch.int32)
tgt_len = torch.tensor([4, 3]).to(torch.int32)
# 构造句子,用0填充空白处
class="lazy" data-src_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, 8, (L, )), (0, max(class="lazy" data-src_len)-L)), 0) for L in class="lazy" data-src_len])
tgt_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, 8, (L, )), (0, max(tgt_len)-L)), 0) for L in tgt_len])
# 构造字典
class="lazy" data-src_embedding_table = nn.Embedding(9, 8)
tgt_embedding_table = nn.Embedding(9, 8)
# 得到向量化的句子
class="lazy" data-src_embedding = class="lazy" data-src_embedding_table(class="lazy" data-src_seq)
tgt_embedding = tgt_embedding_table(tgt_seq)
print(class="lazy" data-src_embedding)
print(tgt_embedding)

二、位置编码

位置编码是transformer的一个重点,通过加入transformer位置编码,代替了传统RNN的时序信息,增强了模型的并发度。位置编码的公式如下:(其中pos代表行,i代表列)

2.1 计算括号内的值

# 得到分子pos的值
pos_mat = torch.arange(4).reshape((-1, 1))
# 得到分母值
i_mat = torch.pow(10000, torch.arange(0, 8, 2).reshape((1, -1))/8)
print(pos_mat)
print(i_mat)

2.2 得到位置编码

# 初始化位置编码矩阵
pe_embedding_table = torch.zeros(4, 8)
# 得到偶数行位置编码
pe_embedding_table[:, 0::2] =torch.sin(pos_mat / i_mat)
# 得到奇数行位置编码
pe_embedding_table[:, 1::2] =torch.cos(pos_mat / i_mat)
pe_embedding = nn.Embedding(4, 8)
# 设置位置编码不可更新参数
pe_embedding.weight = nn.Parameter(pe_embedding_table, requires_grad=False)
print(pe_embedding.weight)

三、多头注意力

3.1 self mask

有些位置是空白用0填充的,训练时不希望被这些位置所影响,那么就需要用到self mask。self mask的原理是令这些位置的值为无穷小,经过softmax后,这些值会变为0,不会再影响结果。

3.1.1 得到有效位置矩阵

# 得到有效位置矩阵
vaild_encoder_pos = torch.unsqueeze(torch.cat([torch.unsqueeze(F.pad(torch.ones(L), (0, max(class="lazy" data-src_len) - L)), 0)for L in class="lazy" data-src_len]), 2)
valid_encoder_pos_matrix = torch.bmm(vaild_encoder_pos, vaild_encoder_pos.transpose(1, 2))
print(valid_encoder_pos_matrix)

3.1.2 得到无效位置矩阵

invalid_encoder_pos_matrix = 1-valid_encoder_pos_matrix
mask_encoder_self_attention = invalid_encoder_pos_matrix.to(torch.bool)
print(mask_encoder_self_attention)

True代表需要对该位置mask

在这里插入图片描述

3.1.3 得到mask矩阵
用极小数填充需要被mask的位置

# 初始化mask矩阵
score = torch.randn(2, max(class="lazy" data-src_len), max(class="lazy" data-src_len))
# 用极小数填充
mask_score = score.masked_fill(mask_encoder_self_attention, -1e9)
print(mask_score)

算其softmat

mask_score_softmax = F.softmax(mask_score)
print(mask_score_softmax)

可以看到,已经达到预期效果

到此这篇关于Pytorch从0实现Transformer的实践的文章就介绍到这了,更多相关Pytorch Transformer内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Pytorch从0实现Transformer的实践

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Pytorch怎么实现Transformer

本篇内容主要讲解“Pytorch怎么实现Transformer”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Pytorch怎么实现Transformer”吧!一、构造数据1.1 句子长度# 关于
2023-06-30

PyTorch中的Transformer模型是如何实现的

在PyTorch中,Transformer模型主要由以下几个部分组成:Encoder:包括多个Encoder层,每个Encoder层由多头自注意力机制和前馈神经网络组成。Encoder的作用是将输入的序列进行特征提取和编码。Decoder:
PyTorch中的Transformer模型是如何实现的
2024-03-05

React18从0实现dispatchupdate流程

这篇文章主要为大家介绍了React18从0实现dispatchupdate流程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-16

React18系列reconciler从0实现过程详解

这篇文章主要介绍了React18系列reconciler从0实现过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-16

React18系列commit从0实现源码解析

这篇文章主要为大家介绍了React18系列commit从0实现源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-16

架构演进实践:从0到4000高并发请求背后的努力!

来自:即时通讯网 http://www.52im.net/thread-2141-1-1.html达达创立于2014年5月,业务覆盖全国37个城市,拥有130万注册众包配送员,日均配送百万单,是全国领先的最后三公里物流配送平台。达达的业务
2023-06-05

从零开始实现SaaS平台:PHP实践指南

从零开始实现SaaS平台:PHP实践指南一、引言随着互联网技术的发展,SaaS(Software as a Service)平台越来越受到企业和个人用户的青睐。作为一种云计算模式,SaaS平台为用户提供了便捷、灵活的软件服务,极大地降低
从零开始实现SaaS平台:PHP实践指南
2024-03-07

【小程序从0到1】首页布局案例的实现

欢迎来到我的博客 📔博主是一名大学在读本科生,主要学习方向是前端。 🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏 🛠目前正在学习的是&#
2023-08-16

从实践中学习:Golang面向对象编程的最佳实践

从实践中学习:Golang面向对象编程的最佳实践随着Golang(Go语言)在近年来的应用越来越广泛,越来越多的开发者开始探索Golang的面向对象编程(OOP)特性。尽管Golang是一门以并发为核心设计的编程语言,其本身并不是一门纯粹
从实践中学习:Golang面向对象编程的最佳实践
2024-02-28

【Linux】从0到1实现一个进度条小程序

个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处 文章目录 前言一、理解回车 '\r' 和换行 '\n'二、初步认识缓冲区1. 认识第一个
2023-08-16

Node.js EventEmitter 实践:从基础到高级的实战指南

Node.js EventEmitter 是一个事件驱动编程的核心模块,它允许应用程序通过发布和订阅事件来进行通信。本文将深入探讨 EventEmitter 的基础知识和高级用法,提供从初学者到资深开发人员的全面指南。
Node.js EventEmitter 实践:从基础到高级的实战指南
2024-02-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录