读书笔记-动手学深度学习-Pytorch版
参考文献
- 动手学深度学习 Pytorch版
2.3 线性代数
标量
-
本书采⽤了数学表⽰法,其中标量变量由普通⼩写字⺟表⽰(例如,、和).本书⽤R表⽰所有(连续)实数标量的空间,之后将严格定义空间(space)是什么,但现在只要记住表达式是表⽰x是⼀个实值标量的正式形式.符号称为“属于”,它表⽰“是集合中的成员”.例如可以⽤来表明和是值只能为0或1的数字.
-
标量由只有⼀个元素的张量表⽰.下⾯的代码将实例化两个标量,并执⾏⼀些熟悉的算术运算,即加法、乘法、除法和指数
1
2
3
4
5
6import 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.))
向量
-
向量可以被视为标量值组成的列表.这些标量值被称为向量的元素(element)或分量(component).当向 量表⽰数据集中的样本时,它们的值具有⼀定的现实意义.在数学表⽰法中,向量通常记为粗体、⼩写的符号(例如,$\mathbf{x} \mathbf{y} \mathbf{z} $)).
1
2
3
4x=torch.arange(4)
x
==> tensor([0, 1, 2, 3]) -
我们可以使⽤下标来引⽤向量的任⼀元素,例如可以通过 来引⽤第个元素.注意,元素 是⼀个标量,所以我们在引⽤它时不会加粗.⼤量⽂献认为列向量是向量的默认⽅向,在本书中也是如此.在数学中,向量可以写为:
- 其中 , . . . , 是向量的元素.
⻓度、维度和形状
-
向量只是⼀个数字数组,就像每个数组都有⼀个⻓度⼀样,每个向量也是如此.在数学表⽰法中,如果我们想说⼀个向量由个实值标量组成,可以将其表⽰为 .向量的⻓度通常称为向量的维度(dimension)
-
与普通的
Python
数组⼀样,我们可以通过调⽤Python
的内置len()
函数来访问张量的⻓度.1
len(x)
-
当⽤张量表⽰⼀个向量(只有⼀个轴)时,我们也可以通过
.shape
属性访问向量的⻓度.形状(shape)是⼀个元素组,列出了张量沿每个轴的⻓度(维数).对于只有⼀个轴的张量,形状只有⼀个元素.1
x.shape
-
矩阵
-
正如向量将标量从零阶推⼴到⼀阶,矩阵将向量从⼀阶推⼴到⼆阶.矩阵,我们通常⽤粗体、⼤写字⺟来表⽰(例如,、和),在代码中表⽰为具有两个轴的张量.
-
数学表⽰法使⽤来表⽰矩阵,其由⾏和列的实值标量组成.我们可以将任意矩阵 视为⼀个表格,其中每个元素属于第⾏第列
-
对于任意,的形状是或.当矩阵具有相同数量的⾏和列时,其形状将变为正⽅形;因此,它被称为⽅阵(
square matrix
). -
当调⽤函数来实例化张量时,我们可以通过指定两个分量和来创建⼀个形状为的矩阵.
1
2
3
4
5
6
7
8A=torch.arange(20).reshape(5,4)
A
==> tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]]) -
当我们交换矩阵的⾏和列时,结果称为矩阵的转置(transpose).通常⽤来表⽰矩阵的转置,如果 , 则对于任意和,都有 .
张量
-
就像向量是标量的推⼴,矩阵是向量的推⼴⼀样,我们可以构建具有更多轴的数据结构.张量(本⼩节中的 “张量”指代数对象)是描述具有任意数量轴的维数组的通⽤⽅法.例如,向量是⼀阶张量,矩阵是⼆阶张量.张量⽤特殊字体的⼤写字⺟表⽰(例如,、和),它们的索引机制(例如和 )与矩阵类似.
1
2
3
4
5
6
7
8
9
10X=torch.arange(24).reshape(2,3,4)
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]]])
张量算法的基本性质
-
标量、向量、矩阵和任意数量轴的张量(本⼩节中的“张量”指代数对象)有⼀些实⽤的属性.例如,从按元素操作的定义中可以注意到,任何按元素的⼀元运算都不会改变其操作数的形状.同样,给定具有相同形状的任意两个张量,任何按元素⼆元运算的结果都将是相同形状的张量.例如,将两个相同形状的矩阵相加,会在这两个矩阵上执⾏元素加法.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19A=torch.arange(20,dtype=torch.float32).reshape(5,4)
B=A.clone()
A,A+B,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.]]),
tensor([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]])) -
具体⽽⾔,两个矩阵的按元素乘法称为Hadamard积(Hadamard product)(数学符号).对于矩阵 , 其中第⾏和第列的元素是 .矩阵和的Hadamard积为:
降维
-
我们可以对任意张量进⾏的⼀个有⽤的操作是计算其元素的和.数学表⽰法使⽤符号$\sum d{\textstyle \sum_{i=1}^{d}} x_{i}$
1
2
3
4x=torch.arange(4,dtype=torch.float32)
x,x.sum()
==> (tensor([0., 1., 2., 3.]), tensor(6.)) -
矩阵A中元素的和可以记
1
2
3A.shape,A.sum()
==>(torch.Size([5, 4]), tensor(190.)) -
默认情况下,调⽤求和函数会沿所有的轴降低张量的维度,使它变为⼀个标量.我们还可以指定张量沿哪⼀ 个轴来通过求和降低维度.以矩阵为例,为了通过求和所有⾏的元素来降维(轴0),可以在调⽤函数时指定
axis=0
.由于输⼊矩阵沿0轴降维以⽣成输出向量,因此输⼊轴0的维数在输出形状中消失.1
2
3
4
5
6
7
8
9A_sum_axis0=A.sum(axis=0)
A_sum_axis0
==> tensor([40., 45., 50., 55.])
A_sum_axis1=A.sum(axis=1)
A_sum_axis1
==> tensor([ 6., 22., 38., 54., 70.]) -
⼀个与求和相关的量是平均值(mean或average).我们通过将总和除以元素总数来计算平均值.在代码中, 我们可以调⽤函数来计算任意形状张量的平均值
1
2
3A.mean(), A.sum() / A.numel()
==> (tensor(9.5000), tensor(9.5000))
⾮降维求和
-
有时在调⽤函数来计算总和或均值时保持轴数不变会很有⽤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16sum_A=A.sum(axis=1,keepdims=True)
sum_A
==> tensor([[ 6.],
[22.],
[38.],
[54.],
[70.]])
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]]) -
如果我们想沿某个轴计算A元素的累积总和,⽐如axis=0(按⾏计算),可以调⽤cumsum函数.此函数不会沿任何轴降低输⼊张量的维度.
1
2
3
4
5
6
7
8
9
10
11
12A.cumsum(axis=0),A
==> (tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]]),
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]))
点积(Dot Product
)
-
给定两个向量,它们的点积(
dot product
)或者是相同位置的按元素乘积的和:1
2
3
4
5
6import torch
y=torch.ones(4,dtype=torch.float32)
x = torch.arange(4, dtype=torch.float32)
x,y,torch.dot(x,y)
==> (tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.)) -
也可以通过按元素乘法,然后求和来表示两个向量的点积
1
torch.sum(x*y)
-
点积在很多场合都很有用.例如,给定一组由向量表示的值,和一组由表示的权重.$\mathbf{x} \mathbf{w}\mathbf{x}^{T}\mathbf{w}(\sum_{i=1}^{d}w_{i=1})$时,点积表示加权平均(
weighted average
).将两个向量规范化得到单位长度后,点积表示它们夹角的余弦.
矩阵-向量积
-
定义矩阵和向量,将矩阵用它的行向量表示:
-
其中每个都是行向量,表示矩阵的第行.矩阵向量积是一个长度为的列向量,其第个元素是点积
-
可以把一个矩阵乘法看作一个从到向量的转换.这些转换时非常有用的,例如可以用方阵的乘法表示旋转.
-
在代码中使用张量表示矩阵-向量积,使用
mv
函数.当为矩阵和向量调用torch.mv(A,x)
时,会执行行矩阵-向量积.注意的列维数(沿轴1的长度)必须与的维数(其长度)相同1
2
3
4A=torch.arange(20,dtype=torch.float32).reshape(5,4)
A.shape,x.shape,torch.mv(A,x)
==> (torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))
矩阵-矩阵乘法
-
假设有两个矩阵和
-
用行向量表示矩阵的第行,并让列向量作为矩阵的第列.要生成矩阵积
-
可以将矩阵-矩阵乘法看作简单地执⾏次矩阵-向量积,并将结果拼接在⼀起,形成⼀个矩阵.
范数
-
线性代数中最有⽤的⼀些运算符是范数(norm).⾮正式地说,向量的范数是表⽰⼀个向量有多⼤.这⾥考虑的⼤⼩(size)概念不涉及维度,⽽是分量的⼤⼩.
-
在线性代数中,向量范数是将向量映射到标量的函数 .给定任意向量,向量范数要满⾜⼀些属性.第⼀个性质是:如果我们按常数因⼦$\alpha $缩放向量的所有元素,其范数也会按相同常数因⼦的绝对值缩放
-
第二个性质是三角不等式
-
第三个性质是范数必须是非负的
-
这是有道理的.因为在⼤多数情况下,任何东西的最⼩的⼤⼩是0.最后⼀个性质要求范数最⼩为0,当且仅
当向量全由0组成 -
范数听起来很像距离的度量.欧⼏⾥得距离和毕达哥拉斯定理中的⾮负性概念和三⻆不等式可能会给出⼀些启发.事实上,欧⼏⾥得距离是⼀个范数:假设n维向量x中的元素是 ,其范数是向量元素平⽅和的平⽅根
-
其中,在范数中常常省略下标2,也就是说等同于 .在代码中,我们可以按如下⽅式计算向量的范数
1
2
3
4u=torch.tensor([3.0,-4.0])
torch.norm(u)
==>tensor(5.) -
深度学习中更经常地使⽤范数的平⽅,也会经常遇到范数,它表⽰为向量元素的绝对值之和:
-
与范数相⽐,范数受异常值的影响较⼩.为了计算范数,我们将绝对值函数和按元素求和组合起来.
1
2
3torch.abs(u).sum()
==>tensor(7.) -
范数和范数都是更⼀般的范数的特例
-
类似于向量的范数,矩阵 ( ) 的 Frobenius 范数 (Frobenius norm) 是矩阵元素平方和的平方根
-
Frobenius范 数 满 ⾜ 向 量 范 数 的 所 有 性 质, 它 就 像 是 矩 阵 形 向 量 的范 数. 调 ⽤ 以 下 函 数 将 计 算 矩 阵 的Frobenius范数
1
2
3torch.norm(torch.ones((4, 9)))
==> tensor(6.)
2.4 微积分
导数和微分
-
假设我们有⼀个函数,其输⼊和输出都是标量.如果的导数存在,这个极限被定义为
-
如果存在,则称在处是可微(differentiable)的.如果在⼀个区间内的每个数上都是可微的,则此函数在此区间中是可微的.可以将上述公式中的导数解释为相对于的瞬时(instantaneous)变化率.所谓的瞬时变化率是基于中的变化,且接近
-
给定 ,其中和分别是函数的自变量和因变量.以下表达式是等价的:
- 其中符号 和是微分符号,表示微分操作.我们可以使用以下规则来对常见函数求微分:
- 其中符号 和是微分符号,表示微分操作.我们可以使用以下规则来对常见函数求微分:
-
为了微分一个由一些常见函数组成的函数,下面的一些法则方便使用.假设函数和都是可微的,是一个常数,则
-
常数相乘法则
-
加法法则
-
乘法法则
-
除法法则
-
偏导数
-
设是⼀个具有个变量的函数.关于第个参数的偏导数(partial derivative)为:
-
为了计算,可以简单地讲看作常数,并计算关于的倒数,对于偏导数的表示,以下是等价的:
梯度
-
我们可以连结⼀个多元函数对其所有变量的偏导数,以得到该函数的梯度(gradient)向量.具体⽽⾔,设函数的输⼊是⼀个维向量$\mathbf{x}=[x_{1} , x_{2} , \dots, x_{n}]^{T} f(\mathbf{x})\mathbf{x}$的梯度是⼀个包含n个偏导数的向量:
- 其中通常在没有歧义时被取代.
-
假设为维向量,在微分多元函数时经常使⽤以下规则:
- 对于所有,都有
- 对于所有,都有
- 对于所有,都有
-
-
同样对于任何矩阵,都有
链式法则
-
然⽽,上⾯⽅法可能很难找到梯度.这是因为在深度学习中,多元函数通常是复合(
composite
)的,所以难以应⽤上述任何规则来微分这些函数.幸运的是,链式法则可以被⽤来微分复合函数. -
让我们先考虑单变量函数.假设函数和都是可微的,根据链式法则
-
现在考虑⼀个更⼀般的场景,即函数具有任意数量的变量的情况.假设可微分函数有变量,其中每个可微分函数都有变量.注意,是 的函数.对于任意,链式法则给出
2.5 ⾃动微分
- 深度学习框架通过⾃动计算导数,即⾃动微分(
automatic differentiation
)来加快求导.实际中,根据设计好的模型,系统会构建⼀个计算图(computational graph
),来跟踪计算是哪些数据通过哪些操作组合起来产⽣输出.⾃动微分使系统能够随后反向传播梯度.这⾥,反向传播(backpropagate
)意味着跟踪整个计算图,填充关于每个参数的偏导数.
2.6 概率
概率论公理
- 在处理骰⼦掷出时,我们将集合 称为样本空间(sample space)或结果空间(outcome space),其中每个元素都是结果(outcome).事件(event)是⼀组给定样本空间的随机结果.例如,“看到5”()和“看到奇数”()都是掷出骰⼦的有效事件.注意,如果⼀个随机实验的结果在A中,则事件A已经发⽣.也就是说,如果投掷出3点,因为,我们可以说,“看到奇数”的事件发⽣了.
- 概率(
probability
)可以被认为是将集合映射到真实值的函数.在给定的样本空间中,事件A的概率,表⽰为,满⾜以下属性:- 对于任意事件,其概率从不会是负数,即;
- 整个样本空间的概率为1,即;
- 对于互斥(
mutually exclusive
)事件(对于所有都有$\mathcal{A}{i}\cap\mathcal{A}{j}=\emptyset \mathcal{A}{1},\mathcal{A}{2},\dots,P(\cup_{i=1}^{\infty}\mathcal{A}{i})=\sum{i=1}^{\infty}P(\mathcal{A_{i}})$
- 以上也是概率论的公理,由科尔莫⼽罗夫于1933年提出.有了这个公理系统,我们可以避免任何关于随机性的哲学争论;相反,我们可以⽤数学语⾔严格地推理.例如,假设事件为整个样本空间,且当所有时的,那么我们可以证明,即不可能发⽣事件的概率是0.
随机变量
- 随机变量⼏乎可以是任何数量,并且它可以在随机实验的⼀组可能性中取⼀个值.考虑⼀个随机变量 ,其值在掷骰⼦的样本空间中.我们可以将事件“看到⼀个5”表⽰为或,其概率表⽰为或.通过,我们区分了随机变量和 可以采取的值(例如).
- 然⽽,这可能会导致繁琐的表⽰.为了简化符号,⼀⽅⾯,我们可以将表⽰为随机变量X 上的分布(distribution):分布告诉我们获得某⼀值的概率.另⼀⽅⾯,我们可以简单⽤表⽰随机变量取值的概率.由于概率论中的事件是来⾃样本空间的⼀组结果,因此我们可以为随机变量指定值的可取范围.例如,表⽰事件,即的概率.等价地,表⽰随机变量 从中取值的概率.
联合概率
- 第⼀个被称为联合概率(
joint probability
).给定任意值和,联合概率可以回答:和同时满⾜的概率是多少?请注意,对于任何和的取值,.这点是确定的,因为要同时发⽣和,就必须发⽣,也必须发⽣(反之亦然).因此,和同时发⽣的可能性不⼤于或是单独发⽣的可能性.
条件概率
- 联合概率的不等式带给我们一个有趣的比率:.我们称这个比率为条件概率(
conditional probability
),并用表示它,它是的概率,前提是已经发生.
⻉叶斯定理
-
使用条件概率的定义,我们可以得出统计学中最有用的方程之一:
Bayes
定理(Bayes' theorem
).根据乘法法则(multiplication rule
)可得到.根据对称性,可得到.假设,求解其中一个条件变量,我们得到 -
请注意,这里我们使用紧凑的表示法: 其中是一个联合分布(
join distribution
),是一个条件分布(conditional distribution
).这种分布可以在定值上进行求值.