当前位置:   article > 正文

pytorch实现transformer(1): 模型介绍_transformer 模型pytorch

transformer 模型pytorch

1. transformer 介绍

Transformer 模型是由谷歌在 2017 年提出并首先应用于机器翻译的神经网络模型结构。机器翻译的目标是从源语言(Source Language)转换到目标语言(Target Language)。Transformer 结构完全通过注意力机制完成对源语言序列和目标语言序列全局依赖的建模。当前几乎全部大语言模型都是基于 Transformer 结构,本节以应用于机器翻译的基于 Transformer 的编码器和解码器介绍该模型。

Transformer它的提出最开始是针对NLP领域的,在次之前大家主要用的是RNN,LSTM这类时序网络。像RNN这类网络其实它是有些问题的,首先它的记忆的长度是有限的,特别像RNN它的记忆长度就比较短,所以后面就有提出LSTM。但是他们还有另外一个问题就是无法并行化,也就是说我们必须先计算 t 0 t_0 t0时刻的输出,计算完之后我们才能进一步计算 t 1 t_1 t1时刻的数据。由于无法并行化,训练效率就比较低.

针对这一问题,Google提出了Transformer来替代之前的时序网络,

  • Transformer不受硬件限制的情况下,理论上记忆是可以无限长的。
  • 其次,它是可以做并行化的,这是一个非常大的优点

基于 Transformer 结构主要分两部分:编码器Encoder和解码器Decoder,它们均由若干个基本的 Transformer 块(Block)组成(对应着图中的灰色框)。每个 Transformer 块都接收一个向量序列 { x i } i = 1 t \{x_i\}_{i=1}^t { xi}i=1t作为输入,并输出一个等长的向量序列作为输出 { y i } i = 1 t \{y_i\}_{i=1}^t { yi}i=1t, 而 y i y_i yi是当前 Transformer 块对输入 x i x_i xi进一步整合其上下文语义后对应的输出。

在这里插入图片描述

图1:基于 Transformer 的编码器和解码器结构

主要涉及到如下几个模块:

  • Position Encoding: 使用位置编码来理解文本的顺序

  • 注意力层:使用多头注意力(Multi-Head Attention)机制 整合上下文语义 ,它使得序列中任意两个token之间的依赖关系可以直接被建模而不基于传统的循环结构,从而更好地解决文本的长程依赖

  • 位置感知前馈层(Position-wise FFN):通过全连接层对输入文本序列中的每个单词表示进行更复杂的变换

  • 残差连接:对应图中的 Add 部分。它是一条分别作用在上述两个子层当中的直连通路,被用于连接它们的输入与输出。从而使得信息流动更加高效,有利于模型的优化

  • 层归一化:对应图中的 Norm 部分。作用于上述两个子层的输出表示序列中,对表示序列进行层归一化操作,同样起到稳定优化的作用。

2 Position Encoding

2.1 位置编码原理

由于Transformer模型没有循环神经网络的迭代操作,所以我们必须提供每个token位置信息给Transformer, 这样它才能识别出语言中的顺序关系。

Positional Encoding(位置嵌入), 它的维度为[num_token,embedding_dimension], 位置嵌入的维度与词向量token的维度是相同的,都是embedding_dimension。其中max_sequence_length属于超参数,指的是限定每个句子最长由多少个词组成。

注意,我们一般以为单位训练Transformer模型,首先初始化字编码大小为[vocab_size,embedding_dimension], vocab_size 为字库中所有字的数量,embedding_dimension为字向量的维度,对应pytorch中,其实就是 nn.Embedding(vocab_size,embedding_dimension)

论文中使用了 s i n sin sin c o s cos cos函数的线性变换来提供给模型位置信息:

在这里插入图片描述
其中pos指的是一句话中某个字的位置,取值范围为[0,max_sequence_length], i i i指的是字向量的序号,取值范围是[0,embedding_dimension/2], d m o d e l d_{model} dmodel指的是embedding_dimension的值。

通过sincos处理,从而使得位置编码产生不同对的周期性变化,使得每个位置在embedding_dimension维度上都会得到不同周期的sincos函数的取值组合,从而产生独一的位置信息,最终使得模型学到位置之间的依赖关系和自然语言的时序特效

2.2 代码实现

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns 
import math


def get_positional_encoding(max_seq_len,embed_dim):
    # 初始化一个positional encoding
    # embed_dim: 字嵌入的维度
    # max_seq_len: 最大的序列长度
    
    positional_encoding = np.array([
        [pos/np.power(1000,2*i/ embed_dim) for i in range(embed_dim)] if pos !=0 else \
            np.zeros(embed_dim) for pos in range(max_seq_len)
            ])
    
    positional_encoding[1:,0::2] = np.sin(positional_encoding[1:,0::2]) #dim 2i 偶数
    positional_encoding[1:,1::2] = np.cos(positional_encoding[1:,1::2]) #dim 2i+1 奇数
    
    return positional_encoding

positional_encoding = get_positional_encoding(max_seq_len=100,embed_dim=16)
plt.figure(figsize=(10,10))
sns.heatmap(positional_encoding)
plt.title('Sinusoidal Function')
plt.xlabel('hidden dimension')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在这里插入图片描述

plt.figure(figsize=(8,5))
plt.plot(positional_encoding[1:,1],label="dimension 1")
plt.plot(positional_encoding[1:,2],label="dimension 2")
plt.plot(positional_encoding[1:,3],label="dimension 3")
plt.legend()
plt.xlabel("Sequence length")
plt.ylabel("Period of Positional Encoding")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

3 Self-attention

自注意力(Self-Attention)操作是基于 Transformer 的机器翻译模型的基本操作,在源语言的编码和目标语言的生成中频繁地被使用以建模源语言、目标语言任意两个单词之间的依赖关系。给定由单词语义嵌入及其位置编码叠加得到的输入表示 { x i ∈ R d } i t \{x_i \in R^d\}_i^t { xiRd}it, 为了实现对上下文语义依赖的建模,进一步引入在自注意力机制中涉及到的三个元素:查询 q i q_i qi Query ,键 k i k_i

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/709897
推荐阅读
相关标签
  

闽ICP备14008679号