【机器学习】一文搞懂算法模型之:Transformer

Transformer

  • 1、引言
  • 2、Transformer
    • 2.1 定义
    • 2.2 原理
    • 2.3 算法公式
      • 2.3.1 自注意力机制
      • 2.3.1 多头自注意力机制
      • 2.3.1 位置编码
    • 2.4 代码示例
  • 3、总结

1、引言

小屌丝:鱼哥, 你说transformer是个啥?
小鱼:嗯… 啊… 嗯…就是…
小屌丝:你倒是说啊,是个啥?
小鱼:你不知道?
小屌丝:我知道啊,
小鱼:你知道,你还问我?
小屌丝:考考你
小鱼:kao…kao… wo??
小屌丝:对
小鱼:看你你很懂 transformer
小屌丝: 必须的
小鱼:那你来跟我说一说?
小屌丝:可以。
小鱼:秃头顶上点灯
小屌丝:啥意思? 你说的是啥意思?你说清楚,啥意思???

在这里插入图片描述
小鱼:唉~ ~没文化,真可怕。

2、Transformer

2.1 定义

Transformer是一种基于自注意力机制的深度学习模型,它完全摒弃了传统的循环神经网络(RNN)和卷积神经网络(CNN)结构,转而通过自注意力机制来计算输入序列中不同位置之间的依赖关系。

Transformer模型由谷歌在2017年提出,并在自然语言处理领域取得了显著的成绩,如机器翻译、文本生成、问答系统等。

2.2 原理

Transformer的核心思想是利用自注意力机制来捕捉输入序列中的上下文信息。
它采用Encoder-Decoder架构,其中Encoder负责将输入序列编码为一系列的隐藏状态,而Decoder则根据这些隐藏状态生成输出序列。

在Transformer中,自注意力机制是通过计算输入序列中每个位置与其他位置之间的相似度来实现的。

具体来说,对于输入序列中的每个位置,Transformer会生成一个查询向量、一个键向量和一个值向量。然后,它会计算查询向量与所有键向量之间的相似度,得到一个相似度分数矩阵。

最后,根据这个相似度分数矩阵对值向量进行加权求和,得到每个位置的输出表示。

2.3 算法公式

2.3.1 自注意力机制

自注意力机制

  • 输入:查询矩阵Q、键矩阵K、值矩阵V
  • 输出:自注意力输出Z
  • 公式 Z = s o f t m a x ( Q K T / √ d k ) V Z = softmax(QK^T/√d_k)V Z=softmax(QKT/√dk)V

其中,d_k是键向量的维度,用于缩放点积结果以防止梯度消失。

2.3.1 多头自注意力机制

多头自注意力机制

  • 输入:查询矩阵Q、键矩阵K、值矩阵V、头数h
  • 输出:多头自注意力输出MultiHead(Q, K, V)
  • 公式 M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , . . . , h e a d h ) W O MultiHead(Q, K, V) = Concat(head_1, ..., head_h)W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO

其中,每个头head_i都执行一次自注意力机制,W^O是输出线性变换的权重矩阵。

2.3.1 位置编码

位置编码
为了捕捉序列中的位置信息,Transformer使用位置编码将位置信息嵌入到输入向量中。

公式 P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 ( 2 i / D ) ) P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 ( 2 i / D ) ) PE(pos, 2i) = sin(pos / 10000^(2i / D)) PE(pos, 2i+1) = cos(pos / 10000^(2i / D)) PE(pos,2i)=sin(pos/10000(2i/D))PE(pos,2i+1)=cos(pos/10000(2i/D))

其中, p o s pos pos是位置索引, i i i是维度索引, D D D是输入向量的维度。

2.4 代码示例

# -*- coding:utf-8 -*-
# @Time   : 2024-03-17
# @Author : Carl_DJ'''
import torch  
import torch.nn as nn  
import torch.nn.functional as F  # 定义位置编码类  
class PositionalEncoding(nn.Module):  def __init__(self, d_model, max_len=5000):  super(PositionalEncoding, self).__init__()  # 计算位置编码  pe = torch.zeros(max_len, d_model)  position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)  div_term = torch.exp(torch.arange(0, d_model, 2).float() *  -(np.log(torch.tensor(10000.0)) / d_model))  pe[:, 0::2] = torch.sin(position * div_term)  pe[:, 1::2] = torch.cos(position * div_term)  pe = pe.unsqueeze(0).transpose(0, 1)  self.register_buffer('pe', pe)  def forward(self, x):  x = x + self.pe[:, :x.size(1)]  return x  # 定义Transformer编码器层  
class TransformerEncoderLayer(nn.Module):  def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1):  super(TransformerEncoderLayer, self).__init__()  self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)  self.linear1 = nn.Linear(d_model, dim_feedforward)  self.dropout = nn.Dropout(dropout)  self.linear2 = nn.Linear(dim_feedforward, d_model)  self.norm1 = nn.LayerNorm(d_model)  self.norm2 = nn.LayerNorm(d_model)  self.dropout1 = nn.Dropout(dropout)  self.dropout2 = nn.Dropout(dropout)  def forward(self, src, src_mask=None, src_key_padding_mask=None):  # 自注意力机制  src2, attn = self.self_attn(src, src, src, attn_mask=src_mask,  key_padding_mask=src_key_padding_mask)  src = src + self.dropout1(src2)  src = self.norm1(src)  # 前馈神经网络  src2 = self.linear2(self.dropout(F.relu(self.linear1(src))))  src = src + self.dropout2(src2)  src = self.norm2(src)  return src, attn  # 定义Transformer编码器  
class TransformerEncoder(nn.Module):  def __init__(self, encoder_layer, num_layers, norm=None):  super(TransformerEncoder, self).__init__()  self.layers = nn.ModuleList([encoder_layer for _ in range(num_layers)])  self.num_layers = num_layers  self.norm = norm  def forward(self, src, mask=None, src_key_padding_mask=None):  output = src  # 堆叠多个编码器层  for mod in self.layers:  output, attn = mod(output, mask, src_key_padding_mask)  if self.norm:  output = self.norm(output)  return output  # 定义完整的Transformer模型  
class TransformerModel(nn.Module):  def __init__(self, src_vocab_size, d_model, nhead, num_encoder_layers, dim_feedforward, max_position_embeddings):  super(TransformerModel, self).__init__()  self.src_mask = None  self.position_enc = PositionalEncoding(d_model, max_position_embeddings)  encoder_layer = TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout=0.1)  encoder_norm = nn.LayerNorm(d_model)  self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, norm=encoder_norm)  self.src_embedding = nn.Embedding(src_vocab_size, d_model)  self.d_model = d_model  def generate_square_subsequent_mask(self, sz):  mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)  mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))  return mask  def forward(self, src, src_mask=None):  if src_mask is None:  device = src.device  bsz, seq_len = src.size()  src_mask = self.generate_square_subsequent_mask(seq_len).to(device)  src = self.src_embedding(src) * math.sqrt(self.d_model)  src = self.position_enc(src)  output = self.encoder(src, src_mask)  output = self.decoder(output)  return output

代码解析

  • PositionalEncoding:定义位置编码类,用于给输入序列添加位置信息。Transformer模型是位置无关的,因此需要通过位置编码来提供序列中每个位置的信息。

  • TransformerEncoderLayer:定义Transformer编码器层,包含自注意力机制和前馈神经网络。每个编码器层都会接收输入序列,经过自注意力机制和前馈神经网络处理,输出新的序列表示。

  • TransformerEncoder:定义Transformer编码器,通过堆叠多个编码器层来构建更深的模型。

  • TransformerModel:定义完整的Transformer模型,包括嵌入层、位置编码、编码器和解码器。模型将源语言序列作为输入,经过一系列变换后,输出每个位置的目标语言词汇的预测概率。

  • generate_square_subsequent_mask:生成一个上三角矩阵的掩码,用于在自注意力机制中防止模型看到未来的信息。

  • forward:模型的前向传播函数。首先,将源语言序列通过嵌入层转换为向量表示,并乘以模型维度的平方根进行缩放。然后,将位置编码加到嵌入向量上。接下来,将结果输入到编码器中。最后,将编码器的输出传递给解码器,得到每个位置的预测概率。

在这里插入图片描述

3、总结

Transformer模型通过自注意力机制打破了传统RNN和CNN的局限性,能够更好地捕捉序列中的长期依赖关系,因此在自然语言处理任务中取得了显著的效果。

Transformer的Encoder-Decoder架构和多头自注意力机制使得模型能够同时处理输入序列中的多个位置,提高了模型的并行性和效率。通过位置编码,Transformer还能够处理序列中的位置信息,使得模型在处理自然语言等序列数据时更加灵活和准确。

虽然Transformer模型具有强大的能力,但它也需要大量的数据和计算资源来进行训练。

因此,在实际应用中,我们通常使用预训练的Transformer模型(如BERT、GPT等)作为基础,通过微调来适应特定的任务需求。

我是小鱼

  • CSDN 博客专家
  • 阿里云 专家博主
  • 51CTO博客专家
  • 企业认证金牌面试官
  • 多个名企认证&特邀讲师等
  • 名企签约职场面试培训、职场规划师
  • 多个国内主流技术社区的认证专家博主
  • 多款主流产品(阿里云等)测评一、二等奖获得者

关注小鱼,一起学习机器学习&深度学习领域的知识。

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

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

相关文章

【Java Web基础】一些网页设计基础(四)

文章目录 1. 做Tab切换2. 下面的内容展示——Card样式3. 采供分类&#xff0c;分类用面包屑导航做4. 出名企业展示&#xff0c;就是普通的图片5. 用热门商品类似的panel做一个农博会展览 1. 做Tab切换 使用BootStrap提供的样式&#xff1a; <ul class"nav nav-tabs&q…

【Redis】缓存穿透

问题发生背景&#xff1a;客户端请求的数据再缓存中和数据库中都不存在。 导致的问题&#xff1a;缓存永远不会生效&#xff0c;这些请求都会去请求数据库—导致数据库压力增大。 解决方案&#xff1a; 1.缓存空对象 在Redis中缓存空对象&#xff0c;告诉客户端数据库中没有该值…

uni-app攻略:如何对接驰腾打印机

一.引言 在当前的移动开发生态中&#xff0c;跨平台框架如uni-app因其高效、灵活的特点受到了开发者们的青睐。同时&#xff0c;随着物联网技术的飞速发展&#xff0c;智能打印设备已成为许多业务场景中不可或缺的一环。今天&#xff0c;我们就来探讨如何使用uni-app轻松对接驰…

Codeforces Round 935 (Div. 3)A~E

A. Setting up Camp 题目分析: 有三种人&#xff0c;内向、外向、综合&#xff0c;内向必须独自一个帐篷&#xff0c;外向必须3个人一个帐篷&#xff0c;综合介于1~3人一个帐篷&#xff0c;我们发现非法情况只会存在外向的人凑不成3个人一个帐篷的情况&#xff0c;因外向不够可…

软件管理rpm与yum

源代码包下载 Compare, Download & Develop Open Source & Business Software - SourceForgehttps://sourceforge.net/ rpm包下载 Welcome to the RPM repository on fr2.rpmfind.nethttp://rpmfind.net/linux/RPM/ 软件包管理 1.rpm包管理: 1)查询: 安装…

微隔离有哪些作用

当前&#xff0c;在零信任安全渐渐被大家熟知的情况下&#xff0c;很多用户在网络安全方面有了更深的认知。在网络安全领域&#xff0c;许多企业用户认为零信任对于降低网络安全风险至关重要&#xff0c;有助于在复杂的网络环境中保护自身企业资源免受未经授权的访问和潜在的网…

HDFSRPC安全认证Token篇

本文主要阐述HDFSRPC安全认证相关的实现。主要介绍Token相关的实现。 写在前面 相关blog https://blog.csdn.net/hncscwc/article/details/124722784 https://blog.csdn.net/hncscwc/article/details/124958357 Token由来 在探究完Kerberos&#xff0c;我一直在想一个问题…

python基本概念和基本数据类型

一、基本概念 1.变量 变量是编程语言中最基本的概念&#xff0c;和字面意思一样&#xff0c;指的就是他们的值可变&#xff0c;和我们以前学习的方程类似&#xff0c;变量可以代入任何值。 命名规范&#xff1a;变量一般使用&#xff1a; 英文字母、下划线 和 数字组成 2.关键…

3.21 day2 QT

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 要求: 1.需要使用Ui界面文件进行界面设计 2.ui界面上的组件相关设置&#xff0c;通过代码实现 3需要添加适当的动图

模拟堆(详解+例题)

一、定义 维护一个数据集合&#xff0c;堆是一个完全二叉树。 那么什么是二叉树呢&#xff1f; 如图&#xff1a; 二、关于小根堆实现 性质&#xff1a;每个根节点都小于等于左右两边&#xff0c;所以树根为最小值。 2.1、堆存储&#xff08;用一维数组来存&#xff09; 记住…

GifGun2汉化版点击渲染失败,弹窗提示“lossless不是有效的模板名称”

总算解决了&#xff0c;记录一下方法&#xff1a; 1&#xff09;在AE顶部导航&#xff0c;点击“编辑 > 模板 > 输出模块” 2&#xff09;新建一个名为GifGun的输出模块&#xff0c;为后续GifGun引用做准备。&#xff08;取名随意&#xff09; 3&#xff09;在AE顶部导航…

软件测试教程 自动化测试之Junit框架

文章目录 1. 什么是 Junit &#xff1f;2. 常见的注解2.1 Test2.2 BeforeAll&#xff0c;AfterAll2.3 BeforeEach&#xff0c;AfterEach 3. 测试用例顺序指定4. 参数化4.1 单个参数4.2 多个参数4.3 通过方法生成 5. 测试套件6. 断言6.1 断言相等6.2 断言不相等6.3 断言为空6.4 …

山东省大数据局副局长禹金涛一行莅临聚合数据走访调研

3月19日&#xff0c;山东省大数据局党组成员、副局长禹金涛莅临聚合数据展开考察调研。山东省大数据局数据应用管理与安全处处长杨峰&#xff0c;副处长都海明参加调研&#xff0c;苏州市大数据局副局长汤晶陪同。聚合数据董事长左磊等人接待来访。 调研组一行参观了聚合数据展…

软件设计师笔记

计算机 运算器组成&#xff1a;算术逻辑单元(ALU)、累加寄存器(AC)、数据缓冲寄存器(DR)、状态条件寄存器()等组成。 控制器组成&#xff1a;指令寄存器(IR)、程序计数器(PC)、地址寄存器(AR)、指令译码器(ID)。 最小数据单位&#xff1a;bit 最小存储单位: byte n进制 转 1…

蓝桥杯单片机备战——关于573问题的填坑

一、遇到的问题 还记得我前面在封装继电器外设的时候遇到的这个问题嘛&#xff0c;当时我怀疑的是138译码器在切换通道的时候会出现其他暂态导致已经锁定的573解锁。 其实不然&#xff0c;之所以会这样还是因为代码问题&#xff0c;也可以说是573反应时间太快了。下面我就分析…

麒麟系统中使用nginx发布项目

1. 安装Nginx sudo apt-get update #进行所有安装操作前都要执行这一句 sudo apt install nginx #出现询问就Yes参考具体 Nginx—在linux的ubuntu系统上的安装使用 2. 修改发布文件 将打包好的dist文件夹中的所有文件覆盖下面这个文件夹中的所有文件 如果出现没有权限替…

openEuler 22.03(华为欧拉)一键安装 Oracle 19C RAC(19.22) 数据库

前言 Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 一键安装 Oracle 19C RAC 过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库…

OPPO案例 | Alluxio在DataAI湖仓一体的实践

分享嘉宾&#xff1a; 付庆午-OPPO数据架构组大数据架构师 在OPPO的实际应用中&#xff0c;我们将自研的Shuttle与Alluxio完美结合&#xff0c;使得整个Shuttle Service的性能得到显著提升&#xff0c;基本上实现了性能翻倍的效果。通过这一优化&#xff0c;我们成功降低了约一…

BetterDisplay Pro:让屏幕管理更高效、更便捷

BetterDisplay Pro是一款功能强大的显示器管理软件&#xff0c;适用于Windows和Mac操作系统。其主要功能包括显示器校准、自动校准、多种预设模式、手动校准以及可视化数据等。 具体而言&#xff0c;这款软件可以根据用户的需求和环境条件调整显示器的颜色、亮度和对比度等参数…

53、简述GCN、NIR、FMIR技术在脑机BCI的发展调查[什么?你咋也叫王富贵?]

最近在搞GCN处理EEG&#xff0c;调查了十几篇文献&#xff0c;总结了一些东西&#xff0c;和学生分享一下&#xff0c;此处只分享一些较为浅显的知识。如下&#xff1a; GCN在其他领域的应用&#xff1a; 1、计算机视觉&#xff1a; 图卷积神经网络在计算机视觉中的应用包括图…