线性代数篇
1.降维求和
一维求和
可以对任意张量进行求和,譬如:
x = torch.arange(4, dtype=torch.float32)
x, x.sum()
(tensor([0., 1., 2., 3.]), tensor(6.))
因此,对于一个一维向量,求和会沿所有的轴降低张量的维度,使它变为一个标量。
我们还可以[指定张量沿哪一个轴来通过求和降低维度]。
二维求和
以矩阵A(二维张量)为例:
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
为了通过求和所有行的元素来降维(轴0),我们可以在调用函数时指定axis=0。 由于输入矩阵沿0轴降维以生成输出向量,因此输入轴0的维数在输出形状中消失。
A_sum_axis0 = A.sum(axis=0)
A_sum_axis0, A_sum_axis0.shape
(tensor([40., 45., 50., 55.]), torch.Size([4]))
指定axis=1将通过汇总所有列的元素降维(轴1)。因此,输入轴1的维数在输出形状中消失。
A_sum_axis1 = A.sum(axis=1)
A_sum_axis1, A_sum_axis1.shape
(tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))
因此axis指的是在哪个维度上作操作,axis=0是第0轴,也就是张量的第一个维度,如(2,3,4)三维,第0轴就是2,axis=1则是3,axis=2则是4。
在指定的axis求和,指的是对那个轴进行降维,譬如对0轴也就是2求和,得到的结果就是(3,4)的shape。
下面以三维数组求和为例:
三维求和
A = torch.arange(24).reshape(2, 3, 4)
A
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]]])
对axis = 0 求和,是对第三维的2(也就是最前面的维度,第0轴)降维,结果是(3,4)
A_sum_axis0 = A.sum(axis=0)
A_sum_axis0, A_sum_axis0.shape
(tensor([[12, 14, 16, 18],
[20, 22, 24, 26],
[28, 30, 32, 34]]),
torch.Size([3, 4]))
对axis = 1 求和,是对3降维,结果是(2,4)
A_sum_axis0 = A.sum(axis=1)
A_sum_axis0, A_sum_axis0.shape
(tensor([[12, 15, 18, 21],
[48, 51, 54, 57]]),
torch.Size([2, 4]))
对axis = 2 求和,是对4降维,结果是(2,3)
A_sum_axis0 = A.sum(axis=2)
A_sum_axis0, A_sum_axis0.shape
(tensor([[ 6, 22, 38],
[54, 70, 86]]),
torch.Size([2, 3]))
同样的,也可以对两个维度求和,axis=[0,1]表示对(2,3)求和,结果剩下(4),也就是一维了
A_sum_axis0 = A.sum(axis=[0,1])
A_sum_axis0, A_sum_axis0.shape
(tensor([60, 66, 72, 78]),
torch.Size([4]))
这里也引起了我个人对tensor的一个维度的理解
2.tensor维度理解
tensor的最后一维一定是列的概念,而其他的均可理解为行的概念
譬如在对三维数组(2,3,4)求和时:
[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
- axis=0是对2求和,即对2行(3,4)这样的矩阵求和,结果肯定是(3,4)的结构
[[12, 14, 16, 18],
[20, 22, 24, 26],
[28, 30, 32, 34]]
- axis=1是对3求和,即对2个矩阵中的3行的每一行相加求和,结果肯定是(2,4)的结构
[[12, 15, 18, 21],
[48, 51, 54, 57]])
- axis=2是对4求和,即对2个矩阵中的3行的每一行的每一列相加求和,结果肯定是(2,4)的结构
[[ 6, 22, 38],
[54, 70, 86]]
这里可能有点难理解,你可以当作先计算二维向量(3,4)的axis=1求和,而对最后一个维度求和一定是对列作计算,所以是列相加。然后再把2个矩阵的结果拼起来。
3.非降维求和
设置keepdims=True
可以保持轴数不变
sum_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]])