我觉得GPT老师的语言功底比大多数的博客主要好(包括我自己),阅读起来更易理解,而且哪里不明白还可以直接问gpt老师,孜孜不倦,尽心尽责,全天待命,究极贴心。有这么厉害的一个老师,不学习简直暴殄天物。
于是乎我准备立一个flag,挑战跟着GPT老师学习365天,每天我都会整理自己的学习心得和脉络(文字大部分都是GPT直接生成的,我觉得比我自己写肯定好多了)感谢gpt老师!跪谢
全系列文章:跟着GPT学习-AI系列
本文翻译自文章:线性代数
线性代数
标量
大多数日常数值计算都是一次处理一个数值。我们称这些数值为标量。例如,帕洛阿尔托的温度是温和的72华氏度。为了将温度转换为摄氏度,你可以使用公式:
c
=
5
9
(
f
−
32
)
c = \frac{5}{9}(f - 32)
c=95(f−32)
其中 ( f ) 是温度,值5,9,32等是常数标量 是常数标量。变量 ( c ) 和 ( f ) 一般表示未知标量。
在数学中,标量用小写字母表示(例如 x x x, y y y 和 z z z),它们可以是实数范围内的任意值。为了方便,我们将省略对空间的严格定义,只需记住表达式 x ∈ R x \in \mathbb{R} x∈R 代表 ( x ) 是一个实值标量。符号 ∈ \in ∈ 表示集合成员身份。例如, x , y ∈ { 0 , 1 } x, y \in \{0, 1\} x,y∈{0,1} 表示 x x x 和 y y y 只能取值 0 或 1。
标量在实际中实现为仅包含一个元素的张量。下面是如何在PyTorch中定义和操作标量:
import torch
x = torch.tensor(3.0)
y = torch.tensor(2.0)
x + y, x * y, x / y, x ** y
输出结果为:
(tensor(5.), tensor(6.), tensor(1.5000), tensor(9.))
向量
向量可以看作是有序排列的一组标量。这些标量称为向量的分量。当向量表示来自实数世界的某些数据时,它们可以有一些实际的物理意义。例如,在机器学习中,向量可以用来表示输入特征。
在代码中,我们可以使用一维张量来表示向量。以下是如何在PyTorch中定义和操作向量:
import torch
x = torch.arange(3)
x
输出结果为:
tensor([0, 1, 2])
我们可以使用下标来访问向量的元素。例如, ( x_2 ) 表示第二个元素,自然从0开始计数。在PyTorch中,通过下标访问元素:
x[2]
输出结果为:
tensor(2)
向量包含三个元素,因此:
len(x)
输出结果为:
3
张量的形状可以通过 .shape 属性来访问。形状是一个元组,表示张量沿每个轴的长度。对于一维张量,形状中只有一个元素:
x.shape
输出结果为:
torch.Size([3])
总的来说,“维度”这个词包括轴的数量以及沿每个轴的长度。为了避免混淆,最好使用张量的形状来表示维度。
矩阵
矩阵和向量一样,矩阵也是一种特殊的张量。矩阵是二维的张量,表示为 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n,其中 m m m 是行数, n n n 是列数。我们使用大写字母表示矩阵(例如, X X X、 Y Y Y和 Z Z Z),并在代码中使用两个索引来表示它们的元素。一个矩阵可以看作由 m m m个行向量和 n n n 个列向量组成。矩阵的元素通常表示为 a i j a_{ij} aij,其中 i i i 是行索引, j j j 是列索引。
例如,矩阵 ( A ) 的表示如下:
A = ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ) A = \begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{pmatrix} A= a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn
创建矩阵
我们可以使用PyTorch中的reshape方法将一维张量转换为矩阵。例如,创建一个
2
×
3
2 \times 3
2×3 的矩阵:
import torch
A = torch.arange(6).reshape(2, 3)
A
输出结果为:
tensor([[0, 1, 2],
[3, 4, 5]])
转置矩阵
矩阵的转置是通过交换矩阵的行和列得到的。对于矩阵 ( A ) ,其转置矩阵记作 ( A^T ),定义为:
A T = ( a 11 a 21 ⋯ a m 1 a 12 a 22 ⋯ a m 2 ⋮ ⋮ ⋱ ⋮ a 1 n a 2 n ⋯ a m n ) A^T = \begin{pmatrix} a_{11} & a_{21} & \cdots & a_{m1} \\ a_{12} & a_{22} & \cdots & a_{m2} \\ \vdots & \vdots & \ddots & \vdots \\ a_{1n} & a_{2n} & \cdots & a_{mn} \end{pmatrix} AT= a11a12⋮a1na21a22⋮a2n⋯⋯⋱⋯am1am2⋮amn
在代码中,我们可以使用.T属性来获取矩阵的转置:
A.T
输出结果为:
tensor([[0, 3],
[1, 4],
[2, 5]])
对称矩阵
如果一个矩阵等于其转置矩阵,则称为对称矩阵。对称矩阵满足 A = A T A = A^T A=AT。例如,检查矩阵是否对称:
A = torch.tensor([[1, 2, 3], [2, 4, 5], [3, 5, 6]])
A == A.T
输出结果为:
tensor([[True, True, True],
[True, True, True],
[True, True, True]])
上面的代码显示矩阵 A A A 是对称的,因为每个元素都满足 a i j = a j i a_{ij} = a_{ji} aij=aji。
张量
张量是机器学习中的一种基本数据结构,用于表示多维数组。张量可以有任意数量的轴(维度),这使得它们能够表示标量、向量和矩阵等各种数据结构。尽管张量这个术语可能会造成混淆,但它实际上是一个非常灵活的工具。
张量表示法使用大写字母和特殊字体,例如 X , Y , Z X, Y, Z X,Y,Z,并使用下标表示其元素,如 x i j k x_{ijk} xijk。当我们开始处理图像时,张量变得尤为重要。每幅图像都可以表示为一个三维张量,其轴分别对应高度、宽度和通道。多幅图像则可以表示为四维张量,其中额外的一个轴表示图像的数量。
在PyTorch中,我们可以如下创建一个张量:
import torch
torch.arange(24).reshape(2, 3, 4)
输出结果为:
tensor([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
张量算法的基本性质
张量算法具有一些基本性质。例如,元素级运算会产生与输入张量形状相同的输出。
张量加法
我们可以对张量进行加法运算。以下是创建两个张量并进行加法运算的示例:
import torch
A = torch.arange(6, dtype=torch.float32).reshape(2, 3)
B = A.clone() # Assign a copy of A to B by allocating new memory
A, A + B
输出结果为:
(tensor([[0., 1., 2.],
[3., 4., 5.]]),
tensor([[ 0., 2., 4.],
[ 6., 8., 10.]]))
Hadamard积
两个矩阵的元素乘积称为Hadamard积(或逐元素乘积)。对于两个矩阵 A , B ∈ R m × n A, B \in \mathbb{R}^{m \times n} A,B∈Rm×n,Hadamard积定义为:
A ∘ B = ( a 11 b 11 a 12 b 12 ⋯ a 1 n b 1 n a 21 b 21 a 22 b 22 ⋯ a 2 n b 2 n ⋮ ⋮ ⋱ ⋮ a m 1 b m 1 a m 2 b m 2 ⋯ a m n b m n ) A \circ B = \begin{pmatrix} a_{11}b_{11} & a_{12}b_{12} & \cdots & a_{1n}b_{1n} \\ a_{21}b_{21} & a_{22}b_{22} & \cdots & a_{2n}b_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1}b_{m1} & a_{m2}b_{m2} & \cdots & a_{mn}b_{mn} \end{pmatrix} A∘B= a11b11a21b21⋮am1bm1a12b12a22b22⋮am2bm2⋯⋯⋱⋯a1nb1na2nb2n⋮amnbmn
在代码中,我们可以使用*操作符来计算Hadamard积:
A * B
输出结果为:
tensor([[ 0., 1., 4.],
[ 9., 16., 25.]])
张量与标量相加
将标量与张量相加或相乘会产生与原张量形状相同的结果。以下示例演示了将标量添加到张量的每个元素中:
a = 2
X = torch.arange(24).reshape(2, 3, 4)
a + X, (a + X).shape
输出结果为:
(tensor([[[ 2, 3, 4, 5],
[ 6, 7, 8, 9],
[10, 11, 12, 13]],
[[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]]]),
torch.Size([2, 3, 4]))
Reduction 归约
在深度学习和张量运算的上下文中,“reduction”通常指的是“归约”操作。归约操作是指将张量的多个元素通过某种方式(如求和、求平均值等)合并为一个单一的值或较低维度的张量。用公式表示为:
∑
i
=
1
n
x
i
\sum_{i=1}^n x_i
∑i=1nxi
在PyTorch中,可以通过以下代码计算张量的总和:
import torch
x = torch.arange(3, dtype=torch.float32)
x, x.sum()
输出结果为:
(tensor([0., 1., 2.]), tensor(3.))
为了表示任意形状张量的元素和,可以对张量的所有轴求和。例如,
m
×
n
m \times n
m×n 矩阵
A
A
A 的总和可以写为:
∑
i
=
1
m
∑
j
=
1
n
a
i
j
\sum_{i=1}^m \sum_{j=1}^n a_{ij}
i=1∑mj=1∑naij
使用以下代码计算矩阵 ( A ) 的总和及其形状:
A = torch.tensor([[1, 2, 3], [4, 5, 6]])
A.shape, A.sum()
输出结果为:
(torch.Size([2, 3]), tensor(21))
默认情况下,sum函数会沿所有轴求和,最后生成标量。我们还可以指定沿哪些轴减少张量。对行(轴0)上的所有元素求和,可以生成一维输出张量:
A.shape, A.sum(axis=0).shape
输出结果为:
(torch.Size([2, 3]), torch.Size([3]))
指定axis=1将通过对所有列元素求和来减少列维度(轴1):
A.shape, A.sum(axis=1).shape
输出结果为:
(torch.Size([2, 3]), torch.Size([2]))
通过求和沿行和列减少张量维度相当于将矩阵的所有元素相加:
A.sum(axis=(0, 1)) == A.sum()
输出结果为:
tensor(True)
一个相关的量是平均值,也称为均值。我们通过将总和除以元素总数来计算平均值。以下代码展示了如何计算张量的平均值和总和:
A.mean(), A.sum() / A.numel()
输出结果为:
(tensor(3.5000), tensor(3.5000))
同时,计算平均值的函数也可以沿特定轴减少张量:
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
输出结果为:
(tensor([2.5000, 3.5000, 4.5000]), tensor([2.5000, 3.5000, 4.5000]))
非归约求和
有时候,在调用计算总和或均值的函数时,保持轴的数量不变是有用的。这在我们想要使用广播机制时尤为重要。
在PyTorch中,我们可以通过如下代码实现这一点:
import torch
A = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
sum_A = A.sum(axis=1, keepdims=True)
sum_A, sum_A.shape
输出结果为:
(tensor([[ 6.],
[15.]]),
torch.Size([2, 1]))
例如,由于 sum_A 在对每一行求和后保持其二维形状,我们可以通过广播机制将 A 除以 sum_A,从而创建一个每行元素总和为1的矩阵:
A / sum_A
输出结果为:
tensor([[0.1667, 0.3333, 0.5000],
[0.2667, 0.3333, 0.4000]])
如果我们想计算张量 A 元素在某个轴上的累积和,例如沿轴0(逐行)计算,我们可以调用 cumsum 函数。按照设计,这个函数不会沿任何轴减少输入张量的维数:
A.cumsum(axis=0)
输出结果为:
tensor([[1., 2., 3.],
[5., 7., 9.]])
点积
到目前为止,我们仅进行了逐元素运算、求和和平均值。如果这就是线性代数的全部内容,那么它就不值得单独列出一个章节。幸运的是,这部分内容会变得更加有趣。点积是最基本的操作之一。给定两个向量 x , y ∈ R d \mathbf{x}, \mathbf{y} \in \mathbb{R}^d x,y∈Rd,它们的点积 x ⋅ y \mathbf{x} \cdot \mathbf{y} x⋅y(也称为内积 ⟨ x , y ⟩ \langle \mathbf{x}, \mathbf{y} \rangle ⟨x,y⟩)是相同位置元素的乘积之和:
x ⋅ y = ∑ i = 1 d x i y i \mathbf{x} \cdot \mathbf{y} = \sum_{i=1}^d x_i y_i x⋅y=i=1∑dxiyi
在PyTorch中,可以通过以下代码计算两个向量的点积:
import torch
x = torch.arange(3, dtype=torch.float32)
y = torch.ones(3, dtype=torch.float32)
x, y, torch.dot(x, y)
输出结果为:
(tensor([0., 1., 2.]), tensor([1., 1., 1.]), tensor(3.))
等价地,我们可以通过逐元素相乘后再求和的方式计算两个向量的点积:
torch.sum(x * y)
输出结果为:
tensor(3.)
点积在许多情况下非常有用。例如,给定一组值 x ∈ R n \mathbf{x} \in \mathbb{R}^n x∈Rn和一组权重 w ∈ R n \mathbf{w} \in \mathbb{R}^n w∈Rn,根据权重对值进行加权求和可以表示为点积 w ⋅ x \mathbf{w} \cdot \mathbf{x} w⋅x。当权重非负并且总和为1时(即 ∑ i = 1 n w i = 1 \sum_{i=1}^n w_i = 1 ∑i=1nwi=1),点积表示加权平均值。
矩阵-向量乘积
了解如何计算点积后,我们可以开始理解 m × n m \times n m×n 矩阵 A \mathbf{A} A 和 n n n维向量 x \mathbf{x} x 之间的乘积。首先,我们将矩阵表示为它的行向量:
A = ( a 1 T a 2 T ⋮ a m T ) \mathbf{A} = \begin{pmatrix} \mathbf{a}_1^T \\ \mathbf{a}_2^T \\ \vdots \\ \mathbf{a}_m^T \end{pmatrix} A= a1Ta2T⋮amT
其中,每个 a i T ∈ R n \mathbf{a}_i^T \in \mathbb{R}^n aiT∈Rn 是矩阵 A \mathbf{A} A的第 i i i行向量。
矩阵-向量乘积 A x \mathbf{A} \mathbf{x} Ax 只是长度为 m m m 的列向量,其中第 i i i个元素是行向量 a i \mathbf{a}_i ai与 x \mathbf{x} x的点积:
A x = ( a 1 T x a 2 T x ⋮ a m T x ) \mathbf{A} \mathbf{x} = \begin{pmatrix} \mathbf{a}_1^T \mathbf{x} \\ \mathbf{a}_2^T \mathbf{x} \\ \vdots \\ \mathbf{a}_m^T \mathbf{x} \end{pmatrix} Ax= a1Txa2Tx⋮amTx
我们可以将矩阵乘法视为一种将向量从 R n \mathbb{R}^n Rn 映射到 R m \mathbb{R}^m Rm的变换。这些变换非常有用。例如,我们可以表示旋转为特定方阵的乘积。矩阵-向量乘积还描述了计算神经网络每层输出时的关键计算过程。
在代码中,可以使用 mv 函数表示矩阵-向量乘积。注意,矩阵
A
\mathbf{A}
A 的列维数(即轴1的长度)必须与向量
x
\mathbf{x}
x 的维数相同。Python有一个方便的操作符 @,可以执行矩阵-向量和矩阵-矩阵乘积:
A = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
x = torch.tensor([1, 1, 1], dtype=torch.float32)
A.shape, x.shape, torch.mv(A, x), A @ x
输出结果为:
(torch.Size([2, 3]), torch.Size([3]), tensor([ 6., 15.]), tensor([ 6., 15.]))
2.3.10 矩阵-矩阵乘法
一旦你掌握了点积和矩阵-向量乘积,矩阵-矩阵乘法应该是直观的。
假设我们有两个矩阵 A ∈ R n × k \mathbf{A} \in \mathbb{R}^{n \times k} A∈Rn×k 和 B ∈ R k × m \mathbf{B} \in \mathbb{R}^{k \times m} B∈Rk×m:
A = ( a 11 a 12 ⋯ a 1 k a 21 a 22 ⋯ a 2 k ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n k ) , B = ( b 11 b 12 ⋯ b 1 m b 21 b 22 ⋯ b 2 m ⋮ ⋮ ⋱ ⋮ b k 1 b k 2 ⋯ b k m ) . \mathbf{A} = \begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1k} \\ a_{21} & a_{22} & \cdots & a_{2k} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n1} & a_{n2} & \cdots & a_{nk} \end{pmatrix}, \quad \mathbf{B} = \begin{pmatrix} b_{11} & b_{12} & \cdots & b_{1m} \\ b_{21} & b_{22} & \cdots & b_{2m} \\ \vdots & \vdots & \ddots & \vdots \\ b_{k1} & b_{k2} & \cdots & b_{km} \end{pmatrix}. A= a11a21⋮an1a12a22⋮an2⋯⋯⋱⋯a1ka2k⋮ank ,B= b11b21⋮bk1b12b22⋮bk2⋯⋯⋱⋯b1mb2m⋮bkm .
让 a i T ∈ R k \mathbf{a}_i^T \in \mathbb{R}^k aiT∈Rk 表示矩阵 A \mathbf{A} A 的第 i i i 行向量, b j ∈ R k \mathbf{b}_j \in \mathbb{R}^k bj∈Rk 表示矩阵 B \mathbf{B} B 的第 j j j 列向量。
A = ( a 1 T a 2 T ⋮ a n T ) , B = ( b 1 b 2 ⋯ b m ) . \mathbf{A} = \begin{pmatrix} \mathbf{a}_1^T \\ \mathbf{a}_2^T \\ \vdots \\ \mathbf{a}_n^T \end{pmatrix}, \quad \mathbf{B} = \begin{pmatrix} \mathbf{b}_1 & \mathbf{b}_2 & \cdots & \mathbf{b}_m \end{pmatrix}. A= a1Ta2T⋮anT ,B=(b1b2⋯bm).
为了得到矩阵积 C ∈ R n × m \mathbf{C} \in \mathbb{R}^{n \times m} C∈Rn×m,我们简单地将每个元素 c i j c_{ij} cij 计算为矩阵 A \mathbf{A} A 的第 i i i 行和矩阵 B \mathbf{B} B 的第 j j j 列的点积:
C = A B = ( a 1 T b 1 a 1 T b 2 ⋯ a 1 T b m a 2 T b 1 a 2 T b 2 ⋯ a 2 T b m ⋮ ⋮ ⋱ ⋮ a n T b 1 a n T b 2 ⋯ a n T b m ) . \mathbf{C} = \mathbf{A}\mathbf{B} = \begin{pmatrix} \mathbf{a}_1^T \mathbf{b}_1 & \mathbf{a}_1^T \mathbf{b}_2 & \cdots & \mathbf{a}_1^T \mathbf{b}_m \\ \mathbf{a}_2^T \mathbf{b}_1 & \mathbf{a}_2^T \mathbf{b}_2 & \cdots & \mathbf{a}_2^T \mathbf{b}_m \\ \vdots & \vdots & \ddots & \vdots \\ \mathbf{a}_n^T \mathbf{b}_1 & \mathbf{a}_n^T \mathbf{b}_2 & \cdots & \mathbf{a}_n^T \mathbf{b}_m \end{pmatrix}. C=AB= a1Tb1a2Tb1⋮anTb1a1Tb2a2Tb2⋮anTb2⋯⋯⋱⋯a1Tbma2Tbm⋮anTbm .
我们可以将矩阵-矩阵乘法视为执行 m m m 次矩阵-向量乘法或 m m m 次点积,并将结果拼接在一起,形成 n × m n \times m n×m 矩阵。在以下代码片段中,我们对矩阵 A \mathbf{A} A 和 B \mathbf{B} B 进行矩阵乘法。这里, A \mathbf{A} A 是一个有两行三列的矩阵, B \mathbf{B} B 是一个有三行四列的矩阵。乘法后,我们得到一个有两行四列的矩阵。
在PyTorch中,可以使用 mm 函数进行矩阵-矩阵乘法:
import torch
A = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
B = torch.ones(3, 4, dtype=torch.float32)
torch.mm(A, B), A @ B
输出结果为:
(tensor([[12., 12., 12., 12.],
[30., 30., 30., 30.]]),
tensor([[12., 12., 12., 12.],
[30., 30., 30., 30.]]))
矩阵-矩阵乘法常简化为矩阵乘法,不应与Hadamard积混淆。
范数
在线性代数中,一些最有用的操作符是范数。非正式地说,向量的范数告诉我们它有多大。例如, ℓ 2 \ell_2 ℓ2 范数测量向量的欧几里得长度。这里,我们使用“大小”这一概念,它关心的是向量分量的幅度,而不是它的维度。
范数是一个函数 ∥ ⋅ ∥ \| \cdot \| ∥⋅∥,它将向量映射到标量,并满足以下三个性质:
-
给定任意向量 x \mathbf{x} x,如果我们将其乘以标量 α ∈ R \alpha \in \mathbb{R} α∈R,则它的范数按相应比例缩放:
∥ α x ∥ = ∣ α ∣ ∥ x ∥ . \| \alpha \mathbf{x} \| = |\alpha| \|\mathbf{x}\|. ∥αx∥=∣α∣∥x∥. -
对任意向量 x \mathbf{x} x 和 y \mathbf{y} y,范数满足三角不等式:
∥ x + y ∥ ≤ ∥ x ∥ + ∥ y ∥ . \|\mathbf{x} + \mathbf{y}\| \leq \|\mathbf{x}\| + \|\mathbf{y}\|. ∥x+y∥≤∥x∥+∥y∥. -
向量的范数是非负的,且当且仅当向量为零时,范数为零:
∥ x ∥ > 0 for all x ≠ 0. \|\mathbf{x}\| > 0 \quad \text{for all} \quad \mathbf{x} \neq 0. ∥x∥>0for allx=0.
许多函数被称为范数,不同的范数编码了不同的大小概念。我们在小学几何中学到的欧几里得范数是直角三角形的斜边长度,即向量元素平方和的平方根。形式上,这被称为 ℓ 2 \ell_2 ℓ2 范数,表示为:
∥ x ∥ 2 = ∑ i = 1 n x i 2 . \|\mathbf{x}\|_2 = \sqrt{\sum_{i=1}^n x_i^2}. ∥x∥2=i=1∑nxi2.
在PyTorch中计算 ℓ 2 \ell_2 ℓ2 范数的方法如下:
import torch
u = torch.tensor([3.0, -4.0])
torch.norm(u)
输出结果为:
tensor(5.)
ℓ 1 \ell_1 ℓ1 范数也很常见,与之相关的度量称为曼哈顿距离。定义上, ℓ 1 \ell_1 ℓ1 范数是向量元素绝对值的总和:
∥ x ∥ 1 = ∑ i = 1 n ∣ x i ∣ . \|\mathbf{x}\|_1 = \sum_{i=1}^n |x_i|. ∥x∥1=i=1∑n∣xi∣.
相比于 ℓ 2 \ell_2 ℓ2 范数, ℓ 1 \ell_1 ℓ1 范数对异常值不太敏感。计算 ℓ 1 \ell_1 ℓ1 范数,我们可以将绝对值与求和操作结合:
torch.abs(u).sum()
输出结果为:
tensor(7.)
ℓ 2 \ell_2 ℓ2 和 ℓ 1 \ell_1 ℓ1 范数都是更一般的 ℓ p \ell_p ℓp 范数的特例:
∥ x ∥ p = ( ∑ i = 1 n ∣ x i ∣ p ) 1 / p . \|\mathbf{x}\|_p = \left( \sum_{i=1}^n |x_i|^p \right)^{1/p}. ∥x∥p=(i=1∑n∣xi∣p)1/p.
对于矩阵,情况更为复杂。矩阵既可以被视为单独条目的集合,也可以被视为操作向量并将其转换为其他向量的对象。例如,我们可以通过矩阵-向量乘积 X v \mathbf{Xv} Xv 来衡量矩阵拉长向量 v \mathbf{v} v 的程度。这种思路被称为谱范数。现在,我们介绍Frobenius范数,它更容易计算,定义为矩阵元素平方和的平方根:
∥ X ∥ F = ∑ i = 1 m ∑ j = 1 n x i j 2 . \|\mathbf{X}\|_F = \sqrt{\sum_{i=1}^m \sum_{j=1}^n x_{ij}^2}. ∥X∥F=i=1∑mj=1∑nxij2.
Frobenius范数的行为类似于矩阵形状向量的 ℓ 2 \ell_2 ℓ2 范数。调用以下函数将计算矩阵的Frobenius范数:
torch.norm(torch.ones((4, 9)))
输出结果为:
tensor(6.)
虽然我们不想走得太远,但我们已经可以对这些概念的用途有一些直觉。在深度学习中,我们经常尝试解决优化问题:最大化观察数据的概率;最大化推荐模型的收益;最小化预测与真实观察值之间的距离;最小化来自同一人的表示与最大化不同人表示之间的距离。这些目标经常以范数形式表达。
练习
1. 证明矩阵转置的转置就是矩阵本身: ( A ⊤ ) ⊤ = A (A^\top)^\top = A (A⊤)⊤=A
证明:
矩阵
A
A
A 的转置定义为
A
i
j
⊤
=
A
j
i
A^\top_{ij} = A_{ji}
Aij⊤=Aji。再次转置后,
(
A
⊤
)
i
j
⊤
=
(
A
⊤
)
j
i
=
A
i
j
(A^\top)^\top_{ij} = (A^\top)_{ji} = A_{ij}
(A⊤)ij⊤=(A⊤)ji=Aij,所以
(
A
⊤
)
⊤
=
A
(A^\top)^\top = A
(A⊤)⊤=A。
2. 给定两个矩阵 A A A 和 B B B,证明和与转置可交换: ( A + B ) ⊤ = A ⊤ + B ⊤ (A + B)^\top = A^\top + B^\top (A+B)⊤=A⊤+B⊤
证明:
(
A
+
B
)
i
j
⊤
=
(
A
+
B
)
j
i
=
A
j
i
+
B
j
i
=
A
i
j
⊤
+
B
i
j
⊤
(A + B)^\top_{ij} = (A + B)_{ji} = A_{ji} + B_{ji} = A^\top_{ij} + B^\top_{ij}
(A+B)ij⊤=(A+B)ji=Aji+Bji=Aij⊤+Bij⊤
所以
(
A
+
B
)
⊤
=
A
⊤
+
B
⊤
(A + B)^\top = A^\top + B^\top
(A+B)⊤=A⊤+B⊤。
3. 给定任意方阵 A A A,是否 A + A ⊤ A + A^\top A+A⊤ 总是对称的?
证明:
(
A
+
A
⊤
)
⊤
=
A
⊤
+
(
A
⊤
)
⊤
=
A
⊤
+
A
=
A
+
A
⊤
(A + A^\top)^\top = A^\top + (A^\top)^\top = A^\top + A = A + A^\top
(A+A⊤)⊤=A⊤+(A⊤)⊤=A⊤+A=A+A⊤
所以
A
+
A
⊤
A + A^\top
A+A⊤ 总是对称的。
4. 在本节中,我们定义了形状为 (2, 3, 4) 的张量。其输出是什么 l e n ( X ) len(X) len(X)?是否对应于某个轴的长度?
答:
len(X) 输出 2,对应于张量的第一个轴的长度。
5. 对于任意形状的张量,是否 len(X) 总是对应于某个轴的长度?
答:
是的,len(X) 总是对应于张量的第一个轴的长度。
6. 运行并查看会发生什么。你能分析结果吗?
A / A.sum(axis=1)
分析:
这将张量 A 的每一行除以该行元素的总和,使每行元素的总和为1。
7. 在曼哈顿中心的两点之间旅行时,你需要按照坐标(即大街和街道)覆盖多少距离?你可以对角线旅行吗?
答:
曼哈顿距离等于两个点的坐标差的绝对值之和。不能对角线旅行。
8. 考虑一个形状为 (2, 3, 4) 的张量。沿轴 0、1 和 2 的求和输出是什么形状?
答:
- 沿轴 0 求和:形状为 (3, 4)
- 沿轴 1 求和:形状为 (2, 4)
- 沿轴 2 求和:形状为 (2, 3)
9. 将具有一个或更多轴的张量输入到 linalg.norm 函数并观察其输出。该函数计算什么?
答:
linalg.norm 计算张量的范数。对于默认情况下,它计算的是 Frobenius 范数,即所有元素平方和的平方根。
10. 考虑三个大矩阵,比如 A ∈ R 1 0 2 × 1 0 6 A \in \mathbb{R}^{10^2 \times 10^6} A∈R102×106、(B \in \mathbb{R}{106 \times 10^2}$ 和 C ∈ R 1 0 2 × 1 0 6 C \in \mathbb{R}^{10^2 \times 10^6} C∈R102×106。用高斯随机变量初始化。你需要计算乘积 A B C ABC ABC。内存占用和速度是否有差异,取决于你是否计算 ( A B ) C (AB)C (AB)C 或 A ( B C ) A(BC) A(BC)?为什么?
答:
是的,有差异。因为矩阵乘法的计算复杂度是
O
(
n
3
)
O(n^3)
O(n3),计算
(
A
B
)
C
(AB)C
(AB)C 需要
1
0
8
×
1
0
2
+
1
0
2
×
1
0
6
=
1
0
10
+
1
0
8
10^8 \times 10^2 + 10^2 \times 10^6 = 10^{10} + 10^8
108×102+102×106=1010+108 次乘法,而计算
A
(
B
C
)
A(BC)
A(BC) 需要
1
0
2
×
1
0
6
+
1
0
2
×
1
0
8
=
1
0
8
+
1
0
10
10^2 \times 10^6 + 10^2 \times 10^8 = 10^8 + 10^{10}
102×106+102×108=108+1010 次乘法。
11. 考虑三个大矩阵,比如 A ∈ R 2 16 × 2 16 A \in \mathbb{R}^{2^{16} \times 2^{16}} A∈R216×216、(B \in \mathbb{R}{2{16} \times 2^{16}}$ 和 C ∈ R 2 16 × 2 16 C \in \mathbb{R}^{2^{16} \times 2^{16}} C∈R216×216。计算度量是否有差异 A ( B C ) A(BC) A(BC) 或 A B ( C ⊤ ) AB(C^\top) AB(C⊤)?为什么?如果初始化 C = B ⊤ \mathbf{C} = \mathbf{B}^\top C=B⊤ 无需考虑?
答:
计算度量不会有差异,因为矩阵的乘法是结合律的,不管先计算哪个乘法,结果都是一样的。
12. 考虑三个小矩阵,比如 A , B , C ∈ R 100 × 200 A, B, C \in \mathbb{R}^{100 \times 200} A,B,C∈R100×200。通过堆叠构建具有三个轴的张量 [ A , B , C ] [A, B, C] [A,B,C]。维数是多少?切出第三轴的第二个坐标即回复 B B B。
答:
堆叠后的张量维数为 (3, 100, 200)。切出第三轴的第二个坐标,得到的结果是矩阵
B
B
B,形状为 (100, 200)。

6万+

被折叠的 条评论
为什么被折叠?



