动手学深度学习-预备知识3-线性代数

272 阅读14分钟

线性代数是深度学习的核心基础,理解其基本概念和运算对于掌握神经网络至关重要。本文将详细介绍线性代数中的关键内容,并结合PyTorch框架进行示例。

一、标量

想象一下你在餐厅支付账单时,你可能已经在无形中运用了线性代数的基本知识,比如加法和乘法。比如,北京的温度以华氏度表示为52°F,这个数字本身就是一个标量。如果你想把华氏度转换为更常见的摄氏度,你可以使用一个简单的数学公式:c=59(f32)c = \frac{5}{9}(f - 32)

在这个公式中,所有的数值,比如华氏度和摄氏度,都是标量。符号通常用小写字母(如 xy)表示,代表这些未知的数值。我们用一个符号空间来表示所有可能的实数标量,比如 R。而符号“属于”表示某个数在这个集合中,比如 x∈ R 意味着 x 是一个实数。

在数学中,标量可以用只有一个元素的张量来表示。下面的代码展示了如何在PyTorch中创建两个标量,并进行加法、乘法、除法和指数运算:

import torch

x = torch.tensor(3.0)  # 创建标量3.0
y = torch.tensor(2.0)  # 创建标量2.0

# 执行算术运算
result_add = x + y  # 加法
result_mul = x * y  # 乘法
result_div = x / y  # 除法
result_pow = x ** y  # 指数

print(result_add, result_mul, result_div, result_pow)

"""
tensor(5.) tensor(6.) tensor(1.5000) tensor(9.)
"""

运行这段代码,得到的结果分别是:5.0(加法),6.0(乘法),1.5(除法),和9.0(指数)。这些基本运算为理解更复杂的线性代数概念奠定了基础。

二、向量

向量可以看作是由标量值组成的列表,这些值称为元素分量。在实际应用中,当向量表示数据集中的样本时,每个分量都具有重要意义。例如,如果我们在训练一个贷款违约风险预测模型,每个申请人可以用一个向量表示,其中的分量可能包括收入、工作年限、过往违约次数等。如果我们研究患者的心脏病发作风险,则可能用一个向量表示每个患者,分量包括最新的生命体征、胆固醇水平、每日运动时间等。

在数学中,向量通常用粗体小写字母(如 vxy)表示。向量可以用一维张量表示,其长度可以根据机器的内存限制变化。下面的代码示例展示了如何在PyTorch中创建一个向量:

import torch

x = torch.arange(4)  # 创建一个包含0到3的向量
print(x)  # 输出: tensor([0, 1, 2, 3])

我们可以通过下标访问向量的任一元素,例如 x[2] 引用第三个元素。值得注意的是,引用的元素是一个标量,因此不需要加粗。文献中通常将列向量视为默认形式。在数学上,向量可以表示为:

v=[v1v2vn]\mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix}

其中 viv_i 是向量的元素。我们可以通过张量的索引来访问这些元素:

element = x[3]
print(element)  # 输出:tensor(3)

长度、维度和形状

向量是数字的数组,每个数组都有一个长度,向量同样如此。如果我们想表示一个包含 𝑛 个实值标量的向量,可以写作 v 𝑅n∈𝑅^n 。向量的长度也被称为维度。 在Python中,我们可以使用内置的 len() 函数来获取向量的长度:

length = len(x)  # 获取向量长度
print(length)  # 输出: 4

当用张量表示一个向量(即只有一个轴时),我们也可以通过 .shape 属性访问长度。形状(shape)是一个包含元素数量的元组,对于一维张量,形状只有一个元素:

shape = x.shape
print(shape)  # 输出: torch.Size([4])

需要注意的是,“维度”这个词在不同上下文中可能会产生混淆。这里我们明确:向量的维度指的是向量的长度,即元素的数量。而张量的维度则指的是张量的轴数。在这种意义上,某个轴的维度表示这个轴的长度。

三、矩阵

矩阵可以看作是将向量从一阶推广到二阶的结构。我们通常用粗体大写字母表示矩阵(例如 ABC)。在代码中,矩阵被表示为具有两个轴的张量

在数学表示中,一个矩阵 𝐴 表示为一个 𝑚 × 𝑛 的实值标量的集合,其中 𝑚 是行数,𝑛 是列数。矩阵的元素 𝑎𝑖𝑗𝑎_{𝑖𝑗} 位于第 𝑖 行第 𝑗 列:

A=[a11a12a1na21a22a2nam1am2amn]\mathbf{A} = \begin{bmatrix} a_{11} & a_{12} & \dots & a_{1n} \\ a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \dots & a_{mn} \end{bmatrix}

对于任意矩阵 𝐴,它的形状为 (𝑚, 𝑛)。当矩阵的行数与列数相等时,称其为方阵。通过指定矩阵的行数和列数,我们可以用代码来创建矩阵。例如,在PyTorch中:

# 创建一个5行4列的矩阵
A = torch.arange(20).reshape(5, 4)
print(A)
"""
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]])
"""

我们可以通过行索引和列索引来访问矩阵的元素,例如 A[1, 2] 访问的是矩阵第二行第三列的元素。注意,矩阵中的元素是标量,所以在引用时不需要加粗。若不特别标注,矩阵通常以行优先方式表示。

element = A[1, 2]
print(element)  # 输出:tensor(6)

矩阵的转置

当我们交换矩阵的行和列时,得到的结果称为矩阵的转置,用 A\mathbf{A}^⊤ 表示。例如,对于上面的矩阵 𝐴,其转置可以在代码中计算:

print(A.T)
"""
tensor([[ 0,  4,  8, 12, 16],
        [ 1,  5,  9, 13, 17],
        [ 2,  6, 10, 14, 18],
        [ 3,  7, 11, 15, 19]])
"""

对称矩阵

一个特殊类型的矩阵是对称矩阵,它等于其转置,即 𝐵=𝐵\mathbf{𝐵} = \mathbf{𝐵}^⊤。例如:


import torch

B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
print(B)
"""
tensor([[1, 2, 3],
        [2, 0, 4],
        [3, 4, 5]])
"""
print(B.T)
"""
tensor([[1, 2, 3],
        [2, 0, 4],
        [3, 4, 5]])
"""
print(B == B.T)
"""
tensor([[True, True, True],
        [True, True, True],
        [True, True, True]])
"""

矩阵在实际中的应用

矩阵是非常有用的数据结构,可以用来组织不同模式的数据。例如,矩阵的行可以表示不同的房屋(数据样本),而可以表示这些房屋的属性。如果你曾经使用过电子表格软件,那么对这种结构应该比较熟悉。

四、张量:多维数据的扩展

就像向量是标量的推广,矩阵是向量的推广一样,张量是我们处理多维数据的更广泛工具。张量可以有任意数量的轴,因此,它被视为一种多维数组的通用表示方法。

  • 向量 是一阶张量,表示一组数排成的列表。
  • 矩阵 是二阶张量,表示二维数据表格。
  • 高阶张量超过两轴的数据结构。

我们用特殊的大写字母表示张量(例如 𝑋, 𝑌, 𝑍)。与矩阵类似,张量中的元素可以通过多个索引(例如 𝑥𝑖𝑗𝑘𝑥_{𝑖𝑗𝑘})来引用。

张量在图像处理中的应用:当处理图像时,张量尤为重要。图像通常以 三维数组 形式表示,其中:

  • 高度(图片的垂直尺寸)
  • 宽度(图片的水平尺寸)
  • 通道(颜色通道:红、绿、蓝)

例如,一张彩色图像可以表示为一个三维张量,每个通道对应于不同的颜色强度值。

创建和查看张量

让我们在 PyTorch 中创建一个简单的三维张量,形状为 2 × 3 × 4(2个“表”,每个“表”包含3行4列的数值):

import torch

# 创建一个形状为 (2, 3, 4) 的张量
X = torch.arange(24).reshape(2, 3, 4)

print(X)
"""
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]]])
"""

张量的结构

  • 第一维表示 2 个二维矩阵(或图像)。
  • 第二维是矩阵的 3 行。
  • 第三维是每行的 4 个元素。

这样,我们就构建了一个三维的张量,可以轻松处理各种维度的复杂数据。未来在图像、视频处理等任务中,张量将成为非常重要的工具。

五、张量算法的基本性质

无论是标量、向量、矩阵还是任意维度的张量,它们都有一些 按元素操作 的特性。换句话说,当我们在张量上执行按元素的运算时,操作不会改变张量的形状,输出张量的形状与输入张量的形状一致。

一元运算

例如,对于一元操作(如对张量的每个元素进行加、减或取反操作),结果的形状与输入相同。

# 取反(Negation)
x = torch.tensor([1.0, -2.0, 3.0])
negated_x = -x
print(negated_x)  # 输出:tensor([-1.,  2., -3.])

# 指数(Exponential)
x = torch.tensor([0.0, 1.0, 2.0])
exp_x = torch.exp(x)
print(exp_x)  # 输出:tensor([1.0000, 2.7183, 7.3891])

# 取绝对值(Absolute Value)
x = torch.tensor([-1.0, -2.0, 3.0])
abs_x = torch.abs(x)
print(abs_x)  # 输出:tensor([1., 2., 3.])

二元运算

同样,任何两个形状相同的张量,在进行按元素的二元运算时,结果仍然会是一个相同形状的张量。一个常见的例子是矩阵的元素相加运算:

# 创建一个5x4的矩阵A,并克隆A到B
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()  # 复制A到B
print(A)
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
"""
print(A + B)  # 矩阵A和B相加
"""
tensor([[ 0.,  2.,  4.,  6.],
        [ 8., 10., 12., 14.],
        [16., 18., 20., 22.],
        [24., 26., 28., 30.],
        [32., 34., 36., 38.]])
"""

Hadamard积

当我们对两个矩阵按元素相乘时,得到的运算称为 Hadamard积,记作 𝐴 ∘ 𝐵:

Cij=Aij×BijC_{ij} = A_{ij} × B_{ij}

对于矩阵 𝐴 和 𝐵,它们的 Hadamard 积计算如下:


print(A * B)
"""
tensor([[  0.,   1.,   4.,   9.],
        [ 16.,  25.,  36.,  49.],
        [ 64.,  81., 100., 121.],
        [144., 169., 196., 225.],
        [256., 289., 324., 361.]])
"""

张量与标量的运算

将张量乘以或加上一个标量不会改变张量的形状,标量运算会应用到张量的每个元素上:

import torch

a = 2
X = torch.arange(24).reshape(2, 3, 4)
print(X)
"""
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]]])
"""
# 标量加操作
print(a + X)
"""
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]]])
"""
# 标量乘操作
print(a * X)
"""
tensor([[[ 0,  2,  4,  6],
         [ 8, 10, 12, 14],
         [16, 18, 20, 22]],

        [[24, 26, 28, 30],
         [32, 34, 36, 38],
         [40, 42, 44, 46]]])
"""
print((a * X).shape)  # 输出:torch.Size([2, 3, 4])

六、降维

我们可以对任意张量进行的一个有用操作是计算其元素的和。数学表示法使用 Σ 符号表示求和。为了表示长度为 𝑛 的向量中元素的总和,可以记为:

i=1nxi\sum_{i=1}^{n} x_i
import torch

x = torch.arange(4, dtype=torch.float32)
print(x)  # tensor([0., 1., 2., 3.])
print(x.sum())  # tensor(6.)

我们可以表示任意形状张量的元素和。例如,矩阵 𝐴 中元素的和可以记为:

i=1mj=1nAij\sum_{i=1}^m\sum_{j=1}^nA_{ij}
A = torch.arange(20).reshape(5, 4)
print(A)
"""
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]])
"""
print(A.shape)  # torch.Size([5, 4])
print(A.sum())  # tensor(190)

默认情况下,调用求和函数沿所有轴降低张量的维度,使其变为一个标量。我们还可以指定张量沿哪一个轴来通过求和降低维度。以矩阵为例,为了通过求和所有行的元素来降维(轴0),可以在调用函数时指定 axis=0dim=0

A_sum_axis0 = A.sum(dim=0)
print(A_sum_axis0, A_sum_axis0.shape)
# tensor([40, 45, 50, 55]) torch.Size([4])

指定 axis=1 将通过汇总所有列的元素降维(轴1)。

A_sum_axis1 = A.sum(dim=1)
print(A_sum_axis1, A_sum_axis1.shape)
# tensor([ 6, 22, 38, 54, 70]) torch.Size([5])

沿着行和列对矩阵求和,等价于对矩阵的所有元素进行求和:

print(A.sum(dim=[0, 1]))  # tensor(190),结果和A.sum()相同

一个与求和相关的量是平均值(mean或average)。我们通过将总和除以元素总数来计算平均值:

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)

print(A)
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
"""

print(A.mean())  # tensor(9.5000)
print(A.sum() / A.numel())  # tensor(9.5000)

同样,计算平均值的函数也可以沿指定轴降低张量的维度:

print(A.mean(dim=0))  # tensor([ 8.,  9., 10., 11.])
print(A.sum(dim=0) / A.shape[0])  # tensor([ 8.,  9., 10., 11.])

非降维求和

有时,在调用函数来计算总和或均值时,保持轴数不变会很有用:

"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
"""
sum_A = A.sum(dim=1, keepdim=True)
print(sum_A)
"""
tensor([[ 6.],
        [22.],
        [38.],
        [54.],
        [70.]])
"""
print(sum_A.shape)  # torch.Size([5, 1])

由于 sum_A 在对每行进行求和后仍保持两个轴,我们可以通过广播将 𝐴 除以 sum_A:

print(A / sum_A)
"""
tensor([[0.0000, 0.1667, 0.3333, 0.5000],
        [0.1818, 0.2273, 0.2727, 0.3182],
        [0.2105, 0.2368, 0.2632, 0.2895],
        [0.2222, 0.2407, 0.2593, 0.2778],
        [0.2286, 0.2429, 0.2571, 0.2714]])
"""

如果我们想沿某个轴计算 𝐴 元素的累积总和,比如 axis=0(按行计算),可以调用 cumsum 函数:

"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
"""
print(A.cumsum(dim=0))
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  6.,  8., 10.],
        [12., 15., 18., 21.],
        [24., 28., 32., 36.],
        [40., 45., 50., 55.]])
"""

七、点积

我们已经学习了按元素操作、求和及平均值。另一个最基本的操作之一是点积。给定两个向量 𝑥, 𝑦,它们的点积(dot product)𝑥T𝑦\mathbf{𝑥}^T\mathbf{𝑦}(或 ⟨𝑥,𝑦⟩)是相同位置的按元素乘积的和:

xy=i=1nxiyjx·y = \sum_{i=1}^nx_iy_j
import torch

x = torch.arange(4, dtype=torch.float32)
print(x)  # tensor([0., 1., 2., 3.])
y = torch.ones(4, dtype=torch.float32)
print(y)  # tensor([1., 1., 1., 1.])
print(torch.dot(x, y))  # tensor(6.)

注意,我们可以通过执行按元素乘法,然后进行求和来表示两个向量的点积:

print(x * y)  # tensor([0., 1., 2., 3.])
print(torch.sum(x * y))  # tensor(6.)

点积在很多场合都很有用。 例如,给定一组由向量 𝑥 表示的值,和一组由 𝑤 表示的权重,𝑥 中的值根据权重 𝑤 的加权和,可以表示为点积 𝑥⋅𝑤。当权重为非负数且和为1(即 𝑤𝑖=1d=1\sum𝑤_{𝑖=1}^d = 1)时,点积表示加权平均(weighted average)。将两个向量规范化得到单位长度后,点积表示它们夹角的余弦。本节后面的内容将正式介绍长度(length)的概念。

八、矩阵-向量积

现在我们知道如何计算点积,可以开始理解矩阵-向量积(matrix-vector product)。 前面定义的矩阵 𝐴 和向量 𝑥。 让我们将矩阵 𝐴 用它的行向量表示:

A=[a1Ta2TamT],\mathbf{A} = \begin{bmatrix} \mathbf{a}_1^T \\ \mathbf{a}_2^T \\ \vdots \\ \mathbf{a}_m^T \end{bmatrix},

其中每个 aiT\mathbf{a}_i^T 都是行向量,表示矩阵的第 𝑖 行。矩阵向量积 Ax 是一个长度为 𝑚 的列向量,其第 𝑖 个元素是点积 aiTx\mathbf{a}_i^T\mathbf{x}

A=[a1Txa2TxamTx],\mathbf{A} = \begin{bmatrix} \mathbf{a}_1^T\mathbf{x} \\ \mathbf{a}_2^T\mathbf{x} \\ \vdots \\ \mathbf{a}_m^T\mathbf{x} \end{bmatrix},

我们可以把一个矩阵乘法看作一个从 RnR_n𝑅𝑚𝑅_𝑚向量的转换。这些转换是非常有用的,例如可以用方阵的乘法来表示旋转。后续将讲到,我们也可以使用矩阵-向量积来描述在给定前一层的值时,求解神经网络每一层所需的复杂计算。

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
print(A, A.shape)
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]]) torch.Size([5, 4])
"""
x = torch.arange(4, dtype=torch.float32)
print(x, x.shape)  # tensor([0., 1., 2., 3.]) torch.Size([4])

print(torch.mv(A, x))
# tensor([ 14.,  38.,  62.,  86., 110.])

九、矩阵乘法

在掌握点积矩阵-向量积的知识后,矩阵-矩阵乘法(matrix-matrix multiplication)应该很简单。假设有两个矩阵A\mathbf{A}B\mathbf{B}

A=(a11a12a13a14a21a22a23a24a31a32a33a34a41a42a43a44a51a52a53a54),  B=(b11b12b13b21b22b23b31b32b33b41b42b43)\mathbf{A} = \begin{pmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \\ a_{51} & a_{52} & a_{53} & a_{54} \end{pmatrix},\;\mathbf{B} = \begin{pmatrix} b_{11} & b_{12} & b_{13} \\ b_{21} & b_{22} & b_{23} \\ b_{31} & b_{32} & b_{33} \\ b_{41} & b_{42} & b_{43} \end{pmatrix}

用行向量 ai\mathbf{a}_i 表示矩阵 A\mathbf{A} 的第 ii 行,并让列向量 bj\mathbf{b}_j 作为矩阵 B\mathbf{B} 的第 jj 列。要生成矩阵积 C\mathbf{C},最简单的方法是考虑 A\mathbf{A} 的行向量和 B\mathbf{B} 的列向量:

C=AB\mathbf{C} = \mathbf{A}⋅\mathbf{B}

当我们简单地将每个元素 cijc_{ij} 计算为点积 cij=aibjc_{ij} = \mathbf{a}_i \cdot \mathbf{b}_j:

cij=kaikbkjc_{ij} = \sum_ka_{ik}b_{kj}

我们可以将矩阵-矩阵乘法 C\mathbf{C} 看作简单地执行 mm 次矩阵-向量积,并将结果拼接在一起,形成一个 m×nm \times n 矩阵。 在下面的代码中,我们在A和B上执行矩阵乘法。 这里的A是一个5行4列的矩阵,B是一个4行3列的矩阵。 两者相乘后,我们得到了一个5行3列的矩阵。

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
print(A)
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
"""
B = torch.ones(4, 3)
print(B)
"""
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
"""
print(torch.mm(A, B))
"""
tensor([[ 6.,  6.,  6.],
        [22., 22., 22.],
        [38., 38., 38.],
        [54., 54., 54.],
        [70., 70., 70.]])
"""

矩阵-矩阵乘法可以简单地称为矩阵乘法,不应与 “ Hadamard积 ” 混淆。

十、范数

我们已经介绍了线性代数中一些基本的运算,如按元素操作、点积、矩阵乘法等。接下来要介绍的是范数 (norm)——向量和矩阵的大小度量。

在线性代数中,向量的范数将向量映射到标量的函数。给定任意向量 uRn\mathbf{u} \in \mathbb{R}^n,其范数需要满足以下性质:

  1. 比例性 (Scaling): 如果我们将向量 u\mathbf{u} 按常数因子 α\alpha 缩放,其范数按 α\alpha 的绝对值缩放:

    αu=αu\|\alpha \mathbf{u}\| = |\alpha| \|\mathbf{u}\|
  2. 三角不等式 (Triangle inequality): 对于任意向量 u\mathbf{u}v\mathbf{v},有

    u+vu+v\|\mathbf{u} + \mathbf{v}\| \leq \|\mathbf{u}\| + \|\mathbf{v}\|
  3. 非负性 (Non-negativity): 向量范数 u0\|\mathbf{u}\| \geq 0,且当且仅当 u=0\mathbf{u} = \mathbf{0} 时, u=0\|\mathbf{u}\| = 0

  4. 正齐次性 (Homogeneity): 对于任何实数 α\alpha 和向量 u\mathbf{u},有

    αu=αu\|\alpha \mathbf{u}\| = |\alpha| \|\mathbf{u}\|

最常见的范数之一是 L2L_2 范数,也称为欧几里得范数 (Euclidean norm),定义为向量元素平方和的平方根:

u2=i=1nui2\|\mathbf{u}\|_2 = \sqrt{\sum_{i=1}^n u_i^2}

在代码中,我们可以按如下方式计算向量的 L2L_2 范数:

u = torch.tensor([3.0, -4.0])
print(torch.norm(u))  # tensor(5.)

除了 L2L_2 范数,L1L_1 范数表示向量元素绝对值之和

u1=i=1nui\|\mathbf{u}\|_1 = \sum_{i=1}^n |u_i|

在代码中,我们可以使用如下代码计算 L1L_1 范数:

u = torch.tensor([3.0, -4.0])
print(torch.abs(u).sum())  # tensor(7.)

LpL_p 范数 是 L1L_1L2L_2 范数的推广形式:

up=(i=1nuip)1p\|\mathbf{u}\|_p = \left( \sum_{i=1}^n |u_i|^p \right)^{\frac{1}{p}}

此外,矩阵的 Frobenius 范数 定义为矩阵元素平方和的平方根,类似于向量的 L2L_2 范数:

AF=i=1mj=1naij2\|\mathbf{A}\|_F = \sqrt{\sum_{i=1}^m \sum_{j=1}^n |a_{ij}|^2}
A = torch.ones([4, 9])
print(torch.norm(A))  # tensor(6.)