Transformer个人详细总结

在这里插入图片描述
必看:非常详细且准确transformer 总结的相当明确
大致流程:(应该是线性转换,再将转换之后的分为H个头)
一. 将一个句子进入embedding层得到句子的字向量(维度是512),再加入编码信息
二.重点:将这个句子得到的字向量复制三份为Q, K, V(Q,K,V的维度是(句子长度,512))
三. 将Q,K,V分别平均切分为8份,得到q1,q2,q3…q8;k1,k2,k3…k8;v1,v2,v3…v8,他们的shape类型是一抹一样的(句子长度,512/8=64),很暴力,直接拆分;他们的值也都是完全一样(q1=k1=v1!=q2)
四. 将切分之后的值分别进行8次不同的线性转换得到新的q1,q2,q3…q8;k1,k2,k3…k8;v1,v2,v3…v8;由于经过不同的线性转换,所以得到值不同(q1 != k1 != v1)
五. 如下图所示,将(q1,k1,v1),(q2,k2,v2)…(q8,k8,v8)分别进行如下图所示的运算,得到head1,head2…head8

在这里插入图片描述6.将head1,head2,head3…head8加起来得到最终结果,维度是(句子长度,64X8 = 512)

在这里插入图片描述

一 .encode部分 Transformer参数变换表示

  1. 首先给一个输入序列,输入也就是输入的Batch_size个句子,其shape为input = [N,T_q],也就是[batch_size = 32,max_length = 15]
  2. 设置权重矩阵的大小,即Embeding = [vocab_size,num_units],也就是[vocab_size,512],通过tf.nn.embedding_lookup(Embeding ,input )函数得到一个shape为[N,T_q,num_units],即[32,15,512]也就是Transformer模型的输入Q,K,V
  3. 将三个Q,K,V输入到Multi_Head attention之前,需要进行位置编码pos_embeding,得到位置编码后的shape依然是[N,T_q,num_units],此时输入的Q,K,V都是具有位置信息的向量了
  4. 这一步是重点,进入多头注意力机制,这个多头注意力机制是需要运行八次的,进入多头注意力之后,首先要进行1次线性转换,Q = tf.layers.dense(queries, num_units, activation=tf.nn.relu),转换之后的Q,K,V的shape为[N,T_q,num_units],(这个就是为什么多头注意力机制会被称为多头了,实际上是经过8次线性转换(self_attention)而来)然后将得到的Q按照第2维拆分成为 h = 8 份,再按照第0维度拼接,Q_ ,K_ ,V_ = tf.concat(tf.split(Q, num_heads, axis=2), axis=0),得到之后的Q_的shape为[hN,T_q,C/h],这里的C就是num_units,[832,15,512/8=64]

在这里插入图片描述在这里插入图片描述
11. 将Q_ ,K_ 想乘,K_经过transponse后shape为[hN,C/h=T_k,T_k],再进行scale,得到V_的权重值outputs,shape为[hN,T_q,T_k]
12. 由于再输入的时候,涉及到padding 0,为了消除这些本身没有任何信息的影响,需要对其msking,其输入为Q,K,不是Q_ ,K_ ,shape为[N,T_q,num_units],具体步骤1.将此矩阵按照第2维度相加起来,key_masks = tf.sign(tf.abs(tf.reduce_sum(keys, axis=-1))) # (N, T_k) 得到[N,T_q],(这个矩阵只可能是0和1,0是被pading为0的,1就是具有信息字词),然后再经过key_masks = tf.tile(key_masks, [num_heads, 1]) 复制,得到shape为 (hN, T_k),然后增加其一个维度,key_masks = tf.tile(tf.expand_dims(key_masks, 1), [1, tf.shape(queries)[1], 1]) 得到shape为(hN, T_q, T_k),目的就是为了和之前的outputs一样。paddings = tf.ones_like(outputs)(-2**32+1)
outputs = tf.where(tf.equal(key_masks, 0), paddings, outputs)这两行的目的就是利用tf.where()这个额函数将padding的向量置为非常非常小的数字,这样就间接的忽略了padding对总体的影响。按照相同的方法将Q也是这样
13. 运用三角矩阵方法,在解码的时候,可以选择是否屏蔽未来的信息
14. 进行droup_out,开始用V_的权值 * V_得到输出,outputs = tf.matmul(outputs, V_) # ( h
N, T_q, C/h)
15. 将这个shape再重写 outputs = tf.concat(tf.split(outputs, num_heads, axis=0), axis=2 ) 得到一个和输入一样的shape (N, T_q, C),然后再进行残差连接 和normal ,outputs += queries,outputs = normalize(outputs) # (N, T_q, C),得到的最终结果和输入时一样,方便进行循环,并且输入给全连接层。
!!!小总结:以上4-9就是多头注意力机制+add,norm的部分
16. 全连接层,该层的输入也就是上面的多头注意力最后的输出outputs,输入层==》隐藏层outputs = tf.layers.conv1d(**params)隐藏层到输出层
params = {“inputs”: outputs, “filters”: num_units[1], “kernel_size”: 1,“activation”: None, “use_bias”: True};outputs = tf.layers.conv1d(**params),然后再经过残差连接+normal,就得出来shape为[N,T_k,C],encode的输出
!!!以上4-10表示的就是就是完整的encode的部分了,需要循环8次!!!

二. decode部分
其实decode和encode差不多,不过比encode多一个带有mask的self_attention机制
1.作为decode的输入,训练和预测是不一样的,A.在训练的时候,直接将目标语言拿过来,通过masked进行遮盖未来信息,即在t时刻时,其输入时目标句子t-1时刻的所有信息,在经过多头注意力机制,输出一个Q,当做下一个多头机制的三个输出之一。这也是为什么Q就相当于前一时刻(也就是t时刻之前的所有时刻)的输出,然后再跟当前时刻的输入进行注意力计算。B.而在预测的时候,由于源语言是随意的,所以就没有所谓的标准答案(目标语言),只能讲上一时刻的输出当做decode的输入
2.经过embeding,再经过pos_embeding,得到Q,K,V。跟encode一样,只是未来信息贝遮掩了,然后得到输出当做下一时刻的输入的Q。而encode的输出当做下一时刻的K,V,经过多头注意力机制,得到一个输出。然后再经过全连接层,经过一个线性转换,在通过softmax的输出一个概率结果
3.quey就是multihead的输入x,key、value是输入x经过不同线性变换(比如,1X1的卷积)得到的不同值,用于计算query中每个词的权重(self attention)

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值