动手学深度学习v2 - 数学相关

本文最后更新于 2022年1月26日 晚上

线代基础内容已经详细学习过,因此不再赘述

线性代数基础操作

转置

1
2
A = torch.arange(20).reshape(5,4)
A.T

对称矩阵

1
A == A.T

构建多维的数据结构

1
X = torch.arange(24).reshape(2, 3, 4) # 2个3行4列

矩阵的哈达玛积 $\odot$ (对应位置元素相乘)

1
A*B

矩阵的一些运算

1
2
3
4
a = 2
X = torch.arange(24).reshape(2, 3, 4)
a + X # 每个元素+2
(a * X).shape # 每个元素*2

张量沿轴求和

1
2
3
4
5
6
7
A_sum_axis0 = A.sum(axis=0) # 实际效果,分别对每一列求和,向下压扁
A_sum_axis1 = A.sum(axis=1) # 分别对每一行求和,向右压扁
# 拓展
# A的shape: [2,5,4]
# axis1 = [2,4]
# 即对哪个axis求,消掉对应的值(维度)
# 当加入keepdims参数=True,不会消掉对应维度,会置为1

求均值

1
2
3
A.mean()
A.sum() / A.numel() # 等价
A.mean(axis=0), A.sum(axis=0) / A.shape[0] # 沿轴求均值

求均值并且保持维度不变

1
2
sum_A = A.sum(axis=1, keepdims=True)
A / sum_A # 可以使用广播机制了

求累计和

1
2
3
A.cumsum() # 当成1维计算,新张量为前面的元素累计
A.cumsum(axis=0) # 列累计相加
A.cumsum(axis=1) # 行累计相加

点积

1
2
3
4
5
x = torch.arange(4)
y = torch.ones(4, dtype=torch.float32)
torch.dot(x, y)
# 等价于
torch.sum(x*y)

求矩阵向量积$Ax$

1
torch.mv(A, x)

矩阵乘法

1
torch.mm(A, B)

$L_2$范数,表示向量或者矩阵的长度

1
torch.norm(u)

$L_1$ 范数,表示为向量元素的绝对值之和:

1
torch.abs(u).sum()

矩阵的弗罗贝尼乌斯范数(Frobenius norm): 矩阵元素平方和的平方根

1
torch.norm(torch.ones((4, 9)))

微分

image-20210410085542120

image-20210410091505570

image-20210410092517602

image-20210410091505570

image-20210410091941381

image-20210410092139742

梯度与偏导理解:

向量链式法则:

image-20210410122401797

image-20210410131120120

自动求导

计算图,与高数求偏导的链式法则类似

image-20210410132256198

image-20210410132632351

image-20210410133013278

反向传递复杂度:

时间复杂度/计算复杂度:$O(n)$,n为操作子个数,通常正向和反向的代价类似

空间复杂度/内存复杂度:$O(n)$,需要存放正向的所有中间结果

正向的内存复杂度:$O(1)$,计算复杂度:$O(n)$,计算一个变量的梯度,复杂度高

假设对函数 $y = 2\mathbf{x}^{\top}\mathbf{x}$关于列向量 $\mathbf{x}$求导

其中x = [0,1,2,3]

手动求导:$y’ = 4x$,可求得[0, 4, 8, 12]

自动求导:

1
2
3
4
5
6
7
8
9
10
11
x = torch.arange(4.0, requires_grad=True)
x.grad # 默认None

y = 2 * torch.dot(x, x) # 28
y.backward() # 计算y关于x的每一个分量的梯度
x.grad
# 验证
x.grad == 4*x

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()

非标量变量的反向传播

计算$y=x^2$

1
2
3
4
5
x.grad.zero_()
y = x * x
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad

练习

2.5.6

  1. 计算$f(x) = sin(x)$的导数

    1
    2
    3
    y = torch.sin(x)
    y.sum().backward()
    x.grad

动手学深度学习v2 - 数学相关
https://nanami.run/2021/04/04/d2l-pytorch-linear/
作者
Nanami
发布于
2021年4月4日
许可协议