☰
人工智能矩阵实战:从核心概念到落地避坑指南
2026/10/14 1:34:57 网站建设 项目流程

1. 为什么矩阵是人工智能的“母语”

很多人学人工智能,第一反应是去啃深度学习框架的API,调包、跑模型、看准确率,觉得这就是入门了。但真到要改网络结构、推导反向传播、或者排查梯度消失的时候,才发现自己卡在了最底层——矩阵的形状对不上、维度搞混了、转置忘了加。这不是编程问题,这是线性代数没学透。

矩阵在人工智能里的地位,就像汉字在写作里的地位。你可以不识字靠语音输入写文章,但一旦要改稿、要推敲措辞,不识字就是寸步难行。人工智能的所有数据——一张图片、一段文本、一条用户行为记录——最终都会被表示成矩阵或张量。神经网络的每一层运算,本质上就是矩阵乘法加上非线性变换。你调的那个model.fit(),底层跑的是成千上万次矩阵运算。

这篇内容适合谁看?如果你正在学机器学习、深度学习,或者准备面试算法岗,但一看到矩阵求导、特征值分解就头疼,那这篇就是写给你的。我不打算照本宣科地讲教材,而是从“一个从业者在实际项目里怎么用矩阵”这个角度,把核心概念、实操要点、踩坑经验一次讲清楚。看完你至少能做到三件事:看懂论文里的矩阵公式、自己推导简单的反向传播、在代码里正确处理矩阵维度。

2. 矩阵的核心概念与人工智能的对应关系

2.1 矩阵的本质:从数据表到线性变换

教科书上矩阵的定义是“由数排列成的矩形阵列”,这个定义没错但太静态了。在人工智能的语境下,矩阵有两种理解方式,而且这两种方式要能随时切换。

第一种是数据容器。一个班30个学生,每人有语文、数学、英语3门课成绩,这就是一个30×3的矩阵。在机器学习里,你的训练集通常就是这样一个矩阵:行是样本,列是特征。图像数据稍微复杂一点,一张28×28的灰度图是一个二维矩阵,彩色图则是28×28×3的三维张量。文本数据经过词嵌入之后,一句话变成一个序列长度×嵌入维度的矩阵。

第二种是线性变换。这是更本质的理解。一个m×n的矩阵A,作用在一个n维向量x上,得到一个新的m维向量y=Ax。这个过程可以理解为:把n维空间里的一个点,映射到m维空间里的另一个点。神经网络的一层,如果忽略激活函数,做的就是这件事——把输入向量通过权重矩阵变换到输出空间。

提示:很多初学者卡在“矩阵乘法为什么这么定义”上。其实矩阵乘法的定义就是为了让“复合变换”能够用矩阵表示。先做变换B再做变换A,等价于用矩阵AB去变换。这个定义不是随便定的,是为了让线性变换的复合有简洁的代数表达。

2.2 形状匹配:矩阵运算的第一道门槛

在实际写代码的时候,90%的矩阵相关报错都是形状不匹配。我把常见的形状规则整理成一张表,建议你贴在显示器旁边。

运算形状要求结果形状常见错误
矩阵加法 A+BA和B形状完全相同同形状广播机制导致意外结果
矩阵乘法 ABA的列数 = B的行数(A行数, B列数)维度不匹配报错
逐元素乘法 A⊙B形状相同或可广播广播后的形状和矩阵乘法混淆
转置 A^T无要求行列互换忘记转置导致乘法失败
求逆 A^{-1}方阵且满秩同形状奇异矩阵报错

这里重点说广播机制。NumPy和PyTorch都支持广播,它让形状不同的数组也能做逐元素运算。比如一个(3,4)的矩阵加上一个(4,)的向量,向量会被自动扩展成(3,4)。广播很方便,但也是bug的温床。我见过太多人因为广播导致结果形状不对,但程序不报错,最后模型效果差得离谱却找不到原因。

注意:调试矩阵代码时,养成随时打印.shape的习惯。尤其是在神经网络的前向传播里,每一层的输入输出形状都要心里有数。我个人的做法是在写模型之前,先在纸上画一遍张量形状的流转图。

2.3 特殊矩阵:人工智能里的“常用工具”

有几类特殊矩阵在人工智能里出现频率极高,值得单独拎出来说。

单位矩阵I:对角线为1,其余为0。它的作用类似于数字里的1,任何矩阵乘以单位矩阵都不变。在残差网络(ResNet)里,跳跃连接本质上就是加了一个单位变换,让梯度能够直接传回去。

对角矩阵:只有对角线有非零元素。对角矩阵的乘法计算量极小,因为只需要逐元素相乘。在批归一化(BatchNorm)里,缩放操作就是用一个对角矩阵去乘。

正交矩阵:满足Q^T Q = I的矩阵。正交矩阵的逆等于它的转置,这个性质在计算上非常友好。在循环神经网络(RNN)里,使用正交初始化可以缓解梯度消失问题,因为正交矩阵不改变向量的范数。

对称矩阵:满足A = A^T的矩阵。协方差矩阵就是对称矩阵,在主成分分析(PCA)里,我们对协方差矩阵做特征值分解,对称矩阵保证了特征值都是实数,特征向量相互正交。

正定矩阵:对于任意非零向量x,都有x^T A x > 0。正定矩阵在优化里很重要,因为如果损失函数的二阶导数矩阵(海森矩阵)是正定的,说明当前点是一个局部极小值。

3. 矩阵运算的实操要点与避坑指南

3.1 矩阵乘法:不只是“行乘列”

矩阵乘法的标准定义是:C = AB,其中C的第i行第j列元素等于A的第i行与B的第j列的内积。这个定义大家都会背,但实际用的时候有几个点容易出错。

第一,矩阵乘法不满足交换律。AB ≠ BA,这是最常见的坑。在神经网络里,权重矩阵和输入矩阵的顺序绝对不能搞反。通常输入是(batch_size, input_dim),权重是(input_dim, output_dim),所以是输入乘以权重,得到(batch_size, output_dim)。如果你写成权重乘以输入,形状直接对不上。

第二,矩阵乘法的计算复杂度。一个(m,n)的矩阵乘以(n,p)的矩阵,计算量是O(mnp)。当m、n、p都很大的时候,这个计算量是惊人的。这就是为什么深度学习需要GPU——GPU的并行计算能力特别适合做大规模的矩阵乘法。在实际工程里,我们经常要把大矩阵乘法拆分成小块,或者用低秩近似来加速。

第三,批量矩阵乘法。在深度学习框架里,我们处理的往往是三维张量:(batch_size, n, m)。这时候的矩阵乘法是批量进行的,即对batch里的每个样本分别做矩阵乘法。PyTorch里的torch.bmm就是干这个的。理解批量矩阵乘法对于实现自定义层非常关键。

import torch # 批量矩阵乘法示例 batch_size = 32 n, m, p = 10, 20, 5 A = torch.randn(batch_size, n, m) B = torch.randn(batch_size, m, p) # 批量矩阵乘法,结果是(batch_size, n, p) C = torch.bmm(A, B) print(C.shape) # torch.Size([32, 10, 5])

3.2 矩阵求导:反向传播的数学基础

矩阵求导是很多人学线性代数时的噩梦,但它在反向传播里无处不在。我先说一个结论:你不需要记住所有矩阵求导公式,但需要理解求导的维度逻辑。

标量对向量求导,结果是一个向量,形状和自变量相同。向量对标量求导,结果也是向量。向量对向量求导,结果是一个矩阵(雅可比矩阵)。矩阵对矩阵求导,结果是一个四维张量——这个在深度学习里很少直接用到,因为框架会自动帮你处理。

在实际推导反向传播时,最常用的是链式法则的矩阵形式。假设y = Wx + b,损失函数L对y的梯度是∂L/∂y,那么∂L/∂W = (∂L/∂y) x^T,∂L/∂x = W^T (∂L/∂y)。这两个公式一定要记牢,它们是全连接层反向传播的核心。

实操心得:推导矩阵求导时,先写出标量形式的表达式,然后观察每个元素的偏导数,最后整理成矩阵形式。不要一上来就试图直接写出矩阵公式,那样容易出错。我个人的习惯是先用小维度(比如2×2)手动推导一遍,确认无误后再推广到一般情况。

3.3 特征值分解与奇异值分解:降维与压缩的利器

特征值分解和奇异值分解(SVD)是矩阵分析里最重要的两个分解,在人工智能里应用极广。

特征值分解要求矩阵是方阵。A = QΛQ^{-1},其中Λ是对角矩阵,对角线上的元素是特征值,Q的列是对应的特征向量。特征值分解的物理意义是:矩阵A作用在特征向量上,只改变向量的长度(缩放特征值倍),不改变方向。在PCA里,我们对协方差矩阵做特征值分解,特征值大的方向就是数据方差大的方向,也就是主成分方向。

奇异值分解适用于任意矩阵。A = UΣV^T,其中U和V是正交矩阵,Σ是对角矩阵(对角线元素是奇异值)。SVD的应用更广泛:推荐系统里的矩阵分解、图像压缩、潜在语义分析(LSA)都用它。在推荐系统里,用户-物品评分矩阵通常非常稀疏,用SVD分解后,可以用低秩矩阵来近似原始矩阵,从而预测缺失的评分。

import numpy as np # SVD示例:图像压缩 # 假设img是一个灰度图像矩阵 U, S, Vt = np.linalg.svd(img, full_matrices=False) # 只保留前k个奇异值 k = 50 S_k = np.diag(S[:k]) img_compressed = U[:, :k] @ S_k @ Vt[:k, :] # img_compressed是压缩后的图像,存储量大大减少

注意:SVD的计算复杂度是O(mn^2)(对于m×n矩阵,假设m>n),当矩阵很大时计算代价很高。在实际工程里,我们通常用随机SVD或者增量SVD来处理大规模矩阵。另外,SVD对数据的中心化很敏感,做PCA之前一定要先减去均值。

4. 矩阵在人工智能核心场景中的落地实践

4.1 神经网络前向传播:矩阵乘法的流水线

一个全连接神经网络的前向传播,本质上就是一系列矩阵乘法加上激活函数。假设输入是x(形状为(batch_size, input_dim)),第一层权重是W1(形状为(input_dim, hidden_dim)),偏置是b1(形状为(hidden_dim,)),那么第一层的输出是:

h1 = relu(x @ W1 + b1)

这里的@是矩阵乘法。x @ W1的结果是(batch_size, hidden_dim),加上b1时,b1会自动广播到每一行。然后经过relu激活函数,得到h1。

第二层类似:h2 = relu(h1 @ W2 + b2),以此类推。最后一层通常不加激活函数(回归问题)或者加softmax(分类问题)。

这个流程看起来简单,但有几个实操细节容易忽略。第一,权重初始化很关键。如果权重全部初始化为0,那么所有神经元的输出都一样,反向传播时梯度也一样,网络永远学不到东西。常用的初始化方法有Xavier初始化和He初始化,它们根据输入输出的维度来调整初始权重的方差。第二,偏置的广播要小心。b1的形状是(hidden_dim,),它会被广播到(batch_size, hidden_dim),这是正确的。但如果你不小心把b1定义成了(batch_size, hidden_dim),那就错了,因为每个样本应该共享同一个偏置。

4.2 卷积运算:矩阵乘法的特殊形式

卷积神经网络(CNN)里的卷积运算,乍看和矩阵乘法没关系,但实际上可以通过im2col操作转化成矩阵乘法。

im2col的思路是:把输入特征图上每个卷积核覆盖的区域拉成一个列向量,所有区域拉成的列向量拼成一个大矩阵。同时把卷积核也拉成行向量。然后做一次矩阵乘法,就完成了卷积。这个技巧在深度学习框架里被广泛使用,因为矩阵乘法有高度优化的BLAS库支持,比直接实现卷积快得多。

理解这一点很重要,因为它解释了为什么CNN的计算量可以用矩阵乘法的复杂度来分析。一个卷积层的计算量大约是:输出特征图大小 × 卷积核大小 × 输入通道数 × 输出通道数。当这些数字都很大的时候,计算量是惊人的。这也是为什么移动端部署CNN需要做模型压缩和加速。

实操心得:在PyTorch里,nn.Conv2d的底层就是用了im2col加矩阵乘法。如果你自己实现卷积层,可以用torch.nn.Unfold来做im2col,然后调用torch.bmm做批量矩阵乘法。这样写出来的卷积层,速度比用for循环快几十倍。

4.3 注意力机制:矩阵乘法的华丽应用

Transformer里的注意力机制,核心就是几个矩阵乘法。给定查询矩阵Q、键矩阵K、值矩阵V,注意力计算为:

Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V

这里的QK^T是矩阵乘法,结果是每个查询和每个键的相似度分数。除以sqrt(d_k)是为了防止点积过大导致softmax梯度消失。softmax之后得到注意力权重,再乘以V得到加权和。

这个计算里,Q、K、V的形状通常是(batch_size, seq_len, d_k)。QK^T的结果是(batch_size, seq_len, seq_len),这个矩阵的大小是序列长度的平方。当序列长度很大时(比如处理长文档),这个矩阵会消耗大量内存。这就是为什么长序列的Transformer训练需要特殊优化,比如稀疏注意力、线性注意力等。

import torch import torch.nn.functional as F def attention(Q, K, V): d_k = Q.size(-1) scores = torch.bmm(Q, K.transpose(1, 2)) / (d_k ** 0.5) weights = F.softmax(scores, dim=-1) return torch.bmm(weights, V) # 示例 batch_size, seq_len, d_k = 2, 10, 64 Q = torch.randn(batch_size, seq_len, d_k) K = torch.randn(batch_size, seq_len, d_k) V = torch.randn(batch_size, seq_len, d_k) output = attention(Q, K, V) print(output.shape) # torch.Size([2, 10, 64])

4.4 推荐系统:矩阵分解的经典应用

推荐系统里有一个经典问题:用户-物品评分矩阵非常稀疏,大部分位置是缺失的。矩阵分解的目标是找到两个低秩矩阵,使得它们的乘积尽可能逼近已知的评分。

假设用户数是m,物品数是n,评分矩阵R是m×n。矩阵分解把R近似为P×Q^T,其中P是m×k,Q是n×k,k是潜在因子维度(通常远小于m和n)。P的每一行代表一个用户的潜在偏好向量,Q的每一行代表一个物品的潜在特征向量。预测用户u对物品i的评分就是P_u和Q_i的内积。

这个方法的妙处在于:即使某个用户和某个物品在训练数据里没有交互,只要它们各自的潜在向量相似,就能预测出评分。这就是矩阵分解能够做推荐的原因。

在实际实现时,我们通常用随机梯度下降来优化P和Q,最小化已知评分的预测误差加上正则化项。正则化很重要,因为评分矩阵很稀疏,不加正则化很容易过拟合。

5. 常见问题与排查技巧实录

5.1 形状不匹配:最常见的报错

形状不匹配是矩阵相关代码里出现频率最高的错误。我把常见的形状问题和解决方法整理成一张速查表。

报错信息可能原因解决方法
mat1 and mat2 shapes cannot be multiplied矩阵乘法维度不匹配检查A的列数是否等于B的行数
The size of tensor a must match tensor b逐元素运算形状不同且无法广播检查两个张量的形状,必要时reshape
expected 4D input卷积层输入维度不对确认输入是(batch, channel, H, W)
index out of range索引超出了矩阵维度打印矩阵形状,检查索引范围
nan in loss矩阵运算出现数值问题检查是否有除零、log(0)、梯度爆炸

排查形状问题的标准流程是:从报错的那一行往前找,打印每一步的张量形状,找到第一个形状不符合预期的地方。我个人的习惯是在模型的前向传播里加一个debug模式,每一步都打印形状,这样出问题能立刻定位。

5.2 数值稳定性:矩阵运算的隐形杀手

矩阵运算里的数值问题很隐蔽,程序不报错,但结果就是不对。常见的数值问题包括:

梯度爆炸:矩阵连乘导致梯度指数级增长。解决方法有梯度裁剪、使用残差连接、合理的权重初始化。

梯度消失:矩阵连乘导致梯度指数级衰减。解决方法有使用ReLU激活函数、批归一化、LSTM等门控机制。

矩阵求逆的数值不稳定:当矩阵接近奇异时,求逆的结果误差很大。解决方法是用伪逆(pinv)代替求逆,或者加一个小的正则化项(Tikhonov正则化)。

softmax溢出:当输入值很大时,exp(x)会溢出。解决方法是在做softmax之前先减去最大值,即softmax(x) = softmax(x - max(x))。

注意:在实现自己的损失函数或层时,一定要考虑数值稳定性。比如计算log(softmax(x))时,不要先算softmax再算log,而是直接用log_softmax,框架内部做了数值优化。

5.3 性能优化:让矩阵运算跑得更快

矩阵运算的性能优化有几个方向:

利用BLAS库:NumPy和PyTorch底层都调用了BLAS(基础线性代数子程序)库,这些库针对不同硬件做了高度优化。所以能用矩阵乘法就不要用for循环。

批处理:把多个小矩阵乘法合并成一个大矩阵乘法,能显著提升GPU利用率。比如处理多个样本时,用批量矩阵乘法而不是循环。

内存布局:矩阵在内存里的存储顺序(行优先还是列优先)会影响访问速度。在PyTorch里,默认是行优先,但某些操作(如转置)会导致内存不连续,影响后续运算速度。可以用.contiguous()把张量变成连续存储。

混合精度:使用float16代替float32做矩阵运算,速度能提升一倍左右,内存占用减半。但要注意float16的数值范围较小,容易溢出,通常需要配合梯度缩放(gradient scaling)使用。

# 混合精度训练示例 from torch.cuda.amp import autocast, GradScaler scaler = GradScaler() for data, target in dataloader: optimizer.zero_grad() with autocast(): output = model(data) loss = loss_fn(output, target) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()

5.4 调试矩阵代码的实用技巧

调试矩阵代码和调试普通代码不太一样,因为矩阵运算往往是批量进行的,单个元素的错误会被淹没在大量正确结果里。我总结了几条实用技巧:

第一,用小维度测试。不要一上来就用完整的数据集和模型,先用2×2或3×3的小矩阵测试你的逻辑。小维度下你可以手动验证结果,确认无误后再扩展到大规模。

第二,可视化中间结果。对于图像相关的矩阵,把中间特征图可视化出来,能直观地看到问题。对于非图像数据,可以打印统计量(均值、方差、最大值、最小值)来检查是否正常。

第三,梯度检查。实现自定义层时,用数值梯度(有限差分)来验证解析梯度是否正确。虽然数值梯度计算慢,但作为一次性检查非常有效。

第四,单元测试。为每个矩阵操作写单元测试,输入已知的矩阵,验证输出是否符合预期。这在团队协作里尤其重要,能防止修改代码时引入回归错误。

6. 从矩阵到张量:维度扩展的思维跃迁

6.1 张量:矩阵的高维推广

在深度学习里,我们处理的往往不是二维矩阵,而是更高维的张量。一张彩色图片是三维张量(高度、宽度、通道),一个batch的图片是四维张量(batch、高度、宽度、通道),一个batch的序列数据是三维张量(batch、序列长度、特征维度)。

从矩阵到张量,最大的思维转变是:矩阵乘法变成了张量收缩。两个张量做乘法时,需要指定哪些维度参与收缩(即内积),哪些维度保留。比如(batch, n, m)和(batch, m, p)做批量矩阵乘法,收缩的是m维度,保留的是batch、n、p维度。

理解张量收缩的最好方法是爱因斯坦求和约定。用torch.einsum可以简洁地表达各种复杂的张量运算。

import torch # 批量矩阵乘法用einsum表示 A = torch.randn(32, 10, 20) B = torch.randn(32, 20, 5) C = torch.einsum('bij,bjk->bik', A, B) print(C.shape) # torch.Size([32, 10, 5]) # 注意力机制用einsum表示 Q = torch.randn(2, 10, 64) K = torch.randn(2, 10, 64) V = torch.randn(2, 10, 64) scores = torch.einsum('bqd,bkd->bqk', Q, K) / (64 ** 0.5) weights = torch.softmax(scores, dim=-1) output = torch.einsum('bqk,bkd->bqd', weights, V) print(output.shape) # torch.Size([2, 10, 64])

einsum的好处是直观、不易出错,而且PyTorch会自动优化计算顺序。缺点是对于特别大的张量,einsum可能不如手写的专用操作快。但在原型开发阶段,einsum能极大提升效率。

6.2 广播机制:张量运算的便利与陷阱

广播机制让不同形状的张量能够做逐元素运算,规则是:从最后一个维度开始对齐,维度大小相等或其中一个为1时才能广播。比如(3, 1, 4)和(2, 4)可以广播成(3, 2, 4)。

广播很方便,但也是bug的高发区。我踩过的一个坑是:本来想对每个样本做不同的缩放,结果因为广播,所有样本用了同一个缩放。程序不报错,但结果完全不对。

避免广播陷阱的方法是:显式地reshape。如果你想让某个维度参与广播,就明确地把它reshape成1,而不是依赖隐式广播。这样代码的可读性更好,也不容易出错。

6.3 矩阵分解在模型压缩中的应用

随着模型越来越大,模型压缩成了一个热门方向。矩阵分解是模型压缩的重要手段之一。

以全连接层为例,一个(input_dim, output_dim)的权重矩阵,参数量是input_dim × output_dim。如果把它分解成两个低秩矩阵:(input_dim, rank)和(rank, output_dim),参数量变成input_dim × rank + rank × output_dim。当rank远小于input_dim和output_dim时,参数量大幅减少。

这种低秩分解在移动端部署里很常见。比如一个1000×1000的权重矩阵,参数量是100万。如果rank取100,参数量变成1000×100 + 100×1000 = 20万,减少了80%。当然,低秩分解会带来精度损失,需要在压缩率和精度之间做权衡。

实操心得:做低秩分解时,通常先对原始权重矩阵做SVD,然后保留前rank个奇异值。rank的选择可以通过观察奇异值的衰减曲线来确定——如果前几个奇异值很大,后面的迅速衰减,说明矩阵本身接近低秩,可以用较小的rank。如果奇异值衰减很慢,说明矩阵信息分布均匀,低秩分解的效果有限。

7. 矩阵学习路径与实战建议

7.1 学习路径:从理解到熟练

如果你现在矩阵基础薄弱,我建议按这个顺序补:

第一步,理解矩阵乘法的几何意义。不要只背公式,要理解矩阵乘法对应着线性变换的复合。推荐3Blue1Brown的线性代数系列视频,可视化做得非常好,能帮你建立直觉。

第二步,动手实现基本运算。用NumPy或PyTorch实现矩阵乘法、转置、求逆、特征值分解。不要调库,自己写一遍,哪怕效率低。写的过程中你会遇到各种形状问题,解决这些问题就是学习的过程。

第三步,推导反向传播。找一个简单的两层神经网络,手动推导一遍反向传播的矩阵公式。这一步能帮你把矩阵求导和神经网络联系起来。

第四步,阅读经典论文里的矩阵运算。比如Transformer的论文,里面全是矩阵公式。试着把每个公式用代码实现出来,验证形状是否正确。

第五步,在实际项目里应用。找一个你感兴趣的项目,比如图像分类、文本情感分析,从头实现一遍。遇到矩阵相关的问题,查资料、做实验、总结规律。

7.2 实战建议:少走弯路的经验

第一,不要追求一次写对。矩阵代码很难一次写对,尤其是涉及复杂形状变换的时候。我的习惯是先写一个能跑通的小版本,用随机数据测试,确认形状和数值都正确后,再扩展到完整数据。

第二,善用断言。在代码里加assert语句检查张量形状,比如assert x.shape[1] == self.weight.shape[0]。这样一旦形状不对,程序会立刻报错,而不是等到后面才出现莫名其妙的错误。

第三,保持维度标注的习惯。在写代码时,用注释标注每个张量的形状,比如# x: (batch, seq_len, d_model)。这样即使过了几个月回头看代码,也能快速理解。

第四,多画图。把张量形状的流转画成图,比在脑子里想要可靠得多。尤其是实现复杂模型时,画图能帮你发现维度不匹配的问题。

第五,不要害怕数学。很多人一看到矩阵公式就跳过,只看代码。但代码只是数学的实现,不理解数学,代码也只能照抄,遇到问题就束手无策。花时间把数学搞懂,长期来看是值得的。

7.3 工具推荐:让矩阵运算更高效

NumPy:最基础的数值计算库,适合做小规模矩阵运算和原型验证。

PyTorch:深度学习框架,支持GPU加速和自动求导,适合做大规模矩阵运算和神经网络训练。

JAX:Google推出的数值计算库,支持自动微分和JIT编译,在科研领域很流行。

Einops:一个专门做张量重排的库,用rearrange、reduce等操作替代reshape和transpose,代码可读性极高。

from einops import rearrange, reduce # 传统写法 x = x.transpose(1, 2).reshape(batch, seq_len, -1) # einops写法 x = rearrange(x, 'b h w c -> b (h w) c')

einops的好处是,操作的含义一目了然,不容易搞错维度顺序。我强烈推荐在项目里使用einops,尤其是处理多维张量的时候。

矩阵这个东西,初学的时候觉得抽象,用多了就会发现它是描述数据变换最自然的语言。人工智能的每一个模型,拆到最底层都是矩阵运算。把矩阵搞懂了,再看那些复杂的网络结构,就会发现它们不过是矩阵运算的不同组合方式。我在实际项目里的体会是:花在矩阵上的时间,最终都会以调试效率的提升和模型理解深度的增加回报给你。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询