type
status
date
slug
summary
tags
category
icon
password
这节课主要讲神经网络如何处理序列信息, 或者如何对数据序列建模
Neurons with Recurrence
处理独立时间步 Handling Individual Time Steps

这里的图表展示了处理独立时间步的情况: 用函数 f 处理单个时间步 x, 得到对应的 y
然而, 这种处理方式中, 我们忽略了序列数据中的一个特点: 每个 y 值都依赖于之前的不止一个时间步
循环的神经元 Neurons with Recurrence

为了解决刚才说的问题, 我们把神经网络中的计算历史/隐藏状态存储为 h, 并将其作为变量参与到 y 的预测中
左图形象的表现了维持循环状态的特点
循环神经网络 RNN

这里的 h 接受 x 与先前的 h 作为输入, 经过一个函数变换, 得到新的值.
RNN 状态的更新与输出

这里做出了一些改动, 由于我们的 已经是 和 的函数了, 因此直接在 的基础上计算 即可
计算图

此处需要区分一下 , , 三个矩阵. 第一个是从 input 到隐藏状态的参数矩阵, 第二个是从隐藏状态进行迭代的矩阵, 第三个是从 h 计算 y 的矩阵.
期中, 前两个参与更新 h, 最后一个参与更新 y
序列建模
在序列建模时需要注意的点:
- 处理长度多变的序列
- 跟踪长期依赖(某些 y 可能与很久之前的 x 有关)
- 保持序列的有序
- 在序列中共享参数
预测词语
向量化 Vectorize
为了把单词序列 (其实就是句子) 传入神经网络, 我们需要把其中的词语向量化, 转化成对应的向量, 使得数据得以被神经网络处理
独热向量 onehot
一个选择是可以把词语映射成 n 维的的独热向量, n 为所有词语的数量
仔细想想就可以知道, 这在实际应用中并不现实, 因此采用另一种映射方法: 嵌入向量 embedding
嵌入向量 embedding
嵌入向量使用一个矩阵来进行词语到向量间的映射, 并通过训练更新矩阵的权重, 使得最终的向量在语义空间中有比较出色的表现
关于这两种向量化的方式, 具体可以参照 zero to hero 的笔记
[[../NN Zero to Hero/Makemore - part 1]]
通过时间反向传播 Back Propagation Through Time
通过时间的反向传播
既然是训练模型, 我们就需要通过 BP 来计算梯度, 以便后续的更新迭代
以下是 RNN 的正向传播和反向传播计算图, 由于 h 作为隐藏状态, 参考之前的状态在时间尺度上不断迭代.
因此可以看到这里传到 h 后涉及延时间传播的情况, 因此又被称作通过时间的反向传播

需要注意的是, 这里的在沿着 loss 传播到 h 之后, 这个 h 需要继续往之前的 h 传, 因此会产生一长串的梯度相乘
梯度消失/爆炸
超长的链式乘法显然不是一件好事, 因为万一遇到多个大数/小数相乘, 可能导致这个梯度的值出现极端情况:
- 当梯度过大时, 称为梯度爆炸
- 当梯度过小时, 称为梯度消失 因此, 在 RNN 网络中追踪长期的依赖关系变得很困难, 需要做出一些调整
新的网络架构
为了解决梯度消失/爆炸的问题, 有一些新的网络结构出现, 他们的调整主要是让 RNN 中的基本单元增加一些新功能, 使得其能够有选择性的传递用于更新隐藏状态的信息
其中, 比较有名的架构有:
- LSTM (Long Short Term Memory 长短期记忆网络)
- GRU (Gated Recurrent Unit 门控循环神经网络)
RNN 的应用与局限
局限
有限的隐藏状态
这里主要指的是 RNN 当中的隐藏状态向量长度是固定的, 因此只能存储有限数量的信息, 对于网络的大小和信息量产生了限制
训练慢, 无法并行计算
由于 RNN 网络中 h 依赖先前的 h, 因此无法实现并行计算, 这会导致模型训练缓慢
无法长期记忆
以上两点共同造成无法实现长期记忆, 但是我没太懂第二点跟这个有啥关系
我倒是觉得梯度的链式乘法是一个主要原因之一
尝试 : 把时间步合并输入
如果尝试把时间步合并成一个向量放进网络中, 是否会解决一些问题呢?
- 确实不需要循环了
- 但是也没有了顺序的概念, 这对于依赖顺序的序列有很大的影响
- 可扩展性差 : 只能用在特定长度的序列上
- 因此, 也没有了长期记忆
于是, 一个想法产生 : 能否设计一种算法, 能够让网络识别有用的, 重要的部分, 并据此建立序列的联系
Attention 注意力机制
为了实现刚才的想法, 我们需要把任务拆解为两部分:
- 识别哪一部分更值得关注
- 从 attention 高的部分提取特征
Q K V
在这里我们可以把 attention 相关的计算转化成一个查找问题
Q : Query 查询 K : Key 关键字 V : Value 关注部分的特征
- 首先我们提出一个问题 Q, 来寻找问题的答案
- 根据各个部分的 K, 我们可以通过比较 Q 和 K 获得相似度来得到 attention 的大小
- 根据 attention 的大小, 确定哪些部分更重要, 在这些部分中寻找特征 V
神经网络中的自注意力机制
目标 : 识别并关注输入中最重要的特征
对位置信息编码
这里引入一个位置编码 Positional Embedding , 其实和之前的嵌入向量很像, 只是这里是将序列输入转化为含有位置/顺序信息的向量
提取用于搜索的 QKV
这里将线性层经过位置编码映射, 得到对应的 QKV 值
这里的三个线性层分别对应的是 QKV 的参数矩阵, 是从模型的训练中学习出来的

计算注意力权重
我们将计算得到的 Q , K 向量比较相似度, 来判断"关键字是否符合问题", 进而确定 attention 的权重
关于如何比较向量的相似度, 我们将 Q, K 向量做点乘, 并加以缩放, 得到量化的"相似度"
然后, 使用 Softmax, 把数值压缩到零到一之间
相似度?
这里通过点乘, 其实就是相当于投影, 量化 Q, K 的相似度
这种做法同时考虑了方向和长度的影响
缩放?
我一开始以为缩放是为了统一向量长度, 只考虑方向
后来发现这个缩放是为了后续的 Softmax 准备的, 让进入激活函数前的数值在合理的区间内
更正:这个机制的全名叫做:Scaled Dot-Product Attention
其中, scaling 的具体取值应该为
其中, 是维度
为什么除以 $d_{k}$
- 如果不缩放,那么在维度 dkdk 很大的时候,点积结果的方差会变大;
- 导致 Softmax 的梯度区域变“尖”,模型训练变得不稳定;
- 因此除以 dkdk 可以让点积保持在一个较合理的数值范围,进入 Softmax 前不会太大也不会太小;
为什么和 $d_{k}$ 有关
点积的方差会随着维度增大而变大
点积的值的方差是维度的线性函数:∼dk,因此维度越高,点积越大。
提取具有高注意力权重的特征
运用刚才计算出的 Attention, 与 Value 矩阵相乘, 得到最终的输出, 实现特征提取

Transformer

注意力块是 transformer 架构的最基础的元件
自注意力机制的应用
- 语言处理 : BERT, GPT
- 生物序列 : 蛋白质结构模型
- 计算机视觉 : Vision Transformer
感谢群友的指正!

- 作者:昊卿
- 链接:hqhq1025.tech/article/6.S191_lec2
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章