- Course Note: d2l-video-05 - 线性代数
- Jupyter Notebook: chapter_preliminaries/linear-algebra.ipynb
预备知识中 Liner Algebra 的部分
线性代数
Scalars 标量: 指只有一个元素的张量 tensors
PYTHONimport torch x = torch.tensor(3.0) # scalar y = torch.tensor(2.0)
Vectors 向量: 可以视作标量构成的列表
PYTHONx = torch.arange(4) x[3] # 通过张量索引访问任一元素 len(x) # 访问张量长度 x.shape # torch.Size([4]) 只有一个轴的张量, 形状只有一个元素
Matrices 矩阵: 类似向量的推广, 可以构建更多轴的数据结构
PYTHON# 构建矩阵 A = torch.arange(20).reshape(5, 4) A.T # 转置 # 对称矩阵 B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]]) B = B.T
形状相同张量的计算
PYTHONA = torch.arange(20, dtype=torch.float32).reshape(5, 4) B = A.clone() A, A + B A * B # 对应元素相乘: Hadamard 积
计算元素的和
PYTHONx = torch.arange(4, detype=torch.float64) x.sum() # 任意形状张量的和
计算平均值
PYTHONA.mean() # 均值 A.sum() / A.numel() # 另一种计算均值的方法: 和 / 数量
点乘是相同位置元素乘积的和
PYTHONx = torch.tensor([0., 1., 2., 3.]]) y = torch.tensor([1., 1., 1., 1.]]) torch.dot(x, y) # torch(6.) # 或者通过元素乘法, 求和表示点积 torch.sum(x * y) # torch(6.)
降维: axis 指定沿着哪一个轴来降低纬度
假如现在有个张量A如下
PLAINTEXTtensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]])
现在沿着第0轴, 通过求和降低纬度
PYTHONA_sum_axis0 = A.sum(axis=0) A_sum_axis0, A_sum_axis0.shape
输出如下
上面降维的原理就是, 由于axis=0, 就将最外层的纬度去掉, 原来 A.shape=torch.Size([5, 4]), 现在变成了A_sum_axis0=torch.Size([4])
PLAINTEXT(tensor([40., 45., 50., 55.]), torch.Size([4]))
类似的, 还可以降低多个纬度
PYTHONA.sum(axis=[0, 1])
由于A就两个轴, 两个轴都被降低就成了标量
PLAINTEXTtensor(190.)
此外, 还可以保持纬度不变, 将要降的纬度变成1
PYTHONsum_A = A.sum(axis=1, keepdims=True) # keepdims=True 不丢掉原来的纬度
输出如下:
原来 A.shape=torch.Size([5, 4]) 现在变成了sum_A.shape=torch.Size([5,1])PLAINTEXTtensor([[ 6.], [22.], [38.], [54.], [70.]])
这种机制常用于广播, 广播要求纬度相同, 例如
A / sum_A
的计算结果如下PLAINTEXTtensor([[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元素的累积总和
A.cumsum(axis=0)
PLAINTEXTtensor([[ 0., 1., 2., 3.], [ 4., 6., 8., 10.], [12., 15., 18., 21.], [24., 28., 32., 36.], [40., 45., 50., 55.]])
Norms 范数
范数可以理解为"向量的长度/大小"的一种度量方式,
- 向量范数
L1范数, 它表示为向量元素的绝对值之和 (曼哈顿距离)
PYTHONtorch.abs(u).sum()
L2范数是向量元素平方和的平方根 (欧几里德距离)
PYTHONu = torch.tensor([3.0, -4.0]) torch.norm(u)
- 矩阵范数: 最小的满足下面公式的值
$$ c = A \cdot b \quad \text{hence} \quad |c| \leq |A| \cdot |b| $$
矩阵的Frobenius范数(Frobenius norm)是矩阵元素平方和的平方根
$$ |A|_{Frob} = \left(\sum_{i,j} A_{ij}^2 \right)^{\frac{1}{2}} $$
PYTHONtorch.norm(torch.ones((4, 9)))