动手学习深度学习——2.3 线性代数

2.3 线性代数

  既然您可以存储和操作数据,那么让我们简要回顾一下基本线性代数的子集,这将有助于理解并实现本书中介绍的大多数模型。下面,我们介绍线性代数中的基本数学对象、算术和运算,通过数学符号和相应的代码实现来表示它们。

2.3.1. 标量(Scalars)

  如果你从未学习过线性代数或机器学习,那么你过去的数学经验可能就是一次只考虑一个数字。而且,如果你曾经处理过支票簿,或者在餐馆付过饭钱,那么你已经知道如何做基本的事情,比如对数字进行加法和乘法。例如,帕洛阿尔托的温度是52华氏度。形式上,我们称仅由一个数值标量组成的值为标量。如果您想将这个值转换为摄氏温度(公制系统的更合理的温度刻度),您将计算表达式 c = 5 9 ( f − 32 ) c=\frac{5}{9}(f-32) c=95(f32),将 f f f 设置为52。在这个方程中,每一项,5,9,32,都是标量值。占位符 c c c f f f 被称为变量,它们表示未知的标量值。

在本书中,我们采用数学中的概念,具体表述如下:

标量:用小写字母表示,比如 x,y,z.
实值空间: R R R
x , y ∈ { 0 , 1 } x,y\in \lbrace{0,1}\rbrace x,y{0,1}:x,y 的取值只能为 0 或者 1.

在张量中,一个标量用一个元素表达。下面的代码片段介绍张量的基本运算(2.1介绍过):

import torch

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

# x + y, x * y, x / y, x**y
print('addition: ', x+y)
print('multiplication: ', x*y)
print('division: ', x/y)
print('exponentiation: ', x**y)

# 输出如下:
addition:  tensor(5.)
multiplication:  tensor(6.)
division:  tensor(1.5000)
exponentiation:  tensor(9.)

2.3.2. 向量(Vectors)

  可以将向量简单认为是标量值列表,称这些标量值为向量的元素。如果向量表示数据集中的一个样本,那么这些值就具有现实意义。比如,我们训练一个模型预测贷款违约的风险,那么每一个申请人的向量表示应该包括:收入,合同年限,违约记录,以及其它因素。如果我们研究医院病人面临心脏病的风险,那么向量包括:生命体征,胆固醇水平,每天运动量等。在数学概念中,我们通常用实体小写字母表示向量(比如,x,y,z)。

一维向量举例,通常向量的长度可以为任意值(受限于电脑内存的大小):

x = torch.arange(4)
print(x)

# 输出如下:
tensor([0, 1, 2, 3])

可以使用下标的方式指示向量的元素。比如,标量 x i x_i xi 表示向量 x 的第 i 个元素。大量的文献认为列向量是向量的默认方向,本书也是如此。数学中,向量 x 的形式如下:
x = [ x 1 x 2 ⋮ x n ] x=\left[ \begin{matrix} x_1\\ x_2\\ \vdots\\ x_n \end{matrix} \right] x=x1x2xn
这里, x 1 , x 2 , ⋯   , x n x_1,x_2,\cdots,x_n x1,x2,,xn 表示向量的每一个元素。

注意:关于向量的介绍,可以参考该系列教程之【2.1 数据操作】,详细介绍了向量(这里主要指张量)的属性,以及各种操作等。

2.3.3. 矩阵

  正如向量是将标量从0维推广到一维一样,矩阵正是将向量从1维推广到二维。通常,用大写,粗体字母(比如,X,Y,Z)表示矩阵。

数学中, A ∈ R m × n A\in R^{m\times n} ARm×n 表示矩阵 A 具有m行,n列的实数标量。视觉上,可以将矩阵 A 看成一个表, a i j a_{ij} aij 表示矩阵的第 i 行,第 j 列的元素。矩阵的一般形式如下所示:
A = [ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ] (2.3.2) A=\left[ \begin{matrix} 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{matrix} \right] \tag{2.3.2} A=a11a21am1a12a22am2a1na2namn(2.3.2)

对于任何矩阵 A ∈ R m × n A\in R^{m\times n} ARm×n,矩阵的形状(shape)为(m,n)或者 m × n m\times n m×n. 那么,当一个矩阵的行与列相等时,矩阵就称为方阵。

我们可以通过调用函数创建矩阵,需要指定矩阵的形状的每个分量值,即 m,n 的值,具体实例如下:

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]])

矩阵元素的书写形式

参考【2.3.2】中索引向量的元素,矩阵元素的形式如下:

  1. [ A ] i j [A]_{ij} [A]ij 或者 a i j a_{ij} aij:表示矩阵 A 的第 i 行,j 列的元素;

矩阵的转置

定义:将矩阵的行与列交换。
形式:A 的转置矩阵书写形式为 A T A^T AT.
性质:令 B = A T B=A^T B=AT,那么对于任何 ( i , j ) (i,j) (i,j) b i j = a j i b_{ij}=a_{ji} bij=aji,那么A的转置矩阵形状为 n × m n\times m n×m
A = [ a 11 a 21 ⋯ a m 1 a 12 a 22 ⋯ a m 2 ⋮ ⋮ ⋱ ⋮ a 1 n a 2 n ⋯ a m n ] (2.3.3) A=\left[ \begin{matrix} 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{matrix} \right] \tag{2.3.3} A=a11a12a1na21a22a2nam1am2amn(2.3.3)
代码如下:

print(A.T)

#输出如下
tensor([[ 0,  4,  8, 12, 16],
        [ 1,  5,  9, 13, 17],
        [ 2,  6, 10, 14, 18],
        [ 3,  7, 11, 15, 19]])

对称矩阵

性质:(1)对称矩阵必须为方阵;(2)对称矩阵与其转置相等,即 A = A T A=A^T A=AT
定义对称矩阵 B,代码如下:

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==B.T)

# 输出如下:
tensor([[True, True, True],
        [True, True, True],
        [True, True, True]])

矩阵小结:矩阵是非常有用的数据结构,它使我们能够组织具有不同变化形式的数据。比如,矩阵中的行(row)与不同的房子有关(一个数据样本),列(columns)与样本不同的特性相关。如果使用过电子表格软件或者看过本博客的系列教程【2.2 数据预处理】,那么会对这个非常熟悉。这样,尽管单个向量的默认方向是列,但是矩阵代表一个表格,更传统的做法是将每个数据实例视为矩阵中的行向量。在后面的章节中,我们将会看到这在深度学习实践中非常普遍。比如,沿着张量的最外层的轴,我们可以获得数据最小的批次(minibatches),如果没有最小批次,那么仅仅获得数据样本。

2.3.4. 张量

  正如标量推广得到向量,向量推广得到矩阵,我们可以创建具有更多轴的数据结构。通过张量,我们可以使用任意数量的轴来描述 n 维数组。向量是一阶张量,矩阵是二阶张量。张量使用特殊的字体的大写字母表示(比如,X,Y,Z),索引机制与矩阵类似。

当处理图像数据(具有3个轴,表示高,宽,通道数量)时,张量会变得更加重要。代码如下:

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.5. 张量算术运算的基本性质

  标量、向量、矩阵和具有任意数量轴的张量(本小节中的“张量”指代数对象)都有一些很好的性质,这些性质被普遍使用。例如,您可能已经从元素操作的定义中注意到,任何元素的一元操作都不会改变其操作对象的形状。同样,给定任意两个具有相同形状的张量,任意二元元素运算的结果都是相同形状的张量。例如,添加两个相同形状的矩阵可以对这两个矩阵进行元素相加。

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()  # Assign a copy of `A` to `B` by allocating new memory
print(A)
print(A+B)

# 输出如下:
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
tensor([[ 0.,  2.,  4.,  6.],
        [ 8., 10., 12., 14.],
        [16., 18., 20., 22.],
        [24., 26., 28., 30.],
        [32., 34., 36., 38.]])

特别地,矩阵对应元素的乘积称为阿达玛积(Hadamard product,数学符合为 ⨀ \bigodot ),考虑矩阵 B ∈ R m × n B\in R^{m\times n} BRm×n,第 i 行,j 列的元素为 b i j b_{ij} bij,那么矩阵 A 和 B的阿达玛积的结果形式如下:
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 ] (2.3.4) A\bigodot B=\left[ \begin{matrix} 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{matrix} \right] \tag{2.3.4} AB=a11b11a21b21am1bm1a12b12a22b22am2bm2a1nb1na2nb2namnbmn(2.3.4)

Pytorch的语法如下:

print(A*B)

# 输出如下:
tensor([[  0.,   1.,   4.,   9.],
        [ 16.,  25.,  36.,  49.],
        [ 64.,  81., 100., 121.],
        [144., 169., 196., 225.],
        [256., 289., 324., 361.]])

一个张量与一个标量相乘或相加也不会改变张量的形状,其中操作数张量的每个元素都将被相加或乘以这个标量。代码如下:

a = 2
X = torch.arange(24).reshape(2, 3, 4)

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

2.3.6. 张量求和运算

一个常见的运算是求张量元素的和。数学概念中,用符号 ∑ \sum 求和运算。那么,求长度为 d 的向量元素和为: ∑ i = 1 d x i \sum ^d_{i=1}x_i i=1dxi,可以直接调用函数计算:

x = torch.arange(4, dtype=torch.float32)
print(x)
print(x.sum())

# 输出如下:
tensor([0., 1., 2., 3.])
tensor(6.)

我们可以对任意形状的张量求和,比如形状为 m × n m\times n m×n 的矩阵 A 的和为: ∑ i = 1 m ∑ j = 1 n a i j \sum^m_{i=1}\sum^n_{j=1}a_{ij} i=1mj=1naij

print(A.shape)
print(A.sum())

# 输出如下:
torch.Size([5, 4])
tensor(190.)

当然,也可以沿着张量某个轴计算元素的和,那么相应轴的形状分量就会丢失,实际中应用很多:

print(A)

# 沿着轴0计算张量和
A_sum_axis0 = A.sum(axis=0)
print(A_sum_axis0, A_sum_axis0.shape)

# 输出如下:
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
# 求和之后,形状为4,丢失了5这个分量
tensor([40., 45., 50., 55.]) torch.Size([4])

同理,也可以沿着【 Axis-1 】计算和,形状变换与上面的例子类似,代码如下:

print(A)
A_sum_axis1 = A.sum(axis=1)
print(A_sum_axis1, A_sum_axis1.shape)

# 输出如下:
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
tensor([ 6., 22., 38., 54., 70.]) torch.Size([5])

同时沿着矩阵 A 的所有轴计算和,等价于矩阵求和,代码如下:

print(A.sum(axis=[0,1])) # 等价于 A.sum()

# 输出如下:
tensor(190.)

与求和相关的是求均值,也即是元素和除以元素个数,代码如下:

# 均值
print(A.mean(), A.sum() / A.numel())

# 输出如下:
tensor(9.5000) tensor(9.5000)

与求和类似,求均值也可以沿着某个轴进行计算,代码如下:

print(A.mean(axis=0), A.sum(axis=0) / A.shape[0])

# 输出如下:
tensor([ 8.,  9., 10., 11.]) tensor([ 8.,  9., 10., 11.])

值得注意的是,有时候我们需要求和之后,保持矩阵轴的个数不变,但是不保证大小,代码如下:

sum_A = A.sum(axis=1, keepdims=True)
print(sum_A, sum_A.shape)

# 输出如下:
tensor([[ 6.],
        [22.],
        [38.],
        [54.],
        [70.]]) torch.Size([5, 1])

由于求和之后没有改变矩阵轴的数量,那么可以借助广播机制进行除法运算,代码如下:

print(A)
print(A / sum_A)

# 输出如下:
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
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]])

计算沿着矩阵某个轴的累加结果,代码如下:

# 累加和
print(A.cumsum(axis=0))

# 输出如下:
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  6.,  8., 10.],
        [12., 15., 18., 21.],
        [24., 28., 32., 36.],
        [40., 45., 50., 55.]])

2.3.7. 点积

数学形式: x , y ∈ R d \pmb x,\pmb y\in R^d xxx,yyyRd,点积表示为 x T y \pmb x^T\pmb y xxxTyyy 或者 <x, y>
计算方法: x T y = ∑ i = 1 d x i y i \pmb x^T\pmb y=\sum^d_{i=1}x_iy_i xxxTyyy=i=1dxiyi

y = torch.ones(4, dtype=torch.float32)
print(x, y, torch.dot(x, y))

# 输出如下:
tensor([0., 1., 2., 3.]) tensor([1., 1., 1., 1.]) tensor(6.)

点积等价于,先求阿达玛积,然后求和,

xy_sum = torch.sum(x * y)
print(xy_sum)

# 输出如下:
tensor(6.)

点积的意义:

x ∈ R d , w ∈ R d \pmb x\in R^d,\pmb w\in R^d xxxRd,wwwRd,那么向量 x 的权重和为 x T w x^Tw xTw

  1. 如果 ∑ i = 1 d w i = 1 \sum^d_{i=1}w_i=1 i=1dwi=1,则表示向量 x 的加权平均;
  2. 如果 向量 xw 均为单位长度,那么计算结果表示向量夹角的 cos 值;

2.3.8. 矩阵与向量的积

  从上面的内容,我们了解了点积的基本知识。现在我们学习矩阵与向量的积。在【2.3.2】和【2.3.1】小节中,我们分别定义了矩阵 A ∈ R m × n A\in R^{m\times n} ARm×n 和向量 x ∈ R n x\in R^n xRn. 下面,我们以行向量表示矩阵 A,形式如下:
A = [ a 1 T a 2 T ⋮ a m T ] (2.3.5) A=\left[ \begin{matrix} a_1^T \\ a_2^T \\ \vdots \\ a_{m}^T \end{matrix} \right] \tag{2.3.5} A=a1Ta2TamT(2.3.5)
这里, a i T ∈ R n a_i^T\in R^n aiTRn,表示矩阵 A 的行向量。

矩阵与向量的积 A x Ax Ax 的结果是长度为 m 的列向量,第 i 个元素是 a i T x a_i^Tx aiTx,表达形式如下:
A x = [ a 1 T a 2 T ⋮ a m T ] x = [ a 1 T x a 2 T x ⋮ a m T x ] (2.3.6) Ax=\left[ \begin{matrix} a_1^T \\ a_2^T \\ \vdots \\ a_{m}^T \end{matrix} \right]\pmb x=\left[ \begin{matrix} a_1^Tx \\ a_2^Tx \\ \vdots \\ a_{m}^Tx \end{matrix} \right] \tag{2.3.6} Ax=a1Ta2TamTxxx=a1Txa2TxamTx(2.3.6)

通过上面的结果,我们可以将矩阵向量积看成是一个变换(transformation),它将长度为 n 的向量转换为长度为 m 的向量( R n → R m R^n\rightarrow R^m RnRm)。这种变换是非常有用的。比如,我们可以用与方阵的积表示旋转变换。在后面的章节中,我们将用矩阵向量积表示神经网络中最为密集的运算。

torch库实现,代码如下:

API:torch.mv().
注意:矩阵A的列应与向量的长度相等,才能进行乘法运算。

Ax = torch.mv(A, x)
print(A.shape, x.shape, Ax.shape)
print(Ax)

# 输出如下
torch.Size([5, 4]) torch.Size([4]) torch.Size([5])
tensor([ 14.,  38.,  62.,  86., 110.])

2.3.9. 矩阵乘法

假设2个矩阵, A ∈ R n × k , B ∈ R k × m A\in R^{n\times k},B\in R^{k\times m} ARn×k,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 ⋯ a 1 m a 21 a 22 ⋯ a 2 m ⋮ ⋮ ⋱ ⋮ a k 1 a k 2 ⋯ a k m ] (2.3.7) A=\left[ \begin{matrix} 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{matrix} \right],B=\left[ \begin{matrix} b_{11} & b_{12} & \cdots & a_{1m} \\ a_{21} & a_{22} & \cdots & a_{2m} \\ \vdots& \vdots& \ddots & \vdots \\ a_{k1} & a_{k2} & \cdots & a_{km} \end{matrix} \right] \tag{2.3.7} A=a11a21an1a12a22an2a1ka2kank,B=b11a21ak1b12a22ak2a1ma2makm(2.3.7)

a i T ∈ R k a_i^T\in R^k aiTRk 表示矩阵 A 第 i 行的行向量, b j ∈ R k b_j\in R^k bjRk 是矩阵 B 第 j 列的列向量。那么矩阵的乘法表示 C = A B C=AB C=AB,那么用行向量表示的A和用列向量表示的B,形式如下:

A = [ a 1 T a 2 T ⋮ a m T ] , B = [ b 1 , b 2 , ⋯   , b m ] . (2.3.8) A=\left[ \begin{matrix} a_1^T \\ a_2^T \\ \vdots \\ a_{m}^T \end{matrix} \right],B=[b_1,b_2,\cdots,b_m]. \tag{2.3.8} A=a1Ta2TamT,B=[b1,b2,,bm].(2.3.8)
那么,矩阵 C ∈ R n × m C\in R^{n\times m} CRn×m 的每一个元素 c i j c_{ij} cij a i T b j a_i^Tb_j aiTbj 的点积得到,具体形式如下:
C = A B = [ a 1 T a 2 T ⋮ a m T ] [ b 1 , b 2 , ⋯   , b m ] = [ 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 ] . (2.3.9) C=AB=\left[ \begin{matrix} a_1^T \\ a_2^T \\ \vdots \\ a_{m}^T \end{matrix} \right][b_1,b_2,\cdots,b_m]=\left[ \begin{matrix} a_{1}^Tb_{1} & a_{1}^Tb_{2} & \cdots & a_{1}^Tb_m \\ a_{2}^Tb_1 & a_{2}^Tb_2 & \cdots & a_{2}^Tb_m \\ \vdots& \vdots& \ddots & \vdots \\ a_{n}^Tb_1 & a_{n}^Tb_2 & \cdots & a_{n}^Tb_m \end{matrix} \right]. \tag{2.3.9} C=AB=a1Ta2TamT[b1,b2,,bm]=a1Tb1a2Tb1anTb1a1Tb2a2Tb2anTb2a1Tbma2TbmanTbm.(2.3.9)
我们可以将矩阵 A B AB AB的乘积看作是进行m个矩阵向量的点积,然后形成了 n × m n\times m n×m 的矩阵。下面,我们举个简单的例子,矩阵 A A A 是 5 行,4 列的矩阵, B B B 是 4 行,3 列的矩阵,结果是 5行,3列的矩阵,代码如下:

B = torch.ones(4, 3)
C = torch.mm(A, B)
print(C)

# 输出如下
tensor([[ 6.,  6.,  6.],
        [22., 22., 22.],
        [38., 38., 38.],
        [54., 54., 54.],
        [70., 70., 70.]])

注意:矩阵乘法与矩阵阿达玛积的区别。

2.3.10. 范数

  范数是线性代数中非常有用的运算符。非正式的说,向量的范数衡量了向量的大小。这里所考虑的尺寸概念不涉及维度,而是涉及分量的大小。

线性代数中,范数将向量映射为一个标量,并满足一些特性。具体如下:

特性1 :常量与向量积的范数等于常数的绝对值与向量范数的乘积,表述如下:
f ( α x ) = ∣ α ∣ f ( x ) (2.3.10) f(\alpha \pmb x)=|\alpha|f(\pmb x)\tag{2.3.10} f(αxxx)=αf(xxx)(2.3.10)
特性2:三角不等式特性,表述如下:
f ( x + y ) < f ( x ) + f ( y ) (2.3.11) f(\pmb x+\pmb y)<f(\pmb x)+f(\pmb y)\tag{2.3.11} f(xxx+yyy)<f(xxx)+f(yyy)(2.3.11)
特性3:范数非负性,表述如下:
f ( x ) ≥ 0 f(\pmb x)\geq0 f(xxx)0
特性4:范数为0,那么向量的每一个元素都为零,表述如下:
∀ i , [ x ] i = 0 ⇔ f ( x ) = 0 (2.3.13) \forall i,[x]_i=0\Leftrightarrow f(\pmb x)=0\tag{2.3.13} i,[x]i=0f(xxx)=0(2.3.13)

计算范数(Norm)

从上面的特性可以看出,范数像是在度量距离。想想之前学习的欧几里得距离,就会对三角不等性和非负性有一定的理解了。事实上,欧几里得距离就是范数:确切地说,是 L 2 \pmb L_2 LLL2 范数。
 
假定 n 维向量的元素为, x 1 , x 2 , ⋯   , x n x_1,x_2,\cdots,x_n x1,x2,,xn,那么向量 x \pmb x xxx L 2 \pmb L_2 LLL2 范数是各个元素平方和的根,计算公式如下:
∣ ∣ x ∣ ∣ 2 = ∑ i = 1 n x i 2 (2.3.14) ||\pmb x||_2=\sqrt{\sum^n_{i=1}x_i^2}\tag{2.3.14} xxx2=i=1nxi2 (2.3.14)
通常,下标 2 是可以省略的, ∣ ∣ x ∣ ∣ ||\pmb x|| xxx 等价于 ∣ ∣ x ∣ ∣ 2 ||\pmb x||_2 xxx2

范数的计算代码如下:

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

# 输出如下
tensor(5.)

在深度学习中,我们经常遇到计算 L 2 L_2 L2 范数的平方值。当然,也会经常遇到计算 L 1 L_1 L1 范数,计算公式如下:

∣ ∣ x ∣ ∣ 1 = ∑ i = 1 n ∣ x i ∣ (2.3.15) ||\pmb x||_1={\sum^n_{i=1}|x_i| }\tag{2.3.15} xxx1=i=1nxi(2.3.15)

L 2 L_2 L2 范数相比, L 1 L_1 L1 范数更不易受外点影响(噪声点,这个后面章节会解释?),计算代码如下:

l1 = torch.abs(u).sum()
print(l1)

# 输出如下:
tensor(7.)

事实上, L 1 L_1 L1 L 2 L_2 L2 范数是 L p L_p Lp 范数的特殊情况,范数的一般定义如下:
∣ ∣ X ∣ ∣ p = ( ∑ i = 1 n ∣ x i ∣ p ) 1 / p (2.3.16) ||\pmb X||_p={(\sum^n_{i=1}|x_i|^p)^{1/p} }\tag{2.3.16} XXXp=(i=1nxip)1/p(2.3.16)

类似于向量的 L 2 L_2 L2 范数,矩阵 X ∈ R m × n X\in R^{m\times n} XRm×n 的 Frobenius 范数定义如下:
∣ ∣ X ∣ ∣ F = ∑ i = 1 m ∑ j = 1 n x i j 2 (2.3.17) ||\pmb X||_F=\sqrt{\sum^m_{i=1}\sum^n_{j=1}x_{ij}^2}\tag{2.3.17} XXXF=i=1mj=1nxij2 (2.3.17)

矩阵的 Frobenius 范数满足向量范数的所有特性。计算代码如下:

m = torch.norm(torch.ones((4, 9)))
print(m)

# 输出如下:
tensor(6.)
2.3.10.1. 范数与目标函数(objectives)

  虽然我们不想过于超前,但我们可以从直觉上理解为什么这些概念是有用的。在深度学习中,我们经常试图解决优化问题:最大似然概率;尽量减少预测和真实观测之间的距离。为词条(如单词、产品或新闻文章)分配向量表示,使相似词条之间的距离最小,不同词条之间的距离最大。目标函数也许是深度学习算法(除了数据)最重要的组成部分,通常被表达为范数。

2.3.11. 更多的线性代数知识

  在这一节中,我们已经教了你基本的线性代数知识,这将有助于理解现代深度学习。还有很多的线性代数知识和其它的数学知识对深度学习很有用。例如,矩阵可以分解为因子,这些分解可以揭示真实数据集中的低维结构。机器学习的整个子领域专注于使用矩阵分解及其对高阶张量的推广来发现数据集中的结构并解决预测问题。但这本书的重点是深度学习。我们相信,一旦你动手在真实数据集中部署有用的机器学习模型,你会更倾向于学习更多的数学。因此,虽然我们保留稍后介绍更多数学的权利,但我们将在这里结束这一节。

如果你对更多的线性代数感兴趣,参考链接: online appendix on linear algebraic operations,以及其它很好的资源:[Strang, 1993][Kolter, 2008][Petersen et al., 2008].

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值