这里记录一下自己学习embedding大模型的记录,涉及到transformer和bert这些。
一切都可以编码,比如说图片是三原色,所以可以用一些三维矩阵的组合来表示任何一张图,图形越清晰,矩阵越多
背景介绍
训练集和测试集的分,无监督学习,现在基本都是使用无监督学习,有监督学习的话参考计算机视觉,图片进行判断分类来训练模型。
Transformer
首先,可以先了解一下Transformer工作原理的四部曲:Embedding(向量化)、Attention(注意力机制)、MLPs(多层感知机)和Unembedding(模型输出)
Transformer可支持并行计算的一点就是矩阵乘法
mask比率:15%,任务是将这些全部预测,将其中的80%替换成[mask],10%替换成一个随机的token,剩下的10%保留原来的token。这样做可以提高模型的鲁棒性。这个比例也可以自己控制。随机的原因是防止过拟合,为什么呢,比如说机械性的学习,看到my dog 就会输出is hairy,因为第二个句子是有明显错误的,因为
80%的时间是采用[mask],my dog is hairy → my dog is [MASK]
10%的时间是随机取一个词来代替mask的词,my dog is hairy -> my dog is apple
10%的时间保持不变,my dog is hairy -> my dog is hairy
桌上的水杯里有咖啡(正确)
咖啡的水杯里有桌上(错误)
从宏观角度来看,Transformer的编码器是由多个相同的层叠加而成 的,每个层都有两个子层(子层表示为sublayer)。第一个子层是多头自注意力 (multi-head self-attention)汇聚;第二个子层是基于位置的前馈网络 (positionwise feed-forward network)。具体来说,在计算编码器的自注意力时,查询、键和值都来自前一个编码器层的输出。受残差网络的启发,每个子层都采用了残差连接 (residual connection)。在Transformer中,对于序列中任何位置的任何输入x∈Rd,都要求满足sublayer(x)∈Rd,以便残差连接满足x+sublayer(x)∈Rd。在残差连接的加法计算之后,紧接着应用层规范化(layer normalization)。因此,输入序列对应的每个位置,Transformer编码器都将输出一个d维表示向量。
Transformer解码器也是由多个相同的层叠加而成的,并且层中使用了残差连接和层规范化。除了编码器中描述的两个子层之外,解码器还在这两个子层之间插入了第三个子层,称为编码器-解码器注意力 (encoder-decoder attention)层。在编码器-解码器注意力中,查询来自前一个解码器层的输出,而键和值来自整个编码器的输出。在解码器自注意力中,查询、键和值都来自上一个解码器层的输出。但是,解码器中的每个位置只能考虑该位置之前的所有位置。这种掩蔽 (masked)注意力保留了自回归(auto-regressive)属性,确保预测仅依赖于已生成的输出词元。
自注意力这个地方是自己的V、K、Q进行计算,输出得到最终结果。
1、两个序列必须具有相同的维度
2、两个序列可以是不同的模式形态(如:文本、声音、图像)
3、一个序列作为输入的Q,定义了输出的序列长度,另一个序列提供输入的K&V
Cross-Attention 机制涉及到两个不同的序列,其中一个序列的元素作为查询(Query),而另一个序列的元素作为键(Key)和值(Value)。这种机制使得模型能够在处理一个序列时参考另一个序列的信息,从而在两个序列之间建立关联。在Transformer模型的解码器(Decoder)部分中,Cross-Attention被用来让解码器的每个位置都能关注到编码器的输出,这样解码器就可以利用编码器处理后的输入序列信息来生成输出序列。
位置编码
Transformer 放弃了循环结构,而采用了自注意力机制,这使得 Transformer 可以并行计算,从而大大提高了训练速度。同时,自注意力机制也使得 Transformer 可以捕获任意距离的依赖关系,从而解决了长期依赖问题。
但由于 Transformer 不包含任何循环结构,Transformer模型对输入序列中的每个元素进行处理时是并行 的,各个单词在 Transformer 中都同时经过 Decoder-Encoder 的变换,这就导致了 Transformer 无法捕获单词的位置信息。因此,如果没有位置信息,Transformer模型无法区分序列中元素的先后顺序。这样会导致无法识别前后文语境使得相同单词计算得到一样的权重。
为了解决这个问题,需要在输入的单词向量中加入某种信息,以区分每个单词的位置。这一信息被称为位置编码。
因此,一个好的位置编码方式通常需要满足以下条件:
1、它应当为每个时间步(单词在句子中的位置)输出唯一的编码
2、在不同长度的句子中,任何两个时间步之间的距离都应保持一致
3、这个方法应当能够推广到任意长的句子,即位置编码的数值应当是有界的
4、位置编码应当是确定的,即对于相同长度的输入,应当输出相同的位置编码
首先,它不只是一个数字,而是一个d维的向量,包含了句子里某个特定位置的信息;其次,这个编码没有集成到模型本身,而是把这个带有句子位置信息的向量配备进字词当中。换句话说,我们通过注入字词的顺序来加强了模型的输入。
前馈神经网络层
激活函数
这里只介绍两个常见用于transformer场景的激活函数。
ReLU
ReLU 激活函数图像如上图所示,函数表达式如下:
ReLU 函数和softmax都是深度学习中较为流行的一种激活函数,它具有如下优点:
1、当输入为正时,不存在梯度饱和问题。
2、由于ReLU 函数中只存在线性关系,因此它的计算速度比较快。
当然,它也有缺点:
-
Dead ReLU 问题。当输入为负时,ReLU 完全失效,在正向传播过程中,这不是问题。有些区域很敏感,有些则不敏感。但是在反向传播过程中,如果输入负数,则梯度将完全为零,sigmoid 函数和 tanh 函数也具有相同的问题;
-
我们发现 ReLU 函数的输出为 0 或正数,这意味着 ReLU 函数不是以 0 为中心的函数。
Softmax
Softmax 是用于多类分类问题的激活函数,在多类分类问题中,超过两个类标签则需要类成员关系。对于长度为 K 的任意实向量,Softmax 可以将其压缩为长度为 K,值在(0,1)范围内,并且向量中元素的总和为 1 的实向量。
softmax的目的是
Softmax 与正常的 max 函数不同:max 函数仅输出最大值,但 Softmax 确保较小的值具有较小的概率,并且不会直接丢弃。Softmax 函数的分母结合了原始输出值的所有因子,这意味着 Softmax 函数获得的各种概率彼此相关。
Max分类只输出最大的类别索引,没有提供关于模型预测信心的信息,也不考虑类别间的概率分布
Softmax 激活函数的主要缺点是:
-
在零点不可微;
-
负输入的梯度为零,这意味着对于该区域的激活,权重不会在反向传播期间更新,因此会产生永不激活的死亡神经元。
引入温度后的softmax计算函数:
在一些场景中比如阿里的在线大模型服务中经常看到选取温度,温度确实本质上是对softmax产生影响从而影响结果的输出的。当Temperature值较高时,softmax函数的输出会更加平滑,体现在各个类别的概率分布会更加均匀,模型更倾向于给出多样化的输出。相反,当Temperature值较低时,softmax函数的输出会更加尖锐,体现在某个类别的概率会显著高于其他类别,模型更倾向于给出确定的输出。
而温度过高和过低表现都不太好,拿写个故事来说,如果温度过低,那么故事会非常老套,温度过高,就容易说着说着开始胡言乱语,因为本质上这种输出都是通过计算概率最高的那个来获取的,温度高了把合乎逻辑的输出都给盖住了,比如说openai中的温度范围取值是0~2。
下面这个图就表示的非常形象:
编码方式
假设有一堆图书的内容,且已经用嵌入向量表示每本书的内容。想要快速找到与某本书内容最相似的其他书,那么可以:
-
构建索引:将所有书的嵌入向量放到索引中。
-
添加数据:如果有新书加入,可以随时添加到索引中。
-
搜索:用某本书的嵌入向量作为查询,快速找到与之相似的其他书。
嵌入向量(Embeddings):
• 将文本、图片等数据转换成一个向量(即一组数字),这种方式使得计算机可以理解和处理这些数据。例如,将一句话转换成一个向量,表示这句话的语义。索引(Index):
• 类似于书籍的目录,用于快速查找和检索数据。Faiss 索引就是用来快速查找相似嵌入向量的结构。度量标准(Metric):
• L2 距离:计算两个向量之间的欧几里得距离,类似于在二维空间中计算两点之间的直线距离。
• 内积(Inner Product):也叫点积,计算两个向量的相似度。
数据的方差越大,说明隐藏的信息越多,稀疏矩阵可以很好地表示特征,但是过于稀疏的同时维度又很大,会有很大的计算压力。
编码方式:
(1)one-hot编码
这种编码方式我觉得对于大多数人比较好理解,就是使用一个唯一的标记来标记一个
(2)整数编码
(3)词嵌入编码(word embedding)
比如说one-hot的编码中"蓝天""白云"分别为10000,00010,那么将这个编码点乘我们设的权重矩阵W后
Matlab
[ w00, w01, w02
w10, w11, w12
w20, w21, w22
w30, w31, w32
w40, w41, w42 ]
会得到 [w00, w01, w02] 和 [w30, w31, w32]。
在pytorch框架下,可以通过下面的方法来实现word embedding:
python
class Embeddings(nn.Module):
def __init__(self, d_model, vocab):
super(Embeddings, self).__init__()
self.lut = nn.Embedding(vocab, d_model)
self.d_model = d_model
def forward(self, x):
return self.lut(x) * math.sqrt(self.d_model)
class PositionalEncoding(nn.Module):
def __init__(self, d_model, dropout, max_len=5000):
super(PositionalEncoding, self).__init__()
self.dropout = nn.Dropout(p=dropout)
pe = torch.zeros(max_len, d_model) # max_len代表句子中最多有几个词
position = torch.arange(0, max_len).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2) *
-(math.log(10000.0) / d_model)) # d_model即公式中的d
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
self.register_buffer('pe', pe)
def forward(self, x):
x = x + self.pe[:, :x.size(1)] # 原向量加上计算出的位置信息才是最终的embedding
return self.dropout(x)
为什么使用相加而不是concat呢?
因为Transformer 通常会对原始输入做一个嵌入(embedding),从而映射到需要的维度,可采用一个变换矩阵做矩阵乘积的方式来实现,上述代码中的输入 x 其实就是已经变换后的表示,而非原输入 。并且在原输入上 concat 一个代表位置信息的向量在经过线性变换后 等同于 将原输入经线性变换后直接加上位置编码信息,这里的数学证明略。
1、Word2vec
2、GloVe
自注意力
首先来介绍注意力机制。
突出的非自主性提示 依赖于任务的意志提示
注意力可以从上面的图看到,模拟的是人类或者生物对于一些东西的观察,左边这个图由于咖啡杯是红色的,其它都是黑白的,所以人眼自然而然的会关注到这个红色的咖啡杯,因为它体现出了更大的突出特征性。这个在计算机的眼中也是很正常的,在图像处理中,颜色的方差可以用来描述图像中颜色的多样性。红色咖啡杯在图像中引入了更多的颜色变化,因此方差更大,使得图像更加生动和吸引人,计算出来的值也都更大。
注意力层的作用就是让模型在处理文本时,将注意力只放在某些词语上,Transformer 模型本来是为了翻译任务而设计的。但是随着时间的发展,可以结合其它的算法。
下面是Encoder-Decoder分心模型
句子对分别由各自的单词序列构成,得到X和Y:
非线性变换后得到中间语义表示C:
对于解码器Decoder来说,其任务是根据句子X的中间语义表示C和之前已经生成的历史信息 y1, y2, ... ... yi-1 来生成i 时刻要生成的单词 yi ,每个 yi 都依次产生,那么看起来就是整个系统根据输入句子X生成了目标句子 Y 。
推荐时,会有一个助词词汇或者出现频率很高的词,这些词需要在计算被剔除,它们对于注意力的影响挺大的,因为出现的频率很大,但表达的含义是有限的,注意力机制很重要。
下面是带了注意力的模型:
很有名的注意力公示:
为什么要乘以矩阵?------参考奇异值分解的过程
通过将输入向量与矩阵相乘,至少有以下优势:
1、增加了每个输入 token 关注输入序列中其他 token 的可能性,而不是关注单个 token 本身
2、可能更好的(潜在)输入向量表示
3、将输入向量转换为所需维度的空间,例如,从维度 5 转换为 2,或从 n 转换为 m 等(这在实践中很有用)
掩码,防止看到未来的结果
多头自注意力
目的:
优势:
计算方法
残差链接
Bert中的池化策略
反向传播
反向传播其实是一个在之前神经网络阶段也很常用的
模型微调
**检索增强技术(**Retrieval Augmented Generation,RAG)
一些常用的地方比如说什么呢,在网页中进行搜索然后存储到临时的数据库中,然后