跟着GPT学习——神经网络前备知识:线性代数

我觉得GPT老师的语言功底比大多数的博客主要好(包括我自己),阅读起来更易理解,而且哪里不明白还可以直接问gpt老师,孜孜不倦,尽心尽责,全天待命,究极贴心。有这么厉害的一个老师,不学习简直暴殄天物。

于是乎我准备立一个flag,挑战跟着GPT老师学习365天,每天我都会整理自己的学习心得和脉络(文字大部分都是GPT直接生成的,我觉得比我自己写肯定好多了)感谢gpt老师!跪谢

全系列文章:跟着GPT学习-AI系列

本文翻译自文章:线性代数

线性代数

标量

大多数日常数值计算都是一次处理一个数值。我们称这些数值为标量。例如,帕洛阿尔托的温度是温和的72华氏度。为了将温度转换为摄氏度,你可以使用公式:
c = 5 9 ( f − 32 ) c = \frac{5}{9}(f - 32) c=95(f32)
其中 ( f ) 是温度,值5,9,32等是常数标量 是常数标量。变量 ( c ) 和 ( f ) 一般表示未知标量。

在数学中,标量用小写字母表示(例如 x x x y y y z z z),它们可以是实数范围内的任意值。为了方便,我们将省略对空间的严格定义,只需记住表达式 x ∈ R x \in \mathbb{R} xR 代表 ( 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} ARm×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= a11a21am1a12a22am2a1na2namn

创建矩阵

我们可以使用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= a11a12a1na21a22a2nam1am2amn

在代码中,我们可以使用.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,BRm×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} AB= a11b11a21b21am1bm1a12b12a22b22am2bm2a1nb1na2nb2namnbmn

在代码中,我们可以使用*操作符来计算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=1mj=1naij

使用以下代码计算矩阵 ( 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,yRd,它们的点积 x ⋅ y \mathbf{x} \cdot \mathbf{y} xy(也称为内积 ⟨ 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 xy=i=1dxiyi

在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 xRn和一组权重 w ∈ R n \mathbf{w} \in \mathbb{R}^n wRn,根据权重对值进行加权求和可以表示为点积 w ⋅ x \mathbf{w} \cdot \mathbf{x} wx。当权重非负并且总和为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= a1Ta2TamT

其中,每个 a i T ∈ R n \mathbf{a}_i^T \in \mathbb{R}^n aiTRn 是矩阵 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= a1Txa2TxamTx

我们可以将矩阵乘法视为一种将向量从 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} ARn×k B ∈ R k × m \mathbf{B} \in \mathbb{R}^{k \times m} BRk×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= a11a21an1a12a22an2a1ka2kank ,B= b11b21bk1b12b22bk2b1mb2mbkm .

a i T ∈ R k \mathbf{a}_i^T \in \mathbb{R}^k aiTRk 表示矩阵 A \mathbf{A} A 的第 i i i 行向量, b j ∈ R k \mathbf{b}_j \in \mathbb{R}^k bjRk 表示矩阵 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= a1Ta2TanT ,B=(b1b2bm).

为了得到矩阵积 C ∈ R n × m \mathbf{C} \in \mathbb{R}^{n \times m} CRn×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= a1Tb1a2Tb1anTb1a1Tb2a2Tb2anTb2a1Tbma2TbmanTbm .

我们可以将矩阵-矩阵乘法视为执行 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 \| ,它将向量映射到标量,并满足以下三个性质:

  1. 给定任意向量 x \mathbf{x} x,如果我们将其乘以标量 α ∈ R \alpha \in \mathbb{R} αR,则它的范数按相应比例缩放:
    ∥ α x ∥ = ∣ α ∣ ∥ x ∥ . \| \alpha \mathbf{x} \| = |\alpha| \|\mathbf{x}\|. αx=α∣∥x∥.

  2. 对任意向量 x \mathbf{x} x y \mathbf{y} y,范数满足三角不等式:
    ∥ x + y ∥ ≤ ∥ x ∥ + ∥ y ∥ . \|\mathbf{x} + \mathbf{y}\| \leq \|\mathbf{x}\| + \|\mathbf{y}\|. x+yx+y∥.

  3. 向量的范数是非负的,且当且仅当向量为零时,范数为零:
    ∥ 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}. x2=i=1nxi2 .

在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|. x1=i=1nxi∣.

相比于 ℓ 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}. xp=(i=1nxip)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}. XF=i=1mj=1nxij2 .

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} AR102×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} CR102×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}} AR216×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}} CR216×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,CR100×200。通过堆叠构建具有三个轴的张量 [ A , B , C ] [A, B, C] [A,B,C]。维数是多少?切出第三轴的第二个坐标即回复 B B B

答:
堆叠后的张量维数为 (3, 100, 200)。切出第三轴的第二个坐标,得到的结果是矩阵 B B B,形状为 (100, 200)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值