[深度学习] Transformer

Transformer是一种深度学习模型,最早由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它最初用于自然语言处理(NLP)任务,但其架构的灵活性使其在许多其他领域也表现出色,如计算机视觉、时间序列分析等。以下是对Transformer模型的详细介绍。

一、基本结构

Transformer模型主要由两个部分组成:编码器(Encoder)和解码器(Decoder)。

编码器(Encoder)
  • 输入嵌入(Input Embedding):将输入的词汇转换为高维向量表示。
  • 位置编码(Positional Encoding):由于Transformer没有循环结构或卷积结构,因此需要显式地加入位置信息。位置编码可以帮助模型了解序列中各个词汇的位置。
  • 多头自注意力机制(Multi-Head Self-Attention):自注意力机制可以捕捉序列中不同位置之间的依赖关系。多头机制允许模型关注不同的子空间。
  • 前馈神经网络(Feed-Forward Neural Network):两个线性变换和一个ReLU激活函数,独立地应用于每个位置。
  • 层归一化(Layer Normalization)残差连接(Residual Connection):每个子层的输出都进行层归一化,并通过残差连接加入子层输入。

编码器包含多个(通常是6个)这样的子层堆叠。

解码器(Decoder)

解码器的结构与编码器类似,但增加了一个用于接收编码器输出的注意力层。

  • 输入嵌入、位置编码、多头自注意力机制、前馈神经网络、层归一化和残差连接:与编码器相同。
  • 掩码多头自注意力机制(Masked Multi-Head Self-Attention):防止解码器当前位置注意到未来位置的信息。
  • 编码器-解码器注意力机制(Encoder-Decoder Attention):使解码器能关注编码器的输出,从而将编码器捕捉到的上下文信息用于生成目标序列。

解码器也包含多个(通常是6个)这样的子层堆叠。

在这里插入图片描述

二、详细机制

注意力机制(Attention Mechanism)

自注意力机制是Transformer的核心。它的计算过程如下:

  1. 计算查询(Query)、键(Key)、值(Value)矩阵
    在这里插入图片描述
    其中,X 是输入序列,WQ、WK、WV是可训练的权重矩阵。

  2. 计算注意力分数
    在这里插入图片描述
    其中:

    • dk是键向量的维度。
    • KT 是键矩阵的转置
  3. 多头机制
    多头注意力机制将输入映射到多个子空间,通过多个注意力头来捕捉不同的特征。然后将这些头的输出连接起来:
    在这里插入图片描述
    其中,每个头是独立的注意力机制,WO 是可训练的线性变换矩阵。

三、Transformer的优点

  1. 并行计算:不同于RNN的序列处理方式,Transformer允许并行计算,提高了训练速度。
  2. 长程依赖:通过自注意力机制,Transformer能够直接捕捉序列中任意位置之间的依赖关系。
  3. 灵活性:Transformer架构可以轻松扩展到不同任务,如语言翻译、文本生成、图像处理等。

四、变种和改进

自从Transformer被提出以来,已经出现了许多改进和变种,例如:

  • BERT(Bidirectional Encoder Representations from Transformers):双向编码器,适用于多种NLP任务。
  • GPT(Generative Pre-trained Transformer):生成模型,专注于文本生成任务。
  • T5(Text-to-Text Transfer Transformer):将所有NLP任务统一为文本到文本的形式。
  • Vision Transformer(ViT):将Transformer应用于图像分类任务。

五、应用领域

Transformer模型在以下领域表现出色:

  1. 自然语言处理(NLP):如机器翻译、文本生成、问答系统等。
  2. 计算机视觉:如图像分类、目标检测等。
  3. 时间序列分析:如股票预测、天气预报等。
  4. 推荐系统:通过捕捉用户与物品之间的复杂关系来提供个性化推荐。

六、代码示例

以下是一个使用TensorFlow实现简单Transformer的代码示例:

import tensorflow as tf
import numpy as np# 注意力机制
def scaled_dot_product_attention(q, k, v, mask):matmul_qk = tf.matmul(q, k, transpose_b=True)dk = tf.cast(tf.shape(k)[-1], tf.float32)scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)if mask is not None:scaled_attention_logits += (mask * -1e9)attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)output = tf.matmul(attention_weights, v)return output, attention_weights# 多头注意力
class MultiHeadAttention(tf.keras.layers.Layer):def __init__(self, d_model, num_heads):super(MultiHeadAttention, self).__init__()self.num_heads = num_headsself.d_model = d_modelassert d_model % self.num_heads == 0self.depth = d_model // self.num_headsself.wq = tf.keras.layers.Dense(d_model)self.wk = tf.keras.layers.Dense(d_model)self.wv = tf.keras.layers.Dense(d_model)self.dense = tf.keras.layers.Dense(d_model)def split_heads(self, x, batch_size):x = tf.reshape(x, (batch_size, -1, self.num_heads, self.depth))return tf.transpose(x, perm=[0, 2, 1, 3])def call(self, v, k, q, mask):batch_size = tf.shape(q)[0]q = self.wq(q)k = self.wk(k)v = self.wv(v)q = self.split_heads(q, batch_size)k = self.split_heads(k, batch_size)v = self.split_heads(v, batch_size)scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask)scaled_attention = tf.transpose(scaled_attention, perm=[0, 2, 1, 3])concat_attention = tf.reshape(scaled_attention, (batch_size, -1, self.d_model))output = self.dense(concat_attention)return output, attention_weights# 前馈神经网络
def point_wise_feed_forward_network(d_model, dff):return tf.keras.Sequential([tf.keras.layers.Dense(dff, activation='relu'),tf.keras.layers.Dense(d_model)])# 编码器层
class EncoderLayer(tf.keras.layers.Layer):def __init__(self, d_model, num_heads, dff, rate=0.1):super(EncoderLayer, self).__init__()self.mha = MultiHeadAttention(d_model, num_heads)self.ffn = point_wise_feed_forward_network(d_model, dff)self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)self.dropout1 = tf.keras.layers.Dropout(rate)self.dropout2 = tf.keras.layers.Dropout(rate)def call(self, x, training, mask):attn_output, _ = self.mha(x, x, x, mask)attn_output = self.dropout1(attn_output, training=training)out1 = self.layernorm1(x + attn_output)ffn_output = self.ffn(out1)ffn_output = self.dropout2(ffn_output, training=training)out2 = self.layernorm2(out1 + ffn_output)return out2# 解码器层
class DecoderLayer(tf.keras.layers.Layer):def __init__(self, d_model, num_heads, dff, rate=0.1):super(DecoderLayer, self).__init__()self.mha1 = MultiHeadAttention(d_model, num_heads)self.mha2 = MultiHeadAttention(d_model, num_heads)self.ffn = point_wise_feed_forward_network(d_model, dff)self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6)self.dropout1 = tf.keras.layers.Dropout(rate)self.dropout2 = tf.keras.layers.Dropout(rate)self.dropout3 = tf.keras.layers.Dropout(rate)def call(self, x, enc_output, training, look_ahead_mask, padding_mask):attn1, attn_weights_block1 = self.mha1(x, x, x, look_ahead_mask)attn1 = self.dropout1(attn1, training=training)out1 = self.layernorm1(x + attn1)attn2, attn_weights_block2 = self.mha2(enc_output, enc_output, out1, padding_mask)attn2 = self.dropout2(attn2, training=training)out2 = self.layernorm2(out1 + attn2)ffn_output = self.ffn(out2)ffn_output = self.dropout3(ffn_output, training=training)out3 = self.layernorm3(out2 + ffn_output)return out3, attn_weights_block1, attn_weights_block2# 编码器
class Encoder(tf.keras.layers.Layer):def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, rate=0.1):super(Encoder, self).__init__()self.d_model = d_modelself.num_layers = num_layersself.embedding = tf.keras.layers.Embedding(input_vocab_size, d_model)self.pos_encoding = positional_encoding(1000, self.d_model)self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate) for _ in range(num_layers)]self.dropout = tf.keras.layers.Dropout(rate)def call(self, x, training, mask):seq_len = tf.shape(x)[1]x = self.embedding(x)x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))x += self.pos_encoding[:, :seq_len, :]x = self.dropout(x, training=training)for i in range(self.num_layers):x = self.enc_layers[i](x, training, mask)return x# 解码器
class Decoder(tf.keras.layers.Layer):def __init__(self, num_layers, d_model, num_heads, dff, target_vocab_size, rate=0.1):super(Decoder, self).__init__()self.d_model = d_modelself.num_layers = num_layersself.embedding = tf.keras.layers.Embedding(target_vocab_size, d_model)self.pos_encoding = positional_encoding(1000, self.d_model)self.dec_layers = [DecoderLayer(d_model, num_heads, dff, rate) for _ in range(num_layers)]self.dropout = tf.keras.layers.Dropout(rate)def call(self, x, enc_output, training, look_ahead_mask, padding_mask):seq_len = tf.shape(x)[1]attention_weights = {}x = self.embedding(x)x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))x += self.pos_encoding[:, :seq_len, :]x = self.dropout(x, training=training)for i in range(self.num_layers):x, block1, block2 = self.dec_layers[i](x, enc_output, training, look_ahead_mask, padding_mask)attention_weights[f'decoder_layer{i+1}_block1'] = block1attention_weights[f'decoder_layer{i+1}_block2'] = block2return x, attention_weights# Transformer模型
class Transformer(tf.keras.Model):def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, rate=0.1):super(Transformer, self).__init__()self.encoder = Encoder(num_layers, d_model, num_heads, dff, input_vocab_size, rate)self.decoder = Decoder(num_layers, d_model, num_heads, dff, target_vocab_size, rate)self.final_layer = tf.keras.layers.Dense(target_vocab_size)def call(self, inp, tar, training, enc_padding_mask, look_ahead_mask, dec_padding_mask):enc_output = self.encoder(inp, training, enc_padding_mask)dec_output, attention_weights = self.decoder(tar, enc_output, training, look_ahead_mask, dec_padding_mask)final_output = self.final_layer(dec_output)return final_output, attention_weights# 位置编码
def positional_encoding(position, d_model):angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], d_model)angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])pos_encoding = angle_rads[np.newaxis, ...]return tf.cast(pos_encoding, dtype=tf.float32)def get_angles(pos, i, d_model):angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model))return pos * angle_rates# 掩码
def create_padding_mask(seq):seq = tf.cast(tf.math.equal(seq, 0), tf.float32)return seq[:, tf.newaxis, tf.newaxis, :]def create_look_ahead_mask(size):mask = 1 - tf.linalg.band_part(tf.ones((size, size)), -1, 0)return mask# 超参数
num_layers = 4
d_model = 128
dff = 512
num_heads = 8
input_vocab_size = 8500
target_vocab_size = 8000
dropout_rate = 0.1# 创建Transformer模型
transformer = Transformer(num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, dropout_rate)# 损失函数和优化器
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction='none')
def loss_function(real, pred):mask = tf.math.logical_not(tf.math.equal(real, 0))loss_ = loss_object(real, pred)mask = tf.cast(mask, dtype=loss_.dtype)loss_ *= maskreturn tf.reduce_sum(loss_) / tf.reduce_sum(mask)learning_rate = tf.keras.optimizers.schedules.ExponentialDecay(1e-4, decay_steps=100000, decay_rate=0.9, staircase=True)
optimizer = tf.keras.optimizers.Adam(learning_rate)# 编译模型
transformer.compile(optimizer=optimizer, loss=loss_function)# 示例输入
sample_input = tf.constant([[1, 2, 3, 4, 0, 0]])
sample_target = tf.constant([[1, 2, 3, 4, 0, 0]])# 训练模型
transformer.fit([sample_input, sample_target], epochs=10)
解释
  1. 注意力机制:定义了计算注意力权重的函数和多头注意力机制。
  2. 前馈神经网络:实现了前馈神经网络的部分。
  3. 编码器和解码器层:定义了编码器和解码器的基本层。
  4. 编码器和解码器:实现了编码器和解码器的堆叠。
  5. Transformer模型:集成了编码器和解码器,定义了完整的Transformer模型。
  6. 位置编码:为输入序列添加位置信息。
  7. 掩码:定义了填充掩码和前瞻掩码,用于处理输入和目标序列中的填充和防止信息泄露。

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

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

相关文章

HarmonyOS Next开发学习手册——选项卡 (Tabs)

当页面信息较多时,为了让用户能够聚焦于当前显示的内容,需要对页面内容进行分类,提高页面空间利用率。 Tabs 组件可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息…

Redis Stream Redisson Stream

目录 一、Redis Stream1.1 场景1:多个客户端可以同时接收到消息1.1.1 XADD - 向stream添加Entry(发消息 )1.1.2 XREAD - 从stream中读取Entry(收消息)1.1.3 XRANGE - 从stream指定区间读取Entry(收消息&…

【王佩丰 Excel 基础教程】第一讲:认识Excel

文章目录 前言一、Excel软件简介1.1、历史上的其他数据处理软件与 Microsoft Excel1.2、Microsoft Excel 能做些什么1.3、Excel 界面介绍 二、Microsoft Excel 的一些重要概念2.1、Microsoft Excel 的几种常见文件类型2.2、工作簿、工作表、单元格. 三、使用小工具:…

SpringDataJPA系列(1)JPA概述

SpringDataJPA系列(1)JPA概述 SpringDataJPA似乎越来越流行了,我厂的mysql数据库和MongoDB数据库持久层都依赖了SpringDataJPA。为了更好的使用它,我们内部还对MongoDB的做了进一步的抽象和封装。为了查漏补缺,温故而知新,整理下…

基于自组织长短期记忆神经网络的时间序列预测(MATLAB)

LSTM是为了解决RNN 的梯度消失问题而诞生的特殊循环神经网络。该网络开发了一种异于普通神经元的节点结构,引入了3 个控制门的概念。该节点称为LSTM 单元。LSTM 神经网络避免了梯度消失的情况,能够记忆更长久的历史信息,更能有效地拟合长期时…

【面试系列】数据科学家 高频面试题及详细解答

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…

[OtterCTF 2018]Name Game

Name Game 题目描述:我们知道这个帐号登录到了一个名为Lunar-3的频道。账户名是什么?猜想:既然登陆了游戏,我们尝试直接搜索镜像中的字符串 Lunar-3 。 直接搜索 Lunar-3 先把字符串 重定向到 txt文件里面去然后里面查找 Lunar-3…

使用 Spring Boot 3.x 与图形学技术,添加电子印章防伪特征

使用 Spring Boot 3.x 与图形学技术,添加电子印章防伪特征 在电子办公和无纸化办公日益普及的今天,电子印章的使用越来越广泛。然而,如何确保电子印章的安全性和防伪能力成为了一个亟待解决的问题。本文将通过 Spring Boot 3.x 和图形学技术,深入探讨如何为电子印章添加防…

Numpy array和Pytorch tensor的区别

1.Numpy array和Pytorch tensor的区别 笔记来源: 1.Comparison between Pytorch Tensor and Numpy Array 2.numpy.array 4.Tensors for Neural Networks, Clearly Explained!!! 5.What is a Tensor in Machine Learning? 1.1 Numpy Array Numpy array can only h…

IDEA中导入Maven项目

IDEA中导入Maven项目 方式1:使用Maven面板,快速导入项目 打开IDEA,选择右侧Maven面板,点击 号,选中对应项目的pom.xml文件,双击即可 说明:如果没有Maven面板,选择 View > Appe…

C#——SortedList 排序列表详情

SortedList 排序列表 SortedList 类用来表示键/值对的集合,这些键/值对按照键值进行排序,并且可以通过键或索引访问集合中的各个项。 我们可以将排序列表看作是数组和哈希表的组合,其中包含了可以使用键或索引访问各项的列表。如果您使用索…

为什么word生成的PDF内容显示不全?

在现代办公环境中,将文档从一个格式转换为另一个格式是一个常见的任务。然而,有时候我们可能会遇到意想不到的问题,比如使用Word转换成PDF时,生成的PDF文件只显示了整个界面的四分之一内容。这种问题不仅令人困扰,也可…

如何自己录制教学视频?零基础也能上手

随着在线教育的蓬勃发展,录制教学视频成为了教师和教育工作者们不可或缺的一项技能。无论是为了远程教学、课程分享还是知识普及,教学视频的录制都变得愈发重要。可是如何自己录制教学视频呢?本文将介绍两种录制教学视频的方法,这…

pg_rman:备份和恢复管理工具#postgresql培训

pg_rman 是 PostgreSQL 的在线备份和恢复工具。 pg_rman 项目的目标是提供一种与 pg_dump 一样简单的在线备份和 PITR 方法。此外,它还为每个数据库集群维护一个备份目录。用户只需一个命令即可维护包括存档日志在内的旧备份。 #PG培训#PG考试#postgresql考试#pos…

[OtterCTF 2018]Bit 4 Bit

我们已经发现这个恶意软件是一个勒索软件。查找攻击者的比特币地址。** 勒索软件总喜欢把勒索标志丢在显眼的地方,所以搜索桌面的记录 volatility.exe -f .\OtterCTF.vmem --profileWin7SP1x64 filescan | Select-String “Desktop” 0x000000007d660500 2 0 -W-r-…

填报高考志愿时,学校、专业和城市怎么选择呢?

我的观点是: 专业>城市>学校 专业是兴趣导向,符合自己的价值观,失去了这种驱动力的专业学习,会变得非常艰难的,而且没有竞争力,所以我的排序第一位是专业。 其次是城市,最好是一线城市&…

mysql_config 命令, 可以查看mysqlclient库的位置在/usr/lib64/mysql下

好吧,其实我是从这里知道了 -l 后面加的库名和so文件这种名不一样,因为库文件实际叫下面这个名(前面有lib)。

基于SSM+Jsp的疫情居家办公OA系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

入门Java爬虫:认识其基本概念和应用方法

Java爬虫初探:了解它的基本概念与用途,需要具体代码示例 随着互联网的快速发展,获取并处理大量的数据成为企业和个人不可或缺的一项任务。而爬虫(Web Scraping)作为一种自动化的数据获取方法,不仅能够快速…

全网唯一免费无水印AI视频工具!

最近Morph Studio开始免费公测!支持高清画质,可以上传语音,同步口型,最重要的是生成的视频没有水印! Morph Studio国内就可以访问,可以使用国内邮箱注册(我用的163邮箱),…