AI-LLM
-

在最初尝试了解 diffusion 模型的时候,原本是打算跳过 VAE (Variational Autoencoder 变分自编码 )模型的,后面发现有点跳不过去。再花了一些时间去了解 VAE,才意识到其实不应该跳过去,相反的,了解 VAE 实现的一些架构、原理、直觉、初衷、数学原理则可以大大帮助理解后续的生成模型。
目录
1. 为什么现在你依旧需要了解 VAE
“潜空间”(latent space)的处理依旧是现代(SOTA)生成模型最为核心的组件。而从autoencoder模型,扩展到 VAE 模型,则是生成模型走出的关键步骤之一。将潜空间限制在一个正态分布的空间内,然后,在这个空间进行采样后进行 decoder 的生成思想,则是现代生成模型很多思想来时的路。
如果跳过这一段,很多的概念则会显得非常突然。
2. VAE 关键直觉与主要思想
2.1 关键直觉
在计算机与数学科学中有几个概念是反复出现的,其中之一就是“高斯分布”(或者叫“正态分布”)。在图像生成模型中非常关键的,则是将潜空间限制在了一个正态分布之中,为什么会这样?似乎并没有人去说明这一点,这里做一个简单的阐述和理解。高斯分布可以理解为大量伯努利分布的极限形式,现实世界的分布我们通常会假设其为大量微小因子的共同作用下的宏观表现,故通常假设其满足高斯分布。
那这与 VAE 有什么关系呢?在经典的 Guassian VAE 中,一个关键假设是:“潜空间” \(z \) 符合高斯分布的(通过训练来将其拉向高斯分布)。然后再对潜空间采样后,就可以生成较为“逼真”的图像了。那么假设“潜空间” \(z \) 符合高斯分布有什么深意吗?还是只是为了方便采样?
从直觉构建的角度,我们可以这样认为:潜空间的每个“维度”都有某这非常强的意义,例如色彩、风格、类型等,那么则有理由相信,一个对象在每一个“维度”上的分布也是符合正态分布的。即“潜空间”是一个符合正态分布的空间,那么从这个样本空间进行采样时,也就更容易得到一个有代表意义的点。
2.2 VAE 的主要思想

如何使用“神经网络”生成“逼真”的数据(例如图片、视频等)呢?在机器学习领域,一个比较自然的探索是从“autoencoder”架构去做一些尝试:“autoencoder” 由一个确定的encoder 将输入压缩到一个低维的“潜编码”(latent code)空间中,然后再由decoder根据“latent code”重建数据。
如右图所示,对于这样的神经网络设计其优势是非常明显的,这可以是非常好的“无监督学习”的神经网络,对比最终输出和输入的数据即可以作为损失函数。
但,在数据生成(例如新的图像生成)上,这样的设计在实践中也有着非常明显的限制:即对于如果随机选取一个“latent code”,通常只能生成一些无意义的数据。
2013年的 “Variational Autoencoder (VAE)” (Kingma and Welling, 2013) 架构则尝试解决这个问题:将“潜空间”(latent space)设计为某个符合某个概率分布结构。终于,可以生成出色的、逼真的数据(例如“图像”)。


上述的描述可能还是比较抽象的,下面将实现一个基础的“VAE”模型,从而观测该模型的各个模块。
3. 一个简单的 VAE 模型的观测
3.1 模型架构概述

这里实现了(主要靠Gemini)一个由多个全连接层构成 VAE 模型。输入是 MNIST 数据集,输入层维度是 \(28 \times 28 = 784 \),中间的潜空间(Latent Space)维度为 20 ,包括 20 个均值和20个方差,然后是一个基本对称的decoder,包括一个400个神经元的全连接层和一个784个神经元的输出层,手绘描述如右图。
相关的代码实现参考:VAE-my-practice.ipynb。
这个神经网络结构之简单、生成效果之惊人,我自己是有点被震惊了的,相比于Autoencoder ,这里将“潜空间”限制在了某个概率分布之中,更为具体的是将每一个样本都“尝试”映射到正态分布中(注:\(p(z|x) \)是正态分布)。这里的“尝试”的做法是,先让神经网络输出“均值”和“方差”,然后再做一次重参数化的“采样”(Sampling)得到 \(z \)。
说明:\(p(z|x) \)是正态分布;从模型架构上看,\(p(z) \) 似乎并不是正态分布,但最终由训练的目标函数将\(p(z) \) “拉向”一个正态分布。
3.2 模型效果观测:某个点附近的数据

这里使用上述模型,将 MNIST 数据集中的一张原始图片计算出对应的正态分布,即均值和方差,然后使用该均值和方差进行了 11 一次采样,再生成 11 张图片,可以看到这些生成的图片和原始图片有非常高的相似度,同时又与原始图片不同。
即达到了生成“逼真”图片的效果。这种实现范式,展现出了非常强的图片生成潜力。也是后续 diffusion 模型的重要基础之一。

再从 \(z \sim \mathcal{N}(0,I) \) 随机采样一些值,再看看这些随机生成的效果,如右图。
可以看到,基本上能够生成一些有意义的图。这里只是使用了一些全连接层,即可以产生非常好的效果,可以预期,如果使用卷积神经网络,是可以有更好的效果的。
3.3 模型效果观测:空间中交接处的情况
从构建直觉的角度我们可以这样理解,encoder 层将原始的“向量空间”映射到了一个“潜空间”(latent space),该潜空间中的数据符合标准正态分布。所以,这就使得我们在“潜空间”变量 \(z \) 中做一个标准正态分布的采样,就可以使用 decoder 生成一个有意义的图片。并且,从构建直觉的角度,我们可以认为decoder 将正态分布中的点映射到“10个”数字的“空间”(784维)中,甚至可以认为(直觉角度)目标空间中有一片“连续”的空间即为“像空间”,这些空间某种程度可以“聚类”为“10类”,这些聚类的边缘则是一些介于不同数字之间的难以辨认的数字。
例如,我们考虑这样观测这些“聚类”中数字“1”和数字“0”之间的图像。我们先使用encoder计算(找一张图片作为输入)出数字“1”、“0”对应的均值,并以此作为对应数字在“潜空间”中的中心(更为严格的可以多计算一些相同的数字,再计算均值),然后在“1”、“1”对应的质心之间进行插值,然后观测这些“插值”经过encoder后的图片。

在放大33% ~ 66% 这个关键阶段:

3.4 模型小结
如上所述,encoder 最终把“原始的数据”映射到一个“潜空间”(latent space),“潜空间”中的数据(在线性代数中类似的概念称为“像空间”)符合正态分布。从从构建直觉角度我们可以有如下的一些理解和疑问。
VAE 模型尝试把“潜空间”限制在一个非常小区域,即以“原点”为中心的一个小“球”中(想想 3 \(\sigma \) 内就可能覆盖了 99.73% 的点),更为准确的是一片标准正态分布的概率云当中。问题:这种把“像空间”限制在小区域内,是否是实现“逼真生成”的关键因素?尝试回答:像空间的大小也许并不是关键的,毕竟,从数学角度来看,单位“球”可能与整个空间是一样大的,只是看起来小了而已;那么,关键可能在于把“像空间”现在在了某种结构上,这里的结构是标准正态分布空间。问题:为什么把“像空间”限制在某种结构上,就能够达到这样的效果呢?
在上述示例的“概率云”中,所有的点并不是“对等的”,概率密度相等的点,其意义也有着非常大的区别。从直觉的角度,例如最某个数字1的点 \(z_1 \in z \),在点 \(z_1 \) 附近的点则映射到的“像”也是更为接近的与数字“1”的点(这里的 \(z_1 = q_{\theta}(x) \quad \text{where} \, x \in \text{Samples} \))。
4. VAE 实现的一些细节
4.1 VAE的训练目标
VAE 模型将潜空间限制在了一个“正态分布”之中,通过在正态分布中采样的方式用来生成新的图片。这个过程并不是很好理解,这里介绍一下 VAE 的数学建模思路。

模型的训练目标(ELBO):
$$
\min_{\theta,\phi} \mathbb{E}_{q_{\theta}(z|x)}[\frac{1}{2\sigma^2}|| x-\mu_{\phi}(z) ||^2] + \mathcal{D}_{KL}(q_{\theta}(z|x)||p(z) ) \tag{1}
$$关于这个式子的完整的数学推导,在网上比较好找到,有一些复杂、也不是很好理解。但是,这个式子的意义却比较明确:
- 前一部分,对于某个输入 \(x \),需要神经网络的参数 \(\theta , \phi \) 生成的图像\(x’ \)能够与原始图像接近
- 后半部分,则让神经网络参数\(\theta \) 是的分布 \(q_{\theta}(z|x) \) 靠近 \(p(z) \)即标准正态分布
4.2 VAE的数学模型
理解 VAE 比较困难的大概是这背后的数学模型,而理解了这个“数学模型”才可能进一步理解上述的公式,以及更多的VAE以及后续生成模型的思想。所以这里总结一些我对这个“数学模型”的理解:
Encoder 部分 \(q_{\theta} \) 是将一个图片 \(x \) 映射到一个概率分布(而不是某个具体的值),通常是 \(\mathcal{N}(\mu,\sigma^2) \)。那么,在神经网络中,如何将一个具体的样本/数据 \(x \) 映射到一个概率分布呢?是这样的:神经网络则需要输出/拟合/回归出该分布的关键参数即可,例如对于正态分布只需要给均值和方差即可。这也是为什么在上述的“示例VAE”中 Encoder 部分输出即为分布 \(z \sim p(z) \) 的均值与方差。那么,要从潜空间 \(z \) 中取一个值(即采样一个值)的时候,则需要“随机”的做一次生成,这里的“随机”则使用了“重参数化”技巧进行处理从而解决训练时向后传播的随机性问题。更为一般的即:$$ q_{\theta}(z|x) := \mathcal{N}(z;\mu_{\theta}(x),\text{diag}(\sigma_{\theta}^2(x))) \tag{2} $$
Decoder 部分 \(p_{\phi} \) 则是将潜空间的采样 \(z \) 映射到一个概率分布,而不是一个具体的值,但这里可能感觉是一个具体指的原因是,通常输出就是这个分布的均值(或期望),而不再另外进行采样操作。在常见的 Gaussian VAE 中,更为一般的有:
$$ p_{\phi}(x|z) := \mathcal{N}(x;\mu_{\phi}(z),\sigma^2 I) \tag{3} $$
最后,有了这两个定义公式(2)、(3),就可以计算上述的损失函数公式(1)了。
5. VAE 中的数学推导
这大概是最难理解的部分,甚至注意到很多领域内的专家(更加注重实践能力),对于这部分也很头疼,这里做一些尝试。
5.1 VAE 基本数学概率模型与训练目标
我们有一个上述的 VAE 模型,其中:
- \(\theta \) 为encoder部分参数,\(\phi \) 为decoder 的参数
- \(p_{\theta}(z|x) \) 表示对于给定的输入 \(x \),encoder 将输入映射为分布\(p_{\theta}(z|x) \) ,通常按照上述的公式(2)定义
- \(p_{\phi}(x|z) \) 表示对于给定的潜空间采样值 \(z \),decoder 将其映射为分布\(p_{\phi}(x|z) \) ,通常按照上述的公式(3)定义
在数学形式上,就可以有目标端(神经网络的输出)\(x \) 的分布:
$$
p_{\phi}(x) = \int p_{\phi}(x|z)p(z)dz
$$这是一个形式上的表达,并不能直接计算,这是因为 \(p_{\phi}(x|z) \) 是一个由神经网络定义的映射或分布,对于每一个 \(z \),并没有一个简单的表达式给出\(p_{\phi}(x|z) \)的形式,或者更为直接的,在公式(3)中的 \(\mu_{\phi}(z) \) 由神经网络定义,并没有数学形式的表达。
这个式子确实不可计算,在实际训练中,则做了一些数学“推导”,训练另一个与此相关的式子(ELBO),这个我们后续再看。
所以,对于 VAE 模型的训练,即需要最大化:
$$
\max_{\phi}\sum_\limits{i} \log p_{\phi}(x_i) \quad \forall x_i \in \text{Sample Data} \tag{4}
$$即对于最终的概率分布(PDF)\(p_{\phi}(x) \),任何的真实的图像(对应的 \(\forall x \in {\text{data}} \))所对应的密度值取值都需要很大,才能最终使得上述式子取值最大。
这似乎还比较抽象,这里我们进一步解释一下上述的式子(4)。考虑真实分布为 \(p_{\text{data}}(x) \),通常我们可以使用 KL 散度衡量两个分布的距离,那么,就需要最小化这个散度值:
$$
\begin{aligned}
\mathcal{D}_{\text{KL}} &= \int p_{\text{data}}(x) \log \frac{p_{\text{data}}(x)}{ p_{\phi}(x)}dx \\[0.8em]
&= \int p_{\text{data}}(x) \log p_{\text{data}}(x)dx – \int p_{\text{data}}(x) \log p_{\phi}(x)dx
\end{aligned}
$$上述式子中的前项是一个常数(认为真实世界的分布是确定的,是拟合的目标,其实就是这个分布的“熵”),那么要这个散度值最小,就是让上述式子中后一项最大,即 \(\int p_{\text{data}}(x)p_{\phi}(x)dx \) 最大;在离散场景,积分则变成求和,并且 \(p_{\text{data}}(x) \)通常不可知,则通常使用\(\frac{1}{N} \)替代或者直接忽略,即有上面的式子(4)。
5.2 使用 ELBO 对上述目标进行近似
关于“Evidence Lower Bound” (简称 ELBO )虽然网上有很多的说明,但总是不够细致(或者要求对概率论有非常深的理解),这里做一个最为详细的推导和说明如下(应该是互联网上能够找到的最为详细的说明了)。
ELBO的定义为:
$$
\mathcal{L}_{\text{ELBO}}
=
\underbrace{
\mathbb{E}_{z \sim q_\theta(z|x)}
\left[ \log p_\phi(x|z) \right]
}_{\text{Reconstruction Term}}
–
\underbrace{
D_{\mathrm{KL}}\!\left( q_\theta(z|x) \,\|\, p(z) \right)
}_{\text{Latent Regularization}}
$$可以通过严格的证明,如下不等式成立:
$$
\begin{equation}
\log p_\phi(x) \ge \mathcal{L}_{\text{ELBO}}(\theta, \phi; x)
\end{equation}
$$证明如下:
$$
\begin{aligned}
\log p_\phi(x) &\stackrel{(1)}{=} \log \int p_\phi(x, z) \, dz \\[0.8em]
&\stackrel{(2)}{=} \log \int q_\theta(z|x) \frac{p_\phi(x, z)}{q_\theta(z|x)} \, dz \\[0.8em]
&\stackrel{(3)}{=} \log \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \frac{p_\phi(x, z)}{q_\theta(z|x)} \right] \\[0.8em]
&\stackrel{(4)}{\geq} \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log \frac{p_\phi(x, z)}{q_\theta(z|x)} \right] \\[0.8em]
&\stackrel{(5)}{=} \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log \frac{p_\phi(x, z) p(z)}{q_\theta(z|x)p(z)} \right] \\[0.8em]
&\stackrel{(6)}{=} \mathbb{E}_{z \sim q_\theta(z|x) p(z)} \left[ \log \frac{p_{\phi}(x|z)p(z)}{q_\theta(z|x)} \right] \\[0.8em]
&\stackrel{(7)}{=} \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log {p_{\phi}(x|z)} – \log { \frac{q_\theta(z|x)}{p(z)} } \right] \\[0.8em]
&\stackrel{(8)}{=} \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log {p_{\phi}(x|z)} \right] – \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log { \frac{q_\theta(z|x)}{p(z)} } \right] \\[0.8em]
&\stackrel{(9)}{=} \mathbb{E}_{z \sim q_\theta(z|x)} \left[ \log {p_{\phi}(x|z)}] – \mathcal{D}_{\mathrm{KL}}(q_\theta(z|x)||p(z)) \right] \\[0.8em]
\end{aligned}
$$各步骤的说明:
- 步骤 (1) 为边缘概率公式
- 步骤(2) 分子、分母都乘以了 \(q_\theta(z|x) \)
- 步骤(3) 使用期望的形式改写上述公式(可以想一想连续形式的概率期望计算),这一步是为了转化为下一步可以使用 “Jensen” 不等式
- 步骤(4) 这里使用 “Jensen” 不等式,对于凹函数 \(\varphi \)有 \(\varphi(\mathbb{E}[X]) \geq \mathbb{E}[\varphi(X)] \) ,函数 \(f(x) = \log (x) \) 即为凹函数
- 步骤(5) 分子、分母都乘以 \(p(z) \)
- 步骤(6) 使用基础的条件概率公式 \(p_{\phi}(x|z)p(z) = p_{\phi}(x,z) \)
- 步骤(7) 使用对数函数基本性质 \(\log \frac{ab}{c} = \log {a} – \log \frac{c}{b} \)
- 步骤(8) 使用期望公式的线性特性 \(\mathbb{E}[X+Y] = \mathbb{E}[X] + \mathbb{E}[Y] \)
- 步骤(9) 使用了KL散度的定义,简单的说,即概率密度对数的差的期望即为散度
步骤(9) 也最终与前述的 \(\mathcal{L}_{\mathrm{ELBO}} \) 定义完全相同,故得证。
-

深度学习领域除了大语言模型之外,另一个极其活跃的领域即为视频、图像处理领域(或者叫“多模”数据)。随着 Stable Diffusion 取得成功,这个领域也在非常快速的发展。这里也打算极其粗浅的了解一下这个领域。打算,从最为基础“组件”之一 “CLIP” 开始。
“CLIP”的全称是“Contrastive Language–Image Pre-training”,描述的是一种训练方法,可以把“图片”、“文字”嵌入(Embedding)到同一个空间(例如 512 维的向量空间),并保持非常好的相关性。利用这个特点,则可以非常好的进行诸如:图片相似性、文本图片相关性的人物;也可以作为其他模型的一部分,提供非常好的文本与图片一致性的关系。这里以典型的“clip-vit-base-patch32”模型为例,去简单实践并了解该模型。
1. 实验设计
这里选择一张图片,如右图,使用该模型对图片进行 Embedding;然后再选择一组文本,如下,使用该模型对其进行 Embedding ,然后观察这些向量之间的余弦距离关系。
texts = [ "a dog", "a cat", "a car", "a landscape", "a person", "a person behind a statue", "a person riding a bicycle", "tourist attraction", "a vacation" ]
2. 实验数据与结果分析
在使用模型进行Embedding后,然后把所有文本向量与图片计算余弦相似度后有右侧数据:
可以看到,图片和文本之间表现出了非常强的相关度。相关度最高的文本为:“a person behind a statue”,也是所有文本中对图片最为准确的描述。“a person” 也比 “a person riding a bicycle” 有着更高的相似度,更比诸如 “a dog”、“a cat” 要高非常多。
0.2707 | a person behind a statue 0.2508 | tourist attraction 0.2074 | a person 0.2063 | a vacation 0.1974 | a person riding a bicycle 0.1875 | a dog 0.1821 | a landscape 0.1754 | a cat 0.1655 | a car2.1 可视化结果
这里在一个数轴上,简单对上述结果进行可视化,从而建立一个更为直观一点的认识:

在数轴上将上述文本与图片的相似度取值绘制出来,可以看到,“a person behind a statue”远比其他的文本相似度要高。
3. 其他
对于 Embedding 出来的向量,这里也使用诸如“T-SNE”、“PCA”、“UMAP”、“MDS”等方式去降维到二维空间分析,但是并没有观察余弦相似度的保持,与上述计算结果不符合。也许是点太少、也许是用法不对。这也让对诸如“T-SNE”等算法在可视化上效果,提高了警惕。关于这部分计算的数据和结果可以参考:SD-Forward-Diffusion-Process.ipynb@Colab,这里不再展示。
-
线性代数回顾
·

如果要理解大模型内部是如何工作的,良好的数学基础是必须的,而线性代数又是所有这些的基础。例如我们来看 \(\text{Attention} \) 机制中的如下问题。
目录
1. 为什么要重温线性代数
考虑第 \(j \) 个 \( \text{Layer} \) 中的第 \( i \) 个 \( \text{Head} \) ,则有如下的计算(为了简化,下述的角标省略了 \( \text{Layer} \) 部分):
$$
\begin{aligned}
Q_i &= XW_i^Q \\[0.3em]
K_i &= XW_i^K \\[0.3em]
\text{Therefore:} \\[0.3em]
\text{Attention Score}_i &= Q_iK_i^T \\[0.3em]
&= XW_i^Q(XW_i^K)^T \\[0.3em]
&= XW_i^Q\big((W_i^K)^T X^T\big) \\[0.3em]
&= XW_i^Q(W_i^K)^T X^T \\[0.3em]
&= X\big(W_i^Q (W_i^K)^T\big) X^T \\[0.3em]
\text{Let:} \quad \\[0.3em]
W_i^{QK} &= W_i^Q (W_i^K)^T \\[0.3em]
\text{Therefore:} \\[0.3em]
\text{Attention Score}_i &= XW_i^{QK} X^T \\[0.3em]
\end{aligned}
$$注:上述的推导使用矩阵的一些简单特性,包括转置计算、结合律等。其中,在开源的GPT2模型中,\(W_i^Q \,, W_i^K \) 都是 \(64 \times 768 \)的矩阵。
这里一个简单、又不太简单的问题是:那为什么每一个 \( \text{Head} \) 中不使用一个权重 \( W_i^{QK} \) 就可以了?这个问题从我第一次看明白 \( \text{Attention} \) 的计算后,困扰了我一会儿,直到重温了线性代数,才算是理解了上述的计算。
大学时学习线性代数学得非常痛苦,而现在带着问题再去看这本书,竟然花了两个晚上就看完了。这里对里面的基本概念和结论做个梳理,以更好的理解什么是“线性变换”、与矩阵的关系是什么、如何研究一个线性变换或矩阵的性质等。
本系列主要以介绍线性代数的“直觉”为主,不会做任何证明,为了更好的阐述“直觉”,甚至牺牲了很多的数学严谨,看客也需要从构建“直觉”与“联系”的角度阅读。本文的阅读前提是已经有一定的线性代数的基础、也对神经网络/LLM技术有一定了解,那么本文则尝试通过较小的篇幅去构建两者的联系,看看如何使用线性代数的技术去研究神经网络的中的问题。
2. 线性代数讨论的主要问题
通常“线性代数”课程会从 \(n\) 元一次线性方程组引入,并使用行列式理论,去较为彻底的回答如何解决 \(n\) 元一次线性方程组。更进一步的,为了更好/更完整的研究 \(n\) 元一次线性方程组的“解空间”,则需要引入一个新的研究对象:“向量空间”。而向量空间本身所具备的普遍性,已经远超出 \(n\) 元一次线性方程组本身。而后,“向量空间”、“线性变换”就变成了新的研究对象,因为现实问题中,我们经常会尝试通过“线性变换”来洞察向量空间中向量的关系。
是不是感觉上面描述漏了什么?是的,漏了“矩阵”。无论是讨论 \(n\) 元一次线性方程组还是“向量空间”或“线性变换”,矩阵都是“核心”工具。这个工具“核心”或者说重要到什么程度呢?甚至很多问题,只需要研究清楚对应“矩阵”的特性,原来的问题就研究清楚了。所以,你会注意到,线性代数的书中,几乎全都在介绍“矩阵”的各种特性。
而各种 \( \text{Embedding} \) 就可以理解为是在最为典型的欧氏空间中的向量。
3. \(n \) 元一次方程组的解
线性代数通常都会以解“\( n \)元一次方程组”为切入点,这个问题看似很简单,但是最终要完全讨论清楚,则需要很多篇幅。这也是“线性代数”前半部分比较枯燥的原因。整体上来看,关于“\( n \)元一次方程组”的解需要讨论清楚几个问题:
- (a) \( n \)元一次方程组的解是否存在?
- (b) 如果存在,如何求解
- (c) 如果解不存在,充要条件是什么
- (d) 如果有解,那么所有的解如何表达
在探讨上述问题的时候,先是引入了“行列式”、“矩阵”的概念与理论,并通过矩阵的“初等变换”实现对上述问题的求解。这里涉及到的概念延伸出了:
- (a) 矩阵的初等变换
- (b) 矩阵的秩等
这里我们列举一些主要的结论(并不做推倒,推倒过程还是非常复杂的,这也正是线性代数书比较枯燥的原因之一)。这里考虑如下的线性方程组:
$$
a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n = b_1, \\
a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n = b_2, \\
\quad\vdots \\
a_{m1}x_1 + a_{m2}x_2 + \cdots + a_{mn}x_n = b_m.
$$结论: 线性方程组有解的充分必要条件是:它的系数矩阵与增广矩阵有相同的秩。
结论: 线性方程组系数矩阵和增广矩阵的秩都是\( r \),方程组的未知数的个数是\( n \),如果:
- \( r = n \) 则线性方程组有唯一解
- \( r < n \) 则线性方程组有无穷组解
上述两个定理较为彻底的回答了解存在性的问题。那么,解的公式化表达是怎样的呢?为了略微简化问题,这里考虑仅考虑\( n \)个方程、\( n \)个未知数,且解唯一的情况:
$$
\begin{cases}
a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n = b_1, \\
a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n = b_2, \\
\quad\vdots \\
a_{n1}x_1 + a_{n2}x_2 + \cdots + a_{nn}x_n = b_n
\end{cases}
\quad\Longleftrightarrow\quad
\begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1n} \\
a_{21} & a_{22} & \cdots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n1} & a_{n2} & \cdots & a_{nn}
\end{bmatrix}
\begin{bmatrix}
x_1 \\ x_2 \\ \vdots \\ x_n
\end{bmatrix}
=
\begin{bmatrix}
b_1 \\ b_2 \\ \vdots \\ b_n
\end{bmatrix}
$$形式化的解,则可以由两种方式给出:
使用矩阵的表达:
$$
\vec{x} = A^{-1}\vec{b}
$$“克莱默法则”(Cramer’s rule / formula):
$$
x_1 = \frac{D_1}{D},x_2 = \frac{D_2}{D},\dots , x_n = \frac{D_n}{D},
$$注意:上述的两种表达,无论哪种,限制条件都非常苛刻,即要求:矩阵\( A \)可逆或者行列列式\(D \neq 0\),当然,这两个条件式等价的。并且,这里的\(D\)也经常写作:\( det(A) \)。
4. 矩阵基础与部分结论
虽然是为了求解线性方程组才引入矩阵的,但很快就会意识到,对矩阵本身特性的研究有着更为广泛的应用。
首先,在定义了矩阵的运算之后,很快就会有一些矩阵的运算律。例如,加法的结合律、交换律、分配律等。这里,矩阵的乘法是重点,且略微复杂一些:
- 首先,首先矩阵的乘法是不满足交换律的
- 很幸运,结合律和分配律都是满足的
- 再次,对于转置运算,是满足如下形式的:\( (AB)^T = B^TA^T \)
结论: 线性方程组的初等变换,对应着三个初等变换矩阵:\( P_{ij} \)、\( D_i(k) \)、\( T_{ij}(k) \),且这三个初等变换矩阵都是可逆的。
结论: 一个\( m \times n\)的矩阵\( A \)总是可以通过初等变换化为以下形式的矩阵:
$$ \bar{A} = \begin{bmatrix}
I_r & O_{r,\,n-r} \\
O_{m-r,\,r} & O_{m-r,\,n-r}
\end{bmatrix} $$这里,\(I_r\)是\( r \)阶单位矩阵,\(O_{st}\)表示\( s\times t\)的零矩阵,\( r \)等于矩阵\(A\)的秩。
结论:\(n \) 阶矩阵\( A \)可逆,当且仅当\( A \)的秩等于\( n \)。
如何求解矩阵的逆:有了这些结论,那么对于一个可逆矩阵要求其逆矩阵,则可以有些办法:即对一个矩阵实施一系列的初等变换,将其变为单位矩阵。而同时,在开始的时候,就将所有的这些初等变换作用在一个单位矩阵上。最后,当原矩阵变为单位矩阵的时候,后面的单位矩阵就变成原矩阵的逆了。
结论: 两个矩阵乘积的秩,不大于任何一个矩阵的秩。特别的,如果有一个矩阵是可逆的,则乘积的秩则等于另一个矩阵的秩。
结论: 一个矩阵的行空间的维数等于列空间的维数,等于这个矩阵的秩。
5. 向量空间
到目前为止,前面的线性方程组的解,还有一些问题没有彻底回答(例如,解空间的描述),在回答这个问题之前,我们需要先了解一下“向量空间”。“向量空间”的严格定义是有些枯燥的,这里暂时把“向量空间”的限制为大家所熟悉的、最为典型的“ \(n \) 维欧氏空间”。
5.1 基
要描述一个向量空间中的元素,则首先需要一组基(坐标)。在\(n\)维欧氏空间,最为常见的一组基,即为多个“垂直”(“正交”)的单位向量,即:
$$ \begin{align}
\alpha_1 &= (1,0,\dots) \\
& \vdots \\
\alpha_i &= (\dots,0,1,0,\dots) \\
& \vdots \\
\alpha_n &= (0,\dots,1)
\end{align}
$$在二维平面空间中,则为:\( \alpha_1 = (1,0) \quad \alpha_2 = (0,1)\);三维空间则为:\( \alpha_1 = (1,0,0) \quad \alpha_2 = (0,1,0) \quad \alpha_3 = (0,0,1)\)。
既然有“正交”基,那么当然有不那么“正交”的基,而此类“基”则是更为普遍的。事实上,更为普遍的,任何 \( n \) 个线性无关的向量都可以作为向量空间的基。
5.2 线性相关与线性无关
考虑一组向量\( \alpha_1,\dots , \alpha_n \),如果当且仅当所有\( a_i = 0 \quad i=1,\dots,n\)时如下的等式才成立:
$$ a_1\alpha_1 + a_2\alpha_2 + \dots + a_n\alpha_n = 0 $$
那么,就说 这组向量 \( \alpha_1,\dots , \alpha_n \) 是线性无关的。反之,则称这组向量是线性相关的。
或者这么说,对于一组线性无关的向量\( \alpha_1,\dots , \alpha_n \):任何一个向量都不能用剩余的向量做“线性表示”。
5.3 一些重要的结论
结论:设\( \{ \alpha_1,\dots , \alpha_n \}\)是向量空间\( V \)的一组基,那么\( V \)空间中的每一个向量都可以唯一的表示为这组基的线性组合。这个线性组合的系数,就叫“坐标”(注:相对于这组基)。
结论:\( W_1 \)、\( W_2 \)是\( V \)的有限子空间,那么有:
$$ dim(W_1+W_2) = dim(W_1) + dim(W_2) – dim(W_1\cap W_2) $$
结论:\( n \)维向量空间中,任意\( n \)个线性无关的向量都可以取做基。
6. 线性变换与矩阵
6.1 概述
“线性变换”是指向量空间中一类特殊的映射 \( \sigma : R^n \to R^m \) ,需要满足条件是:
- \( \sigma(\xi + \eta) = \sigma(\xi) + \sigma(\eta) \)
- \( \sigma(a\xi) = a\sigma(\xi) \)
“线性变换” 描述了向量空间之间的映射。后续所有的内容大概都是围绕此而展开,后续所有的内容都会尝试通过各种方式将 “线性变换” 的特性研究清楚。这里写出部分结论,后面再慢慢展开:
- 线性变换之下,原点保持不变。即 \( \sigma( \vec{0} ) = \vec{0} \)
- 几何意义下,通常,线性变换包括了:旋转、镜像、拉伸/压缩(特别的,有时候会压缩到零)、剪切
为了研究清楚一个线性变换上述的特点,通常需要选取一组“基”,然后使用这组“基”的“坐标”来描述空间中的点,进而再描述对应的线性变换。最为常见的基为“正交单位基”。
从方法上来看,研究清楚“线性变换”最为关键的是研究清楚对应的“变换矩阵”。所以,“线性代数”的核心后面就变成了对矩阵特性的研究,但是,也不要忘记了初衷,否则很快就迷失了。
6.2 线性变换
我在大学期间对于线性变换、矩阵有什么作用,是完全没有概念的。所以对于他们的特性研究也没有掌握的很深,基本上是停留在能够把一些联系题做对这个层面。而现在,注意线性变换的广泛应用之后,尝试去理解去本质之后,就会寻根问底的去理解清楚什么是线性变换、什么是矩阵。这里再次说说我的理解。
在一个向量空间中,最为常见的是 \(n \) 维欧氏空间,会有很多的向量,例如每个 Embedding 就可以理解是在一个线性空间中,“线性变换”表述了是空间中的一类映射,该映射满足上述“小结2.1”中的两个要求,即原点依旧到原点、映射保持所谓的“线性”(例如,向量和的映射等于映射的和等)。
在一个向量空间中,一个线性变换就是一个符合一定条件的映射。与向量空间的基的选取是没有关系的。自此,与矩阵也是没有关系的。所以,线性变换本身是更为底层、更为基础的概念。
6.3 欧氏空间的线性变换与矩阵
现在我们把问题限定在 \(n \) 维欧氏空间中。那么,这时候,我们如何描述一个线性变换呢?是的,就是“基”与“矩阵”。
通常,\(n \) 维欧氏空间,我们会先选取一组基,然后使用一个矩阵去描述这个线性变换。并且非常幸运的,一旦这组基 选定了,这个矩阵是唯一的。
结论:在\(n \) 维欧氏空间(这个条件似乎可以去掉)中,对于线性变换 \(\sigma \),如果选定一组“基”,那么就存在唯一的“矩阵”描述该线性变换。
上述的结论,是比较明显的。我们考虑对于线性变换中的上述选定的基向量 \(\alpha_i,\quad \text{where } i = 1,\ldots,n \),线性变换将其映射到 \(\beta_i,\quad \text{where } i = 1,\ldots,n \),那么根据“基”的基本性质,对于这里的任何 \(\beta_i \)都可以表示成\(\alpha_i \)的线性组合,所有的这些系数构成的矩阵,就是上述描述的唯一的“矩阵”。具体的:
$$
\begin{aligned}
\beta_1 &= a_{11}\alpha_1 + a_{21}\alpha_2 + \cdots + a_{n1}\alpha_n \\[0.5em]
\beta_2 &= a_{12}\alpha_1 + a_{22}\alpha_2 + \cdots + a_{n2}\alpha_n \\[0.5em]
&\ \vdots \\[0.5em]
\beta_n &= a_{1n}\alpha_1 + a_{2n}\alpha_2 + \cdots + a_{nn}\alpha_n
\end{aligned}
$$即:
$$
\begin{aligned}
\begin{bmatrix}
\beta_1 & \beta_2 & \cdots & \beta_n
\end{bmatrix}
=
\begin{bmatrix}
\alpha_1 & \alpha_2 & \cdots & \alpha_n
\end{bmatrix}
\begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1n} \\
a_{21} & a_{22} & \cdots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n1} & a_{n2} & \cdots & a_{nn}
\end{bmatrix}
\end{aligned}
$$即在这个线性变换\(\sigma \) 在选定基 \(\alpha_i,\quad \text{where } i = 1,\ldots,n \) 对应的矩阵为:
$$
\begin{aligned}
A =
\begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1n} \\
a_{21} & a_{22} & \cdots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n1} & a_{n2} & \cdots & a_{nn}
\end{bmatrix}
\end{aligned}
$$从这段简洁的“证明”(或“说明”)来看,我们很自然有如下结论,根据空间中的“基”的选取不同,我们会得到不同的矩阵。因为我们反复会提到,我们经常会通过研究矩阵的特性来研究线性变换。那么,同一个线性变换在不同的“基”下的不同“矩阵”,很自然的能够想到,这些“矩阵”是有某些共性的,是的,我们称这些矩阵为“相似矩阵”,相关特性,暂不展开。
7. 特征向量与特征值
7.1 为什么
为什么我们需要关注“特征值与特征向量”呢?为什么我们要去了解奇异值分解(SVD)呢?
原因是“线性变换”是一个映射,是非常抽象的。而特征值 、特征向量、SVD分解可以把线性变换最为关键的特性,以非常“直观”的形式表达出来。当然,这里的“直观”并不是简单意义上能够一眼就看出什么来,事实上,“线性变换”本身就有很强的抽象性,这里的“直观”只是相对的,是否直观,完全依赖于各位看客自己的“悟性”了 。
特征向量的基本定义:如果有 \( \sigma(\xi) = \lambda \xi \) ,那么这里的 \( \xi \) 就是特征向量,对应的 \(\lambda \) 就是对应的特征值。
要想真正说清楚特征向量与特征值是需要非常多篇幅的,而且关于对特征向量的理解对于理解线性变化也是非常关键的,所以,建议花些时间较为系统的做一些理解。如果你已经建立的基础概念,这里的一篇文章可能是帮助你增强一些理解:特征向量与特征值。
7.2 关于对特征向量的理解
完整的讨论特征向量与特征值是复杂的,这里将其限定在一些较为简单的情况,作为一个入门。我们这里考虑最为简单的情况,即对于一个 \(n \times n \)的矩阵,其秩为 \(n \),并且在计算特征值时,有 \(n \) 是不重复的实数解,即没有任何根式重根。如果,恰好 \( n = 2 \)这大概是最为简单的情况了,不过理解这种情况,再进一步拓展,则学习曲线会平滑很多。
我们来看一个实例,在二维空间中,在标准基下,我们有如下的线性变换矩阵:
$$
W = \begin{bmatrix}
2 & 1 \\
1 & 2
\end{bmatrix}
$$根据上述特征向量特征值的定义进行求解,我们可以有如下的特征值与特征向量:
- \( \lambda_1 = 3 \) 特征向量 \( (1,1) \)
- \( \lambda_2 = 1 \) 特性向量 \( (-1,1) \)

从特征向量角度理解线性变换:那么上述的矩阵A对应的线性变换 \(\sigma \) 有如下特性,在这个二维空间任何向量 \(\beta \),都可以分解(投影)为上述两个特征向量方向的向量: \(\beta_1 \,, \beta_2 \),且有:\(\beta = \beta_1 + \beta_2 \)。那么,则有:\(\sigma(\beta) = \lambda_1 \beta_1 + \lambda_2 \beta_2 \)。即,这个线性变换可以这样描述:先将任何向量沿着特征向量方向分解,然后再按照特征值的大小进行拉伸或压缩,然后再把向量合并起来。
上述的解释,可以对照着右图去理解。特征向量分别为 \((1,1) \) 和 \((-1,1) \) ,即图中浅绿色、浅蓝色方向。该矩阵作用在向量 \((0,1) \) 上,即图中的红色向量。先将红色向量沿着浅绿色、浅蓝色方向分解,然后按照特征值进行拉伸,即图中的绿色、蓝色向量,最后合并为图中的紫色最终向量。
上述的场景是线性变换中,最为简单的一类。而实际的线性变换,则更为复杂,可能还涉及到对于向量的旋转、镜像、剪切等变换。关于更多场景可以自己探索,或者阅读相关书籍,也可以看看这篇文章中的更多直观的例子:特征值与特征向量。
“特征向量”可以很好的帮助理解“方阵”变换,还有一类变换时非方阵的情况,通常这时候可以借助于奇异值分解的方式去理解,关于奇异值分解可以参考:奇异值分解–深度学习的数学基础。
8. 一些补充说明
初等的线性代数核心部分大概是这些内容,出于完整性的考虑,可以再进一步了解“Jordan 块”相关的内容,从而把相关理论补充完整,这里不再详述。
如果再回到最初的线性方程组解的问题,我们这里就可以回答最后一个问题:对于一个线性方程组,如果有解,那么所有的解空间是怎样的?
结论:如果方程组的系数矩阵的秩为\( r \),那么解空间的维度为\( n-r \)。解空间的“基”则可以通过初等变换求得。这里不再详述。
9. 再看看前面的问题
$$
\begin{aligned}
\text{Attention Score}_i = XW_i^{QK} X^T \quad \text{where} \,,W_i^{QK} = W_i^Q (W_i^K)^T
\end{aligned}\tag{1}
$$$$
\text{Attention Score}_i = Q_iK_i^T = XW_i^Q(XW_i^K)^T \tag{2}
$$在上面的计算(1) 和 计算(2),那么在模型中训练 \(W_i^{QK} \) 和 在模型中训练单独训练 \(W_i^Q \,,W_i^K \) 是否是等价的?
答案是否定的。
这里以 GTP2 模型为例,原因在于如果单独训练 \(W_i^{QK} \) ,那么这个矩阵的秩,则很可能是 768 ;而单独训练 \(W_i^Q \,,W_i^K \),这两个矩阵的秩则一定小于 64,这两个矩阵的乘积的秩也一定是 64 (严格来说是小于等于)。所以最终训练获得的效果一定是不同的。当然,哪个更好,这倒不一定,但他们并不是等价的。
一般意义来说,使用 \(W_i^{QK} \) 可能有着更强的表达能力,只是意义没有那么明确,并且训练的参数要更多。


