MultiHeadAttention在Tensorflow中的实现原理


前言

通过这篇文章,你可以学习到Tensorflow实现MultiHeadAttention的底层原理。


一、MultiHeadAttention的本质内涵

1.Self_Atention机制

MultiHeadAttention是Self_Atention的多头堆嵌,有必要对Self_Atention机制进行一次深入浅出的理解,这也是MultiHeadAttention的核心所在。

Self_Attention并不直接使用输入向量,而是先将其进行映射,使得输入向量在每个位置上产生一个query和context,context充当字典。在context的每个位置都提供一个key和value向量。

query:尝试去获取某类信息的序列。

context:包含key序列和value序列,是query感兴趣的内容。

最终输出的形状将与query序列相同。

一个常见的类比是,这种操作就像字典查询。一个模糊的、可区分的、矢量的字典查询。

如下是一个普通的 python 字典类型数据,有 3 个键和 3 个值,并被传递给一个query——"What color is it ?"。这个query会与key="color"最契合,最终得到查询结果value="blue"

query是你要尝试去找的东西。key表示字典里有哪些信息,而value就是这些信息。当你在正则字典中查找一个query时,字典会找到匹配的key,并返回其相关的value。这个查询要么有一个匹配的键,要么没有。你可以想象一个模糊的字典,其中的键不一定要完全匹配。如果你在上面的字典中查找 query—"What species is it ?",也许你希望它返回 key="type",value="pickup",因为那是与query最匹配的key和value。

注意力层就像这样做了一个模糊查找,但它不仅仅是在寻找最好的key,而是根据query与每个key的匹配程度来组合这些value。

那是如何做到这一点的呢?在注意力层中,query、key和value都是向量。注意力层不是简单地做哈希查找,而是结合query和key向量来确定它们的匹配程度——计算query和key的向量点积,再将所有匹配程度经过Softmax映射完后,即得到 "注意力得分"。最终该层返回所有value的加权平均值,以 "注意力分数 "为权重。

对于一段具体的文本来说,每一个字都会引发一个疑问query,并提供一个关键值key和一个目标内容value。每个query都会去寻找感兴趣的key,并按注意力分数提取并组合value,

图中越粗的红线对应的attention权重更大,query与key的紧密程度也越近。attention权重如此分布也是很符合情理的,要想回答query =“他是谁?”,我们很大可能会在“是”后面寻找答案,因为“爱人”提供的信息最多,所以它俩的attention权重最大。

总的来说,Self_Attention模拟的是一个符合人脑思维逻辑的研究过程。每当遇到一些新的信息,我们总会产生一定量的疑问(query),为了解决疑问,我们需要在信息中捕捉关键字(key),进而凝练出该关键字中所蕴涵的答案(value)。特定的疑问(query)需要联系特定的关键字(key),进而得出最终答案,这个最终答案往往是折合了不同value而得来的。

2.MultiHead_Atention机制

在不同情景中,字引发的query是不同的,例如,

“他是男的,已婚。”

query可以是”他的性别是什么?”,或者”他结婚了吗?”。不同的query会产生不同的注意力分数。单一的Self_attention无法捕捉多层面query和key之间的依赖关系,因为它只进行一次attention的分配。意在解决此类局限性,MultiHead_Atention会计算多次Self_attention。

利用MultiHead_Atention机制,可以为每一个输入学习到一个信息量丰富的向量表示。

二、使MultiHeadAttention在TensorFlow中的代码实现

1.参数说明

TensorFlow中是用tf.keras.layers.MultiHeadAttention()实现的。它的参数分为两类,一种参数为初始化参数,存在于__init__方法中;另一种为调用参数,存在于call方法中。

主要的初始化参数:

num_heads:Self_Attention的层数

key_dim:query和key多头映射层的输出shape在axis=-1上的长度。因为后续需要计算query和key的点积,所以需要保证query和key在最后一个轴上的长度相等。

value_dim:value多头映射层的输出shape在axis=-1上的长度。如果不指定,则默认等于key_dim

output_shape:  指定输入经过整个MultiHeadAttention层后的输出shape,默认与进入query多头映射层的输入shape相同

主要的call方法参数:

'''  B即Batch_size,每一批中的样本数;

    T是query的个数,即一段序列产生的疑问个数;S是value和key的个数,即一段序列产生的关键字和关键信息的个数,序列产生的key和value是成对出现的,所以value映射层 和key映射层的输入张量在axis=1处的长度S相同。T和S是可以随意指定的,只需在样本集进入Embedding层之前,先通过一个dense层进行T和S的指定(T和S等于各自dense层中的神经元个数)。例如,文本集shape=(B, S),经过一个具有T个神经元的Dense层→shape=(B, T),再经Embedding层→shape=(B, T, dim),得到query映射层的输入张量。当然,如果不愿如此麻烦,可直接将经Embedding层得到shape=(B, S, dim)的张量作为query映射层的输入;

    dim通常是Embedding向量的长度(每个字对应一个Embedding向量)'''

query:输入query多头映射层且shape为(B, T, dim)的张量

value:输入value多头映射层且shape为(B, S, dim)的张量

key:输入key多头映射层且shape为(B, S, dim)的张量,如果未指定,则key=value

use_causal_mask:布尔值,是否开启causal_mask(因果掩码)机制

2.整体结构

tf.keras.layers.MultiHeadAttention类中call()方法的逻辑过程就是MultiHeadAttention的前向传播过程,我将其提炼成以下三部分,

        ''' 多头映射层 '''query = self._query_dense(query)key = self._key_dense(key)value = self._value_dense(value)''' 注意力层 '''attention_output, attention_scores = self._compute_attention(query, key, value, attention_mask, training)''' 输出层 '''attention_output = self._output_dense(attention_output)

3.多头映射层

由query多头映射层—query_dense,value多头映射层—value_dense,key多头映射层—key_dense组成。

每个映射层执行的张量运算是一样的,张量运算逻辑为,

                                                   ' abc , cde -> abde '               



该层的训练参数总数为,

4.注意力层

计算query与key之间的内积,张量运算逻辑为,

                                              ' aecd, abcd -> acbe '

内积能够反映向量之间的相关程度,内积结果越大则相关性越大,联系也越紧密。得到query和key的内积后,为了得到attention分数,需要将内积结果进行softmax映射。

sttention_scores张量可视作一个B行num_heads列的矩阵,其矩阵中的元素均是T行S列的注意力分数矩阵。当输入是大序列(比如音频序列)时,TransFormer需要维护的注意力分数矩阵将呈n^{2}曲线式增长,这种庞大的数据量将会对TransFormer训练和推理的效率和速度产生严重的影响,在内存上的要求也会成n^{2}曲线式增长。


最后利用attention分数对value进行加权叠加,张量运算逻辑为,

                                                        'acbe,aecd->abcd' 

  



注意:如果指定use_causal_mask=True引入Causal_Mask(因果掩码)机制,则在softmax映射时,会传入一个左下三角为True右上三角为False的,布尔类型的,且与attention_scores.shape相同掩码张量,此时掩码张量中为False的对应位置(对应attention内积张量)将会被softmax忽略。如此一来就会导致每个query只会与当前及其以前的key进行内积,并不会考虑未来的key。进而导致在每个query处产生的新value只会是当前value与过往value在sttention分数上的加权叠加。这样的结构是因果的,符合在预测中结果会对输入产生影响的因果逻辑。因果掩码会在Decoder中使用。


注意力层无可训练的参数。

5.输出映射层

属于MultiHeadAttention的最后一层,负责将注意力层得到的value在sttention分数上的加权叠加后的张量进行输出映射。张量运算逻辑为,

                                                       ' abcd, cde -> abe '



该层训练参数总共为,


验证

import tensorflow as tflayer = tf.keras.layers.MultiHeadAttention(num_heads=2, key_dim=2)
target = tf.keras.Input(shape=[9, 16])
source = tf.keras.Input(shape=[4, 16])
output_tensor, weights = layer(query=target, value=source,return_attention_scores=True)''' 手动计算训练参数总数 '''
sum = 16*2*2*3+2*2*3+2*2*16+16
print(f'手动计算的训练参数总数为 : {sum}')
print(f'训练参数总共为 : {layer.count_params()}')
print(f'输出shape为 : {output_tensor.shape}')
print(f'注意力分数shape为 : {weights.shape}')手动计算的训练参数总数为 : 284
训练参数总共为 : 284
输出shape为 : (None, 9, 16)
注意力分数shape为 : (None, 2, 9, 4)

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

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

相关文章

牛客NC357 矩阵第K小【中等 堆 Java、Go、PHP】

题目 题目链接: https://www.nowcoder.com/practice/c754e7a920614cba9b8b692ba9b20b5d 核心 堆,或者叫优先级队列参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改&#xff…

【网站项目】“最多跑一次”小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

微软如何打造数字零售力航母系列科普01 --- Azure顾问(AZURE Advisor)简介

Azure顾问(AZURE Advisor)简介 目录 一、什么是AZURE顾问(AZURE Advisor)? 二、常见问题 三、接下来的步骤 一、什么是AZURE顾问? AZURE顾问是一种数字云助手,可帮助您遵循最佳实践来优化Az…

Java面试八股之marshalling和demarshalling

marshalling和demarshalling Marshalling(序列化)是将内存中的对象状态转化为适合传输或存储的格式(如字节流、JSON、XML),以便进行网络通信、持久化存储或跨平台/语言交互操作。Demarshalling(反序列化&a…

Java Record

Java Record 1.Java Record的作用与特性2.Java Record 如何使用创建和使用RecordRecord 的 MethodRecord 的构造方法Record 的 extends 和 implements 3.Record 和 Lombok4.Record类和java.lang.Class类5.instanceof判断Record类型6.Local Record与嵌套Record Java14 中预览(Ja…

深度学习-优化策略

1.使用众所周知的梯度下降法。 (1).批量梯度下降法:每次参数更新使用所有的样本(2).随机梯度下降法:每次参数更新只使用一次样本(3).小批量梯度下降法:每次参数更新使用…

20.Unity飞机大战游戏

1任务:使背景图动起来 2任务:飞机换帧动画 3任务:让飞机发射子弹 4任务:敌机出现 5任务:控制飞机 6任务:游戏碰撞逻辑 7任务:另外两种类型的敌机 8任务:拾取奖励物品换枪 9…

强固型工业电脑在码头智能闸口、OCR(箱号识别)、集装箱卡车车载电脑行业应用

集装箱卡车车载电脑应用 背景介绍 针对码头集装箱卡车的调度运用, 结合码头TOS系统设计出了各种平台的车载电脑(VT系列)和车载LED显示屏(VLD系列),同时提供各种安装支架,把车载电脑固定到狭小的驾驶室中;同时提供了各种天线选择(…

【Linux】NFS网络文件系统搭建

一、服务端配置 #软件包安装 [roothadoop01 ~]# yum install rpcbind nfs-utils.x86_64 -y [roothadoop01 ~]# mkdir /share#配置文件修改 #格式为 共享资源路径 [主机地址] [选项] # [roothadoop01 ~]# vi /etc/exports /share 192.168.10.0/24(rw,sync,no_root_squash) #…

VBA技术资料MF144:将PDF首页作为对象插入工作表

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

神经网络中的神经元和激活函数介绍

文章目录 1、什么是人工神经网络 2、什么是神经元 3、什么是激活函数 线性激活函数 Sigmoid激活函数 双曲正切激活函数 修正线性单元(ReLU)激活函数 Leaky ReLU激活函数 Softmax激活函数 1、什么是人工神经网络 神经网络能够利用多层神经元学习复杂的模…

AlDente Pro for mac最新激活版:电池长续航软件

AlDente Pro是一款专为Mac用户设计的电池管理工具,旨在提供电池安全和健康管理的一站式解决方案。它具备实时监控电池状态的功能,让用户随时了解电池的电量、充电次数、健康状态等信息。 AlDente Pro for mac最新激活版下载 同时,AlDente Pro…