赞
踩
目录
基于Encoder-Decoder 的Multi-Head Attention
自注意力:输入句子中,其他单词对某个单词的影响
前馈神经网络:输入句子中,同一位置的单词,前馈神经网络一致
编码-解码自注意力:输入句子的相关部分
矢量是一阶张量、矩阵是二阶张量
假设词嵌入的维数为4,则实际的位置编码如下:
每一行对应一个词向量的位置编码,
所以第一行对应着输入序列的第一个词。
每行包含512个值,每个值介于1和-1之间。
已经对它们进行了颜色编码,所以图案是可见的。
20字(行)的位置编码实例,词嵌入大小为512(列)。
它从中间分裂成两半。
左半部分的值由一个函数(使用正弦)生成,
右半部分由另一个函数(使用余弦)生成。
然后将它们拼在一起而得到每一个位置编码向量。
文本进入到模型需要编码,transformer的编码方式包括Word Embedding和Positional Encoding。
word embedding两种方式:
1、使用预训练模型直接生成,相当于提供一个lookup table;
(若针对一个特定的nlp任务,其训练集词库有限,即预测过程中可能出现词库外的词语。)
2、 随机初始化,在模型训练过程中作为一个可训练的参数参与梯度优化,这样在模型训练完成之时词向量也会随之生成。
word embedding代码:
- class Embeddings(nn.Module):
- def __init__(self, d_model, vocab):
- """
- :param d_model: word embedding维度
- :param vocab: 语料库词的数量
- """
- super(Embeddings, self).__init__()
- self.lut = nn.Embedding(vocab, d_model)
- self.d_model = d_model
-
- def forward(self, x):
- """
- :param x: 一个batch的输入,size = [batch, L], L为batch中最长句子长度
- """
- return self.lut(x) * math.sqrt(self.d_model) #这里乘了一个权重,不改变维度. size = [batch, L, d_model]
d_model是此向量的维度,理论上输入以后就是个定值了,那么最后乘的权重math.sqrt(self.d_model)显然也是个常数。所有随机向量乘一个常数,相当于同时放缩,理论上不会有什么影响。
Position Encoding两种方式:
1、通过训练学习positional encoding 向量;
2、编了个公式来计算positional encoding向量;
两种方式的结果是相似的,第二种,减少了训练参数,而且在训练集中没有出现过的句子长度上也能用
pos表示单词在句子中的绝对位置,pos=0,1,2…,
例如:Jerry在"Tom chase Jerry"中的pos=2;
dmodel表示词向量的维度,在这里dmodel=512;
2i和2i+1表示奇偶性,i表示词向量中的第几维,例如这里dmodel=512,故i=0,1,2…255。
- class PositionalEncoding(nn.Module):
- def __init__(self, d_model, dropout, max_len=5000):
- """
- :param d_model: pe编码维度,一般与word embedding相同,方便相加
- :param dropout: dorp out
- :param max_len: 语料库中最长句子的长度,即word embedding中的L
- """
- super(PositionalEncoding, self).__init__()
- # 定义drop out
- self.dropout = nn.Dropout(p=dropout)
-
- # 计算pe编码
- pe = torch.zeros(max_len, d_model) # 建立空表,每行代表一个词的位置,每列代表一个编码位
- position = torch.arange(0, max_len).unsqueeze(1) # 建个arrange表示词的位置以便公式计算,size=(max_len,1)
- #torch.arange(start=1.0,end=6.0)和range区别,arrange生成浮点数值为start~end的数组但不包括end
- #unsqueeze(i)压缩,增加维数,在第i+1个维度上再加一维
- div_term = torch.exp(torch.arange(0, d_model, 2) * # 计算公式中10000**(2i/d_model)
- -(math.log(10000.0) / d_model))
- pe[:, 0::2] = torch.sin(position * div_term) # 计算偶数维度的pe值
- pe[:, 1::2] = torch.cos(position * div_term) # 计算奇数维度的pe值
- pe = pe.unsqueeze(0) # size=(1, L, d_model),为了后续与word_embedding相加,意为batch维度下的操作相同
- self.register_buffer('pe', pe) # pe值是不参加训练的
-
- def forward(self, x):
- # 输入的最终编码 = word_embedding + positional_embedding
- x = x + Variable(self.pe[:, :x.size(1)],requires_grad=False) #size = [batch, L, d_model]
- return self.dropout(x) # size = [batch, L, d_model]
全连接层公式如下:
FFN(x)=max(0,xW_1+b_1)W_2+b_2
这里的全连接层是一个两层的神经网络,先线性变换,然后ReLU非线性,再线性变换。
为什么深度神经网络会发生退化?
举个例子:
假如某个神经网络的最优网络层数是18层,本着层数越深越好的理念,我们设计了32层,多余的14层网络必须进行恒等映射,恒等映射的意思就是说,输入什么,输出就是什么,可以理解成F(x)=x这样的函数,
但现实是神经网络的参数都是训练出来地,要想保证训练出来地参数能够很精确的完成F(x)=x的恒等映射其实是很困难
F(X)为残差,X为输入值,
F(X)是经过第一层线性变化并激活后的输出,
第二层进行线性变化之后激活之前,F(X)加入了这一层输入值X,然后再进行激活后输出。
在第二层输出值激活前加入X,这条路径称作shortcut连接。
恒等映射的函数h(X)=F(X)+X,我们要让h(X)=X,只需要让F(X)=0就可以了
神经网络通过训练变成0是比变成X容易很多地,
一般初始化神经网络的参数的时候就是设置的[0,1]之间的随机数嘛。所以经过网络变换后很容易接近于0。
为什么使用Layer Normalization(LN)而不使用Batch Normalization(BN)
LN是在同一个样本中不同神经元之间进行归一化,而BN是在同一个batch中不同样本之间的同一位置的神经元之间进行归一化。
BN是对于相同的维度进行归一化
Decoder的输入分为两类:
一种是训练时的输入,
例如翻译任务,Encoder输入"Tom chase Jerry",Decoder输入"汤姆追逐杰瑞"。
一种是预测时的输入。
开始输入的是起始符,然后每次输入是上一时刻Transformer的输出。例如,
输入"",输出"汤姆",
输入"汤姆",输出"汤姆追逐",
输入"汤姆追逐",输出"汤姆追逐杰瑞",
输入"汤姆追逐杰瑞",输出"汤姆追逐杰瑞"结束。
Masked Multi-Head Attention
与Encoder的Multi-Head Attention计算原理一样,只是多加了一个mask码。mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。
1.padding mask
每个批次输入序列长度是,要对输入序列进行对齐。
在较短的序列后面填充 0。
输入的序列太长,则是截取左边的内容,把多余的直接舍弃。
把填充位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!attention就不会关注
2.sequence mask
sequence mask 是为了使得 decoder 不能看见未来的信息。
训练的时候每次是将target数据完整输入进decoder中地,
预测的时候只能得到前一时刻预测出的输出。
产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上
Encoder中只需要padding mask即可,而Decoder中需要padding mask和sequence mask。
Encoder中的Multi-Head Attention是基于Self-Attention
Decoder中的第二个Multi-Head Attention就只是基于Attention,它的输入Quer来自于Masked Multi-Head Attention的输出,
Keys和Values来自于Encoder中最后一层的输出。
第一个Masked Multi-Head Attention是为了得到之前已经预测输出的信息,相当于记录当前时刻的输入之间的信息的意思。
第二个Multi-Head Attention是为了通过当前输入的信息得到下一时刻的信息,也就是输出的信息,是为了表示当前的输入与经过encoder提取过的特征向量之间的关系来预测输出。
Softmax得到输出的概率分布,然后通过词典,输出概率最大的对应的单词作为我们的预测输出。
参考:
深入理解transformer源码_了不起的赵队的博客-CSDN博客_transformer源码
图解Transformer(完整版)_龙心尘的博客-CSDN博客_transformer
史上最小白之Transformer详解_Stink1995的博客-CSDN博客_transformer神经网络
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。