3.1.1 词向量
[词向量(Word embedding),又叫Word嵌入式自然语言处理(NLP)中的一组语言建模和特征学习技术的统称,其中来自词汇表的单词或短语被映射到实数的向量。 从概念上讲,它涉及从每个单词一维的空间到具有更低维度的连续向量空间的数学嵌入。]
3.1.2 词嵌入
将单词映射到实向量的技术称为词嵌入。
为什么不选择one-hot而要选择更为复杂的word embedding呢:一个主要原因是独热向量不能准确表达不同词之间的相似度,比如我们经常使用的“余弦相似度”。对于向量x,y∈R,它们的余弦相似度是它们之间角度的余弦:
xTy||x||||y||∈[−1,1]
由于任意两个不同词的独热向量之间的余弦相似度为0,所以独热向量不能编码词之间的相似性。
word2vec工具是为了解决上述问题而提出的。它将每个词映射到一个固定长度的向量,这些向量能更好地表达不同词之间的相似性和类比关系。word2vec工具包含两个模型,即跳元模型(skip-gram) (Mikolov et al., 2013)和连续词袋(CBOW) (Mikolov et al., 2013)。
任何神经网络或任何监督训练技术的先决条件是具有标记的训练数据。当您没有任何标记数据(即单词及其相应的单词嵌入)时,如何训练神经网络来预测单词嵌入?
我们将通过创建一个“假”任务来训练神经网络来做到这一点。我们不会对这个网络的输入和输出感兴趣,相反,目标实际上只是学习隐藏层的权重,这些权重实际上是我们试图学习的“词向量”。
word2vec#
Skip-gram#
以黄色突出显示的单词是源单词,以绿色突出显示的单词是其相邻单词
Skip-gram 模型的任务是,给定一个单词,我们将尝试预测它的相邻单词,如上图。
如下式,給定中心词 w 和模型参数 θ 要計算上下文 c 出現的几率 p(c|w; θ),其中 C(w) 表示中心词 w 周围的上下文词的个数。
对于所有的在文本中的中心词 w 我们希望可以通过更新模型参数 θ ,最大化上下文词语的出现的概率的乘积,此时的 θ 就是我们需要的词向量,词向量并不是某个NN的结果而是中间层,且一般为一个浅层的NN。
argmaxθ∏ω∈Text[∏c∈C(ω)p(c|ω;θ)]
其条件概率可以通过点积然后softmax进行建模,其中ω是中心词,c为上下文词,
p(c|ω;θ)=evc⋅vω∑c′∈Vevc′⋅vω
为了得到需要的θ∗我们需要使用maximum log likelihood:
argmaxθ∑(w,c)∈Dlogp(c|w)=∑(w,c)∈D(logevc⋅vw−log∑c′evc′⋅vw)
另外还需要注意的一点是Text中的每一个词语都可以有两个身份分别是作为中心词和作为上下文词出现所有在实际的操作中,
word2vec将为每个词都预设两个向量(中心词向量矩阵 W & 上下文向量矩阵 W’)下面是实际的流程:
- input layer 为中心词 xk 的 1-hot vector,维度 1 x V。
- 通过预先初始化好的权重 W,W 的大小为上下文窗口 V 与词向量维度 N ,V x N 的矩阵,此 W 训练完成后,就是我们需要的词向量矩阵
- 完成第二步后, hidden layer 获得中心词维度 N 的词向量。
- 从 hidden layer 到 output layer 做了 C 次的前向传播,每次的传播都与 W’产生 V 維的向量 y,这里的 W’ 表示上下文的词向量矩阵,这样的话通过进行C次传播,可以使得在一定窗口大小内的词向量的位置具有一定的影响,再通过更改窗口的尺寸去更新这种影响(个人见解不敢保证准确),W’不同于 W 的是当词语的身份是是上下文时,才会对应到到此向量,而且W’中包含的不仅仅是上下文词出现的信息还有出现的位置c的信心(但是我不确定的是这种位置信息怎么读取或者说他在这里是可以读取的吗);而 C 表示该中心词语的上下文数量,通过 window size 決定(2*window size)。
- 将这 C 次所产生的值 Softmax function 转换,这里要注意的是,Softmax 分母的计算是由结果的每一个维度而來,而非只通过对应維度,因此我们可以將结果的每一个维度值视为所有上下文词语与中心词的点积,点积越大,概率值就越大。
- 由于 y1 到 yC 都是 xk 的上下文词,因此给定中心词 xk 我们要最大化 y1 到 yC 的条件概率值,而每一个条件概率值就以 Softmax 來模拟。
[注意:实际上这不是一个网络而应该是C个网络不过他们的W权重是相同的,但是 W′应该分为Wc′去确定位置,y_{kj}其实指的是k位置j词作为上下文的概率]
CBOW#
连续词袋(CBOW)模型类似于跳元模型。与跳元模型的主要区别在于,连续词袋模型假设中心词是基于其在文本序列中的周围上下文词生成的。由于连续词袋模型的输入存在多个上下文词,所以我们在计算条件概率时对这些上下文词向量进行平均如式
P(w|c(1),c(2),c(3),…,c©)=exp(vω⊤v¯c)∑i∈Vexp(vωi⊤v¯c)
相当于我们需要
argmaxθ∑v=1VlogP(w(v)∣c(v−C2),…,c(v−1),c(v+1),…,c(v+C2))
这里的意思是我们要最大化给定上下文词,所有中心词出现的概率
加速计算#
负采样#
负采样修改了目标函数。给定中心词ω的上下文窗口,任意上下文词c∈C是由以下建模概率的事件
P(D=1|c,w)=σ(vcTvω)
考虑最大文本化序列中所有这些事件的联合概率V是文本总词数,C为上下文词数(C=2*window_size):
∏v=1V∏−C2≤i≤C2,c≠0P(D=1∣w(v),c(v+i))
对一个正样本,考虑一个小的负样本集合,也就是随机选择一个负单词集合(也就是若干非上下文的单词组成的一个子集)
P(c(v+i)∣w(v))=P(D=1∣w(v),c(v+i))∏k=1,ck∼P(ω)P(D=0∣w(v),ck)
然后取对数,计算似然函数损失
−logP(cv+i∣ωv)=−logσ(vTcv+ivωv)−∑ωk∼P(ω)logσ(−vckvωv)
层序Softmax#
Huffman Tree (哈夫曼树)
哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树
作者利用霍夫曼编码 (huffman coding) 來建立二元树,通过统计每个词的出现频率,来决定词的编码,词频越高,编码越短,从而实现对数据的高效压缩。
每个节点都有一个可训练的参数 θ,分别与输入 X_w 点积后作为 sigmoid 函数的输入,根据 sigmoid 的特性其输出介于0-1之间,所以,可依据 sigmoid 的输出值靠近 1 或靠近 0,来决定要往右或往左走
σ(XωTθ)=11+e−XωTθ
可以把条件概率写为
这里的djω是预先对词进行的Huffman编码用于确定我们需要最大化向左还是向右的概率
p(djω|Xω,θj−1ω)={σ(XωTθj−1ω),djω=0;1−σ(XωTθj−1ω),djω=1;
可以等价为
p(djω|Xω,θj−1ω)=[σ(XωTθj−1ω)]1−djω⋅[1−σ(XωTθj−1ω)]djω
计算似然函数
L=∑ω∈Clog∏j=2lω{[σ(XωTθj−1ω)]1−djω⋅[1−σ(XωTθj−1ω)]djω}=∑ω∈C∑j=2lω{(1−djω)⋅log[σ(XωTθj−1ω)]+djω⋅log[1−σ(XωTθj−1ω)]}
Glove#
GloVe 本质上是一个具有加权最小二乘目标的对数双线性模型。该模型的主要直觉是一个简单的观察,即词与词共现概率的比率有可能编码某种形式的含义。例如,考虑目标词 ice 和 steam 与词汇表中各种探测词的共现概率。以下是来自 60 亿个单词语料库的一些实际概率:
正如所预料的那样,冰与固体的共生频率高于与气体的共生频率,而蒸汽与气体的共存频率高于固体的共存频率。这两个词经常与它们的共同属性水同时出现,并且都很少与不相关的词时尚同时出现。只有在概率比率中,来自水和时尚等非歧视性词语的噪音才会被抵消,因此大值(远大于 1)与冰的特定属性密切相关,而小值(远小于 1)与蒸汽的特定属性密切相关。这样,概率比编码了与热力学相的抽象概念相关的某种粗略的意义形式。
于是基于上面的发现我们可以假设存在于一个未知的函数F
F(ωi,ωj,ωk)=PikPjk
经过推导可得到F的形式和J
推导过程见:通俗易懂理解——Glove算法原理
因为共现概率的比值是标量,所以我们要求是标量函数,因此我们改进为:
F((ωi−ωj)T⋅ωk)=PikPjk
公式左边是差右边为商
我们自然而然的可以得到F的一个选择为exp,那么公式可转换为
exp(wiTwk−wjTwk)=exp(wiTwk)exp(wjTwk)=PikPjk
现在我们选择exp(wiTwk)=αPik=αXikXi
两边取对数可得到:
wiTwk=logα+logXik−logXi
这样模型就引入了两个偏置项(bias)
再计算加权平方误差就可以得到如下公式
J=∑ikf(Xik)(wiTwk+bi+bk−logXik)2
加权函数为
f(x)={(xxmax)α,ifx<xmax1,otherwise
加权函数的选择Glove的作者给出了一种比较好的选择为:xmax=100,β=34
下图为原论文中glove对比CBOW和SG的结果,可以看出存在明显的优势。
SVD(矩阵分解)+共现矩阵#
首先我们先了解SVD的概念:
SVD分解将任意矩阵分解成一个正交矩阵和一个对角矩阵以及另一个正交矩阵的乘积。对角矩阵的对角元称为矩阵的奇异值,可以证明,奇异值总是大于等于0的。当对角矩阵的奇异值按从大到小排列时,SVD分解是唯一的。
A=UΣVT
可以推出:
AAT=(UΣVT)(VΣTUT)=U(ΣΣT)UT
UTAATU=ΣΣT
依然是对角矩阵,又为正交矩阵。依然是对角矩阵,又为正交矩阵。(ΣΣT)依然是对角矩阵,又U为正交矩阵。
所以(ΣΣT)为AAT的相似对角矩阵,其对角元为AAT的特征值,U由其对应特征向量构成,这些向量称为A的左奇异向量。
因此Σ的对角元为AAT特征值的平方根,称之为矩阵A的奇异值。
类似地V由ATA的特征向量构成,这些向量称为A的右奇异向量。
简单来说我们对AAT和ATA进行特征值分解,得到的特征矩阵分别就是U和V,然后对(ΣΣT)的对角线取平方根就可以了
另外(ΣΣT)和(ΣTΣ)在是不相等的,两者的维度不相同,但是两者对角线的值是一样的。
你是对的,ΣΣT和ΣTΣ在矩阵的角度上是不相等的,因为它们的维度不同。ΣΣT是一个m×m的矩阵,而ΣTΣ是一个n×n的矩阵,其中m是A的行数,n是A的列数。
设
Σ=[σ10⋯00σ2⋯0⋮⋮⋱⋮00⋯σr00⋯0⋮⋮⋱⋮00⋯0]
其中r是A的奇异值个数。
则
ΣΣT=[σ120⋯00⋯00σ22⋯00⋯0⋮⋮⋱⋮⋮⋱⋮00⋯σr20⋯000⋯00⋯0⋮⋮⋱⋮⋮⋱⋮00⋯00⋯0]
ΣTΣ=[σ120⋯00⋯00σ22⋯00⋯0⋮⋮⋱⋮⋮⋱⋮00⋯σr20⋯000⋯00⋯0⋮⋮⋱⋮⋮⋱⋮00⋯00⋯0]
这样我们就可以使用三个矩阵去代表一个矩阵(听起来工作还增加了 ?)但是对于奇异值,它跟我们特征分解中的特征值类似,在奇异值矩阵中也是按照从大到小排列,而且奇异值的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上的比例。也就是说,我们也可以用最大的k个的奇异值和对应的左右奇异向量来近似描述矩阵。也就是说:
Am×n=Um×mΣm×nVn×nT≈Um×kΣk×kVk×nT
其中k要比n小很多,也就是一个大的矩阵A可以用三个小的矩阵,实现了降维操作(感觉和PCA有异曲同工之妙)
下面介绍共现矩阵
我们定义一个window_size,来对称的寻找出现在某个单词周围单词的频数,最后把他们汇总为一个矩阵。
例如我们有下列语料库设置window_size=1:
- I love you
- I like deep learning
- I like cats
那么我们就可以得到
I | love | you | like | deep | learning | cats | |
---|---|---|---|---|---|---|---|
I | 0 | 1 | 0 | 2 | 0 | 0 | 0 |
love | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
you | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
like | 2 | 0 | 0 | 0 | 1 | 0 | 1 |
deep | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
learning | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
cats | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
接着我们对共现矩阵进行SVD降维、可视化,依然呈现出了类似Word2Vec的效果。结果如下:
Copy
import numpy as np
import matplotlib.pyplot as plt
la=np.linalg
words=["I","love","you","like","deep","learning","cats"]
x=np.array([[0,1,0,2,0,0,0],[1,0,1,0,0,0,0],[0,1,0,0,0,0,0],[2,0,0,0,1,0,1],[0,0,0,1,0,1,0],[0,0,0,1,0,0,0],[0,0,0,1,0,0,0]])
U,s,Vh=la.svd(x,full_matrices=False)
scale_factor = 10
plt.xlim(np.min(U[:, 0])-0.1, np.max(U[:, 0])+0.1)
plt.ylim(np.min(U[:, 1])-0.1, np.max(U[:, 1])+0.1)
for i in range(len(words)):
plt.text(U[i,0],U[i,1],words[i])
plt.show()
3.2.1 Embedding API 使用
如何使用API见LLM学习(2)——使用 LLM API 开发应用(传送门)
Copy
result = genai.embed_content(
model="models/text-embedding-004",
content="What is the meaning of life?",
task_type="retrieval_document",
title="Embedding of single string")
# 1 input > 1 vector output
print(str(result['embedding'])[:50], '... TRIMMED]')
print(result)
print(type(result))
print(type(result['embedding']))
#结果如下
3.2.2 检索
Copy
#导入数据,并且切割,这里并没有对数据进行清洗只是简单的进行了文档的分割
file_paths = []
folder_path = '.\data'
for root, dirs, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
file_paths.append(file_path)
print(file_paths)
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders import UnstructuredMarkdownLoader
# # 遍历文件路径并把实例化的loader存放在loaders里
loaders = []
for file_path in file_paths:
file_type = file_path.split('.')[-1]
if file_type == 'pdf':
loaders.append(PyPDFLoader(file_path))
elif file_type == 'md':
loaders.append(UnstructuredMarkdownLoader(file_path))
# 下载文件并存储到text
texts = []
for loader in loaders: texts.extend(loader.load())
text = texts[1]
print(f"每一个元素的类型:{type(text)}.",
f"该文档的描述性数据:{text.metadata}",
f"查看该文档的内容:\n{text.page_content[0:]}",
sep="\n------\n")
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 切分文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, chunk_overlap=50)
split_docs = text_splitter.split_documents(texts)
结果:
Copy
#向量库构建
from langchain_google_genai import GoogleGenerativeAIEmbeddings
os.environ["GOOGLE_API_KEY"] = "AIzaSyBZFSrCWg7Ow2D3I2rMbf37qXp1SlF9T5k"
# 这里无法使用004可能是因为还没有适配???
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001",task_type="retrieval_document")
下
## 建立一个用来存放chroma数据库的文件夹
# if not os.path.isdir(".\data\vector_db\chroma"):
# os.makedirs(".\data\vector_db\chroma")
## 下面是查看API可以调用的model但是好像不能查看embedding的model
# for m in genai.list_models():
# if 'generateContent' in m.supported_generation_methods:
# print(m.name)
from langchain_community.vectorstores import Chroma
vectordb = Chroma.from_documents(
documents=split_docs[:20],
embedding=embeddings,
persist_directory=".\data\vector_db\chroma"
)
vectordb.persist()
print(f"向量库中存储的数量:{vectordb._collection.count()}")
Copy
#相似检索
question="什么是大语言模型"
sim_docs = vectordb.similarity_search(question,k=3)
print(f"检索到的内容数:{len(sim_docs)}")
for i, sim_doc in enumerate(sim_docs):
print(f"检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")
# MMR检索
mmr_docs = vectordb.max_marginal_relevance_search(question,k=3)
for i, sim_doc in enumerate(mmr_docs):
print(f"MMR 检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")
下面是两种检索的结果:(都蛮古怪的)
补充
PCA和SVD之间有着密切的联系。实际上,PCA可以被视为对数据矩阵进行SVD分解后的特例。具体来说假设我们的样本是m * n的矩阵X,如果我们通过SVD找到了矩阵 XTX 的最大的k个特征向量组成的m * d维矩阵U,则我们进行如下处理:
Xd×n′=Ud×mTXm×n
可以得到一个d * n的矩阵X,且这个矩阵和我们原来的m * n维的样本矩阵X相比,行数从m剪到了K,可见对行数进行了压缩。
也就是说,左奇异矩阵可以用于行数的压缩。相对的,右奇异矩阵可以用于列数即特征维度的压缩,也就是我们的PCA降维。
proof
在PCA中,我们可以通过计算数据的协方差矩阵来找到主成分方向这个协方差矩阵可以被分解为C=VΛVT其中V是特征向量矩阵,Λ是特征值对角矩阵
对数据进行去中心化后Xc=X−X¯将进行进行Xc进行SVD分解得到Xc=UΣVT代入协方差矩阵可以得到
C=1nXcTXc=1nVΣ2VT
如何系统的去学习AI大模型LLM ?
作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。
但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料
包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
四、AI大模型商业化落地方案
阶段1:AI大模型时代的基础理解
- 目标:了解AI大模型的基本概念、发展历程和核心原理。
- 内容:
- L1.1 人工智能简述与大模型起源
- L1.2 大模型与通用人工智能
- L1.3 GPT模型的发展历程
- L1.4 模型工程
- L1.4.1 知识大模型
- L1.4.2 生产大模型
- L1.4.3 模型工程方法论
- L1.4.4 模型工程实践 - L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
- 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
- 内容:
- L2.1 API接口
- L2.1.1 OpenAI API接口
- L2.1.2 Python接口接入
- L2.1.3 BOT工具类框架
- L2.1.4 代码示例 - L2.2 Prompt框架
- L2.2.1 什么是Prompt
- L2.2.2 Prompt框架应用现状
- L2.2.3 基于GPTAS的Prompt框架
- L2.2.4 Prompt框架与Thought
- L2.2.5 Prompt框架与提示词 - L2.3 流水线工程
- L2.3.1 流水线工程的概念
- L2.3.2 流水线工程的优点
- L2.3.3 流水线工程的应用 - L2.4 总结与展望
- L2.1 API接口
阶段3:AI大模型应用架构实践
- 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
- 内容:
- L3.1 Agent模型框架
- L3.1.1 Agent模型框架的设计理念
- L3.1.2 Agent模型框架的核心组件
- L3.1.3 Agent模型框架的实现细节 - L3.2 MetaGPT
- L3.2.1 MetaGPT的基本概念
- L3.2.2 MetaGPT的工作原理
- L3.2.3 MetaGPT的应用场景 - L3.3 ChatGLM
- L3.3.1 ChatGLM的特点
- L3.3.2 ChatGLM的开发环境
- L3.3.3 ChatGLM的使用示例 - L3.4 LLAMA
- L3.4.1 LLAMA的特点
- L3.4.2 LLAMA的开发环境
- L3.4.3 LLAMA的使用示例 - L3.5 其他大模型介绍
- L3.1 Agent模型框架
阶段4:AI大模型私有化部署
- 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
- 内容:
- L4.1 模型私有化部署概述
- L4.2 模型私有化部署的关键技术
- L4.3 模型私有化部署的实施步骤
- L4.4 模型私有化部署的应用场景
学习计划:
- 阶段1:1-2个月,建立AI大模型的基础知识体系。
- 阶段2:2-3个月,专注于API应用开发能力的提升。
- 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
- 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的所有 ⚡️ 大模型 LLM 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费
】
全套 《LLM大模型入门+进阶学习资源包》↓↓↓ 获取~