Transformer详解,输入部分(词嵌入、位置编码)

Transformer解读

1.整体架构解读

image.png

由图可知:

1.1输入部分:

inputs和带标签的输入分别进encoder和decoder

Positional Encoding

1.2输出部分

线性层

softmax层

1.3编码器部分

由N个编码器堆叠而成

每个编码器有两个子层相连接

第一个子层->多头自注意力机制和规范化层以及一个残差连接

第二个子层->全连接层和规范化层以及一个残差连接

1.4解码器部分

由N个解码器堆叠而成

每个编码器有三个子层相连接

第一个子层->一个多头自注意力机制层和规范化层以及一个残差连接

第二个子层->多头注意力机制和规范化层以及一个残差连接

第三个子层->全连接层和规范化层以及一个残差连接

2.输入部分详解

2.1Embedding词嵌入

目的是为了将目标文本的数字表示->向量表示,为了在高维空间捕捉词汇间的关系

#1.embedding类的实现
import torch
from torch.autograd import Variable
import math
import torch.nn as nn

class Embeddings(nn.Module):#需要继承
    def __init__(self,d_model,vocab):#词嵌入的维度,词表大小
        super(Embeddings,self).__init__()#继承
        self.lcut = nn.Embedding(vocab,d_model)
        self.d_model = d_model

    def forward(self,x):
        """
        可以理解为该层的前向传播逻辑,所有层中都会有此函数。传给类的实例化对象时,自动调用
        :param x:输入进模型的文本通过词汇映射后的数字张量
        :return:
        """
        return self.lcut(x)*math.sqrt(self.d_model)

效果如下

d_model = 512
vocab = 100
x = Variable(torch.LongTensor([[1,2,3,4],[5,6,7,8]]))#[2,4]
emb = Embeddings(d_model,vocab)
embr = emb(x)
print("emb:",embr)
print(embr.shape)#[2,4,512]

>>>>>
emb: tensor([[[-13.7408,  -4.3108,  35.0170,  ..., -44.5515, -16.5556,  -2.9577],
         [ 23.3314,  -9.3100,  26.4966,  ...,   7.4887,  28.7678,  16.3725],
         [-13.5485,  28.9699,  35.8271,  ..., -22.9973,  -0.4782,   9.3057],
         [-26.4563,   6.6810, -58.8932,  ...,  55.4734,  16.3932, -38.4998]],

        [[  0.6895,  43.8544, -10.3074,  ...,  39.5331,  20.9398,  13.0055],
         [ 10.1109,  16.5785,   7.7799,  ...,  19.8802, -18.9864,  -0.1557],
         [-31.9423,  -5.7930,   2.0319,  ...,   0.4931, -27.7125,  -3.4999],
         [-47.6672,   4.2582, -32.6036,  ...,  12.7451,   9.8043,  -1.6442]]],
       grad_fn=<MulBackward0>)
torch.Size([2, 4, 512])

2.2Positional Encoding

2.2.1为什么需要位置编码器(没有上下文关系这种)

在Transformer编码器中没有针对词汇位置信息的处理,故需要在embedding层后加入位置编码器,将词汇位置不同可能会产生不同语义的信息加入到嵌入张量中(embedding),用来弥补位置信息的缺失。

2.2.2位置信息编码的实现

class PositionalEncoding(nn.Module):
    def __init__(self,d_model,dropout,max_len=5000):
        """
        :param d_model:embedding的维度
        :param dropout: Dropout的置零比例
        :param max_len: 每个句子的最大长度
        """
        super(PositionalEncoding, self).__init__()
        #实例化Dropout层
        self.dropout = nn.Dropout(p=dropout)

        #初始一个位置编码矩阵,大小是max_len*d_model
        pe = torch.zeros(max_len,d_model)
        #初始化一个绝对位置矩阵,词汇的位置就是用它的索引表示max_len*1
        position = torch.arange(0,max_len).unsqueeze(1)#由[0,1,2...max_len][max_len] -> [[0],[1]...[max_len]][max_len,1]
        #目的是要把position的信息放到pe里面去

        #定义一个变换矩阵使得position的[max_len,1]*变换矩阵得到pe[max_len,d_model]->变换矩阵格式[1,d_model]
        #除以这个是为了加快收敛速度
        #div_term格式是[0,1,2...d_model/2],分成了两个部分,步长为2
        div_term = torch.exp(torch.arange(0,d_model,2)*-(math.log(10000.0)/d_model))
        # print(div_term.shape)
        # print(position * div_term)
        # a = position*div_term
        # print(a.shape)
        #将前面定义好的矩阵进行奇数偶数赋值
        pe[:,0::2] = torch.sin(position*div_term)
        pe[:,1::2] = torch.cos(position*div_term)

        #此时pe[max_len,d_model]
        #embedding三维(可以是[batch_size,vocab,d_model])#vocab就是max_len
        #将pe升起一个维度扩充成三维张量
        pe = pe.unsqueeze(0)


        #位置编码矩阵注册成模型的buffer,它不是模型中的参数,不会跟随优化器进行优化
        #注册成buffer后我们就可以在模型的保存和加载时,将这个位置编码器和模型参数加载进来
        self.register_buffer('pe',pe)


    def forward(self,x):
        """
        :param x:x代表文本序列的词嵌入
        pe编码过长将第二个维度也就是max_len的维度缩小成句子的长度
        """
        x = x + Variable(self.pe[:,:x.size(1)],requires_grad=False)
        return self.dropout(x)


x = torch.LongTensor([[1,2,3,4],[5,6,7,8]])#[2,4]
emb = Embeddings(d_model,vocab)#[2,4,512]
embr = emb(x)
pe = PositionalEncoding(d_model,dropout=0.2,max_len=50)
pe_result = pe(embr)
#
print(pe_result)
print(pe_result.shape)#[2,4,512]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249