深度学习架构Seq2Seq-添加并理解注意力机制(一)
第一章:人工智能之不同数据类型及其特点梳理
第二章:自然语言处理(NLP):文本向量化从文字到数字的原理
第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码)
第四章:循环神经网络RNN、LSTM以及GRU 对比(附代码)
第五章:理解Seq2Seq的工作机制与应用场景中英互译(附代码)
第六章:深度学习架构Seq2Seq-添加并理解注意力机制(一)
第七章:深度学习架构Seq2Seq-添加并理解注意力机制(二)
本文主要是分析Seq2Seq 架构本身具有的缺点,并分析针对长序列输入时,导致信息丢失这一问题,造成这个问题的原因,以及针对这一问题,通过引入注意力机制,如何来解决这一问题。
一、Seq2Seq简介
Seq2Seq(Sequence to Sequence)模型是一种深度学习架构,主要用于处理输入和输出均为可变长度序列的任务,如机器翻译、文本摘要和语音识别等。其核心结构包含两部分,编码器(Encoder)和 解码器(Decoder),如下图所示,输入是英文单词 ‘like’ 翻译成中文 ‘喜欢’
- 编码器(Encoder):通常由RNN、LSTM或GRU等循环神经网络构成,负责将输入序列逐步编码为一个固定长度的上下文向量(Context Vector),该向量综合了输入序列的整体语义信息。
- 解码器(Decoder):同样基于循环神经网络,接收编码器生成的上下文向量作为初始输入,逐步生成输出序列的每个元素。训练时常用“教师强制”(Teacher Forcing)方法,即将前一步的真实输出作为当前步的输入以提高稳定性。
Seq2Seq模型的特点在于处理变长序列时无需严格对齐输入与输出的长度,例如将中文句子翻译为英文时,输出长度可灵活变化。
二、普通 Seq2Seq 的局限性
普通 Seq2Seq 模型将输入序列压缩为 单一的上下文向量(Encoder 的最后一个隐藏状态,就是上图中的Context Vector),存在以下问题:
- 信息瓶颈:长序列输入时,单一向量难以保留所有细节,即整个输入序列被压缩成一个固定大小的向量上下文向量,可能导致信息丢失。
- 长距离依赖丢失:解码器无法灵活关注输入序列的不同部分。
- 速度慢:训练速度较慢且难以并行化。
在Seq2Seq模型中,编码器将整个输入序列压缩成一个固定大小的向量(即上下文向量或语义向量),然后解码器使用这个向量来生成输出序列。这种做法存在几个潜在的问题,尤其是当处理较长的输入序列时,可能会导致信息丢失。
输入序列太长,为什么会导致信息丢失?
-
固定维度限制:无论输入序列有多长,上下文向量的维度都是固定的。这意味着如果输入序列非常长,编码器需要将大量信息压缩到一个有限维度的空间里。这就像试图将一本书的内容压缩进一句话中一样,不可避免地会丢失一些细节和细微差别。
-
信息覆盖问题:对于某些复杂的任务,如长文本翻译或对话系统,源序列可能包含多个主题、观点或重要细节。由于上下文向量的容量有限,编码器可能无法有效地表示所有这些信息,从而导致关键信息被忽略或覆盖。
举例说明
假设我们有一个中文句子“我喜欢吃鱼,特别是新鲜的鲑鱼,它富含Omega-3脂肪酸,对心脏健康有益”,我们要将其翻译成英文。
-
没有注意力机制的情况:编码器尝试将这句话的所有信息压缩成一个固定大小的向量。然而,这句话包含了多个部分的信息——个人偏好(喜欢)、食物类型(鱼)、具体种类(鲑鱼)、营养成分(Omega-3脂肪酸)以及健康益处(对心脏健康有益)。如果输入序列过长或者信息过于复杂,那么单一的上下文向量很可能无法承载这么多不同的信息点。结果,在解码阶段,解码器可能难以准确地再现原句的所有细节,可能会遗漏一些重要的内容,例如忘记提及“Omega-3脂肪酸”或是“对心脏健康有益”。
-
有注意力机制的情况:在这种情况下,每当解码器准备生成下一个单词时,它不仅依赖于前一时刻的状态,还能够通过注意力机制直接访问输入序列的不同部分。这样,即使输入序列很长,解码器也能够根据当前生成的内容需求,选择性地关注最相关的信息。比如,在生成关于鲑鱼营养价值的部分时,它可以特别关注与“Omega-3脂肪酸”相关的输入部分;而在提到饮食喜好时,则可以更侧重于“我喜欢吃鱼”这部分的信息。因此,注意力机制大大提高了模型处理长距离依赖关系的能力,并且减少了信息丢失的可能性。
固定大小的上下文向量在处理长或复杂序列时面临信息丢失的风险,因为它们不能完全捕捉并保留原始输入序列中的全部信息。引入注意力机制是解决这一问题的有效方法之一。
三、注意力机制的核心思想
注意力机制 允许解码器在每个时间步动态关注输入序列的 相关部分,而非依赖单一向量。其核心流程如下:
- 编码器输出 所有时间步的隐藏状态(而非仅最后一步)。
- 解码时,计算解码器当前状态与所有编码器状态的 相似度,生成注意力权重。
- 根据权重 加权求和编码器状态,生成动态上下文向量。
- 将动态上下文向量与解码器输入结合,预测当前输出。
四、实现步骤
4.1 编码器处理输入序列
- 输入序列: X = ( x 1 , x 2 , … , x T ) \mathbf{X} = (x_1, x_2, \dots, x_T) X=(x1,x2,…,xT)
- 编码器输出:所有时间步的隐藏状态 { h 1 , h 2 , … , h T } \{h_1, h_2, \dots, h_T\} {h1,h2,…,hT}
4.2 计算注意力权重
在解码器的第 t t t 步:
-
解码器当前隐藏状态: s t − 1 s_{t-1} st−1(上一步的隐藏状态)
-
编码器所有隐藏状态: { h 1 , h 2 , … , h T } \{h_1, h_2, \dots, h_T\} {h1,h2,…,hT}
-
计算相似度(注意力分数):
e t i = score ( s t − 1 , h i ) e_{ti} = \text{score}(s_{t-1}, h_i) eti=score(st−1,hi)
常用相似度计算方式:- 点积(Dot Product): e t i = s t − 1 ⊤ h i e_{ti} = s_{t-1}^\top h_i eti=st−1⊤hi
- 加性(Additive): e t i = v ⊤ tanh ( W s s t − 1 + W h h i ) e_{ti} = \mathbf{v}^\top \tanh(\mathbf{W}_s s_{t-1} + \mathbf{W}_h h_i) eti=v⊤tanh(Wsst−1+Whhi)
-
归一化为权重:
α t i = exp ( e t i ) ∑ j = 1 T exp ( e t j ) \alpha_{ti} = \frac{\exp(e_{ti})}{\sum_{j=1}^T \exp(e_{tj})} αti=∑j=1Texp(etj)exp(eti)
4.3 生成动态上下文向量
c t = ∑ i = 1 T α t i h i \mathbf{c}_t = \sum_{i=1}^T \alpha_{ti} h_i ct=∑i=1Tαtihi
4.4 结合上下文向量生成输出
- 拼接解码器状态与上下文向量:
s ~ t = tanh ( W c [ s t − 1 ; c t ] + b c ) \tilde{s}_t = \tanh(\mathbf{W}_c [s_{t-1}; \mathbf{c}_t] + \mathbf{b}_c) s~t=tanh(Wc[st−1;ct]+bc) - 预测输出概率分布:
p ( y t ∣ y < t , X ) = Softmax ( W o s ~ t + b o ) p(y_t | y_{<t}, \mathbf{X}) = \text{Softmax}(\mathbf{W}_o \tilde{s}_t + \mathbf{b}_o) p(yt∣y<t,X)=Softmax(Wos~t+bo)
4.5 数学公式总结
对于解码器的第 t t t 步:
Attention Weights: α t i = Softmax ( score ( s t − 1 , h i ) ) Context Vector: c t = ∑ i = 1 T α t i h i Decoder Output: p ( y t ∣ y < t , X ) = Softmax ( W o ⋅ tanh ( W c [ s t − 1 ; c t ] + b c ) ) \begin{aligned} \text{Attention Weights:} \quad & \alpha_{ti} = \text{Softmax}(\text{score}(s_{t-1}, h_i)) \\ \text{Context Vector:} \quad & \mathbf{c}_t = \sum_{i=1}^T \alpha_{ti} h_i \\ \text{Decoder Output:} \quad & p(y_t | y_{<t}, \mathbf{X}) = \text{Softmax}(W_o \cdot \tanh(W_c [s_{t-1}; \mathbf{c}_t] + b_c)) \end{aligned} Attention Weights:Context Vector:Decoder Output:αti=Softmax(score(st−1,hi))ct=i=1∑Tαtihip(yt∣y<t,X)=Softmax(Wo⋅tanh(Wc[st−1;ct]+bc))
4.6 理解点积(Dot Product)
点积(Dot Product),也被称为内积(Inner Product),是向量之间的一种二元运算,在数学、物理学以及工程学中有着广泛的应用。
对于两个维数相同的向量 a = [ a 1 , a 2 , . . . , a n ] \mathbf{a} = [a_1, a_2, ..., a_n] a=[a1,a2,...,an] 和 b = [ b 1 , b 2 , . . . , b n ] \mathbf{b} = [b_1, b_2, ..., b_n] b=[b1,b2,...,bn],
它们的点积定义为:
a ⋅ b = ∑ i = 1 n a i b i = a 1 b 1 + a 2 b 2 + . . . + a n b n \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1b_1 + a_2b_2 + ... + a_nb_n a⋅b=∑i=1naibi=a1b1+a2b2+...+anbn
即,两个向量的点积等于对应元素相乘后的和。
几何解释
点积还有一个重要的几何意义,即两个向量的点积等于它们的模长乘积与它们之间夹角余弦值的乘积:
a ⋅ b = ∣ a ∣ ∣ b ∣ cos θ \mathbf{a} \cdot \mathbf{b} = |\mathbf{a}| |\mathbf{b}| \cos{\theta} a⋅b=∣a∣∣b∣cosθ
这里, ∣ a ∣ |\mathbf{a}| ∣a∣ 和 ∣ b ∣ |\mathbf{b}| ∣b∣ 分别表示向量 a \mathbf{a} a 和 b \mathbf{b} b 的长度(或称为模),而 θ \theta θ 是两向量之间的夹角。通过这个公式,我们可以看出点积可以用来计算两个向量之间的角度,或者判断它们是否正交(如果点积为零,则两向量垂直)。
在机器学习和深度学习领域,点积常用于衡量向量间的相似度。例如,在注意力机制中,它被用来计算查询向量与键向量之间的匹配程度。
4.7 理解加性(Additive)
在深度学习和自然语言处理的上下文中,“加性”(Additive)通常指的是“加性注意力机制”,这是一种用于序列到序列(Seq2Seq)模型中的注意力计算方法。与点积注意力(Dot-Product Attention)不同,加性注意力使用了一个小型的前馈神经网络来计算输入序列中每个位置的注意力分数。
加性注意力机制的工作原理
其主要思想是通过一个小型的两层前馈神经网络来计算注意力权重,这个过程可以分解为以下几个步骤:
-
输入准备:对于解码器中的每一个时间步 t t t,我们考虑编码器的所有隐藏状态 { h 1 , h 2 , . . . , h n } \{h_1, h_2, ..., h_n\} {h1,h2,...,hn} 和当前解码器的隐藏状态 s t − 1 s_{t-1} st−1。
-
能量计算:将编码器的每个隐藏状态 h i h_i hi 和解码器隐藏状态 s t − 1 s_{t-1} st−1 作为输入,传递给一个小的前馈神经网络。这个网络通常包含一层或多层,并使用tanh作为激活函数。具体来说,计算能量值 e t i e_{ti} eti 的公式如下:
e t i = v T tanh ( W [ h i ; s t − 1 ] ) e_{ti} = v^T \tanh(W[h_i; s_{t-1}]) eti=vTtanh(W[hi;st−1])
其中, W W W 是权重矩阵, v v v 是输出向量, [ h i ; s t − 1 ] [h_i; s_{t-1}] [hi;st−1] 表示向量拼接操作。
-
注意力权重计算:对上述得到的能量值进行Softmax变换,以确保所有注意力权重之和为1。即,
α t i = exp ( e t i ) ∑ j exp ( e t j ) \alpha_{ti} = \frac{\exp(e_{ti})}{\sum_j \exp(e_{tj})} αti=∑jexp(etj)exp(eti) -
上下文向量生成:根据计算出的注意力权重对编码器的所有隐藏状态进行加权求和,得到上下文向量 c t c_t ct:
c t = ∑ i α t i h i c_t = \sum_i \alpha_{ti} h_i ct=∑iαtihi
-
结合上下文向量与解码器状态:最后,上下文向量 c t c_t ct 被用来辅助解码器预测下一个词,通常会与当前解码器的状态结合起来。
加性注意力 vs 点积注意力
- 复杂度:加性注意力通常比点积注意力更复杂,因为它需要额外的参数和非线性变换(如tanh激活函数)。然而,它也提供了更大的灵活性来捕捉输入之间的复杂关系。
- 适用场景:点积注意力在高维度空间中更加高效,因为它的计算可以直接利用矩阵乘法加速;而加性注意力可能更适合于那些需要更多非线性处理的任务或数据集。
下一篇《深度学习架构Seq2Seq-添加并理解注意力机制(二)》使用中文翻译成英文的案例,“我喜欢吃鱼” 翻译为 “I like eating fish” 的简单例子,通过具体的数字,模拟模型推理过程,来辅助解释上面这一套公式。
相关文章:

深度学习架构Seq2Seq-添加并理解注意力机制(一)
第一章:人工智能之不同数据类型及其特点梳理 第二章:自然语言处理(NLP):文本向量化从文字到数字的原理 第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码) 第四章:循环神经网络RNN、LSTM以及GR…...
Kafka底层结构
1. Kafka 架构总览 Kafka 是一个分布式消息队列,采用**发布-订阅(Pub-Sub)**模式,核心组件包括: Producer(生产者): 负责向 Kafka 发送消息。Broker(Kafka 服务器&…...

[BUUCTF]web--wp(持续更新中)
ps:文章所引用知识点链接,如有侵权,请联系删除 [极客大挑战 2019]EasySQL 题目类型:简单SQL注入 发现是登录页面,用万能登录方法测试,两种语句均能解出flag [极客大挑战 2019]Havefun 题目类型:代码审计…...
axios请求设置request umijopenai生产前端请求 ts状态全局 v-if v-else 与动态js变量
axios请求 安装 npm install axios全局自定义请求 集中处理设置 集体通用请求 example const instance axios.create({baseURL: https://some-domain.com/api/,timeout: 1000,headers: {X-Custom-Header: foobar} });请求前 请求后 拦截器 // 添加请求拦截器 axios.in…...

SparkSQL全之RDD、DF、DS ,UDF、架构、资源划分、sql执行计划、调优......
1 SparkSQL概述 1.1 sparksql简介 Shark是专门针对于spark的构建大规模数据仓库系统的一个框架Shark与Hive兼容、同时也依赖于Spark版本Hivesql底层把sql解析成了mapreduce程序,Shark是把sql语句解析成了Spark任务随着性能优化的上限,以及集成SQL的一些…...

深入理解Linux内存缓存:提升性能的关键
在深入探索 Linux 系统的奇妙世界时,内存管理无疑是一个至关重要的领域。而在 Linux 内存体系中,Cache 扮演着举足轻重的角色。它就像是一位默默奉献的幕后英雄,为系统的高效运行立下汗马功劳。那么,Linux 内存中的 Cache 究竟是什…...
STM32-FOC-SDK包含以下关键知识点
STM32-FOC-SDK(Field-Oriented Control - Software Development Kit)是专为STM32微控制器设计的一套软件开发工具,用于实现电机控制的磁场定向控制(Field Oriented Control,简称FOC)。STM32是一款基于ARM C…...

sql调优:优化响应时间(优化sql) ; 优化吞吐量
Sql性能调优的目的 1.优化响应时间>>优化sql 经过调优后,执行查询、更新等操作的时候,数据库的反应速度更快,花费的时间更少。 2.优化吞吐量 即“并发”, 就是“同时处理请求”的能力。 优化sql 尽量将多条SQL语句压缩到一句>…...

【Mybatis】如何简单使用mybatis-plus,以及MybatisGenerator自动生成或者实现SQL语句
前言 🌟🌟本期讲解关于mybatis中SQL自动生成的相关知识介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆…...

Halcon 车牌识别-超精细教程
车牌示例 流程: 读取图片转灰度图阈值分割,找车牌内容将车牌位置设置变换区域形状找到中心点和弧度利用仿射变换,斜切车牌旋转转正,把车牌抠出来利用形态学操作拼接车牌号数字训练ocr开始识别中文车牌 本文章用到的算子(解析) Halcon 算子-承接车牌识别-CSDN博客 rgb1_to_gray…...
LeetCode 25 - K 个一组翻转链表
LeetCode 25 - K 个一组翻转链表 这道题是一个典型的链表操作题,考察我们对链表的精确操作,包括反转链表、分组处理、递归和迭代的结合应用等。还可以通过变体问题延伸到优先队列操作、归并、分块等,这使得它成为面试中的高频考题之一。 题目…...
一文读懂智能硬件定位:开启智能时代的精准导航
一、智能硬件定位是什么 (一)基本概念阐述 智能硬件定位,本质上是智能硬件依托一系列特定技术手段,精准测定自身所处地理位置的过程。这一实现过程离不开诸多关键技术的支撑。传感器堪称其中的 “排头兵”,像加速度计…...

夸父工具箱(安卓版) 手机超强工具箱
如今,人们的互联网活动日益频繁,导致手机内存即便频繁清理,也会莫名其妙地迅速填满,许多无用的垃圾信息悄然占据空间。那么,如何有效应对这一难题呢?答案就是今天新推出的这款工具软件,它能从根…...
Html5学习教程,从入门到精通,HTML5 列表语法知识点及案例代码(11)
HTML 列表语法知识点及案例代码 一、HTML 列表类型 HTML 提供了三种列表类型: 无序列表 (Unordered List):使用 <ul> 标签定义,列表项使用 <li> 标签定义。默认情况下,列表项前面会显示黑色圆点。有序列表 (Ordere…...

内核进程调度队列(linux的真实调度算法) ─── linux第13课
目录 内核进程调度队列的过程 一个CPU拥有一个runqueue(运行队列在内存) 活动队列(active) 过期队列(expired) active指针和expired指针 重绘runqueue linux内核O(1)调度算法 总结 补充知识: 封装链式结构的目的是: 仅使用封装链式结构可以得到全部的task_struct的信…...
16.7 LangChain LCEL 极简入门:Prompt + LLM 的黄金组合
LangChain LCEL 极简入门:Prompt + LLM 的黄金组合 关键词:LCEL 基础示例、Prompt 模板设计、LLM 集成、链式调用、LangChain 快速上手 1. 基础架构解析:Prompt → LLM → Output 1.1 核心组件交互流程 #mermaid-svg-pv3fH3mEKyE4TNaF {font-family:"trebuchet ms&qu…...

Spring线程池学习笔记
Spring提供了多种方式来配置和使用线程池,最常见的是通过TaskExecutor和ThreadPoolTaskExecutor。 Spring线程池 TaskExecutor 接口 TaskExecutor 是Spring框架中的一个接口,它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口…...

ArcGIS操作:08 计算shp面积并添加到属性表
1、打开属性表 注意:计算面积前,需要把shp的坐标系转化为投影坐标系(地理坐标系用于定位、投影坐标系用于测量) 2、创建字段 3、编辑字段名、类型 4、选择字段,计算几何 5、选择属性、坐标系、单位...
安卓音频框架混音器
在 Android 音频框架中,混音器(Mixer) 是 AudioFlinger 服务的核心组件之一,负责将多个音频流(来自不同应用或系统组件)混合为统一的输出流,再传输到音频硬件设备(如扬声器、耳机等&…...
左值引用与指针的区别
很多朋友遇到过这个问题:左值引用与指针有哪些区别?脑子里闪过很多答案,但大部分都是各自的定义,真要说他们两个有什么区别,有的时候还这是说不上来。本文针对这个问题进行归纳总结,希望对大家有所帮助。 …...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...