线性代数
标量
标量由只有一个元素的张量表示。
实例化两个标量,并执行一些熟悉的算术运算,即加法、乘法、除法和指数运算:
import torch
x = torch.tensor(3.0)
y = torch.tensor(2.0)
print(x + y, x * y, x / y, x**y)
(tensor(5.), tensor(6.), tensor(1.5000), tensor(9.))
向量
向量可以被视为标量值组成的列表。
创建一个向量并按照索引访问任意元素:
x = torch.arange(4)
print(x)
print(x[3])
tensor([0, 1, 2, 3])
tensor(3)
矩阵
矩阵-向量积
矩阵-向量积顾名思义是矩阵乘以向量,在代码中以mv函数表示。
A.shape, x.shape, torch.mv(A, x)
(torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))
矩阵-矩阵乘法
我们可以将矩阵-矩阵乘法AB看作简单地执行多次矩阵-向量积,并将结果接在一起,形成一个n*m的矩阵。
矩阵-矩阵乘法的计算方式:
实例:
结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。
在代码中以mm函数表示:
B = torch.ones(4, 3)
torch.mm(A, B)
tensor([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]])
降维
任意张量可以进行的一个操作是计算其元素的和
x = torch.arange(4, dtype=torch.float32)
print(x, x.sum())
(tensor([0., 1., 2., 3.]), tensor(6.))
可以通过指定张量沿哪一个轴来通过求和降低维度:
A = torch.arange(20*2).reshape(2, 4, 5)
print(A, A.shape, A.sum())
# 按照第一个维度降维,即降至torch.Size([4, 5])
A_sum_axis0 = A.sum(axis=0)
print(A_sum_axis0, A_sum_axis0.shape)
# 按照第二个维度降维,即降至torch.Size([2, 5])
A_sum_axis1 = A.sum(axis=1)
print(A_sum_axis1, A_sum_axis1.shape)
tensor([[20, 22, 24, 26, 28],
[30, 32, 34, 36, 38],
[40, 42, 44, 46, 48],
[50, 52, 54, 56, 58]]) torch.Size([4, 5])
tensor([[ 30, 34, 38, 42, 46],
[110, 114, 118, 122, 126]]) torch.Size([2, 5])
也可以用来求均值:
tensor(19.5000, dtype=torch.float64) tensor(19.5000)
tensor([[10., 11., 12., 13., 14.],
[15., 16., 17., 18., 19.],
[20., 21., 22., 23., 24.],
[25., 26., 27., 28., 29.]], dtype=torch.float64)
tensor([[10., 11., 12., 13., 14.],
[15., 16., 17., 18., 19.],
[20., 21., 22., 23., 24.],
[25., 26., 27., 28., 29.]]
非降维求和
有时在调用函数来计算总和或均值时保持轴数不变会很有用,即不降维。
计算总和或者均值时保持轴数不变,需要利用广播机制
,在此需要使用keepdims保证维度不变,才能使用广播机制,否则二维和三维无法进行计算.
sum_A = A.sum(axis=2, keepdims=True)
print(sum_A)
print(A / sum_A)
# 计算A元素的累计求和
print(A.cumsum(axis=2))
tensor([[[ 10],
[ 35],
[ 60],
[ 85]],
[[110],
[135],
[160],
[185]]])
tensor([[[0.0000, 0.1000, 0.2000, 0.3000, 0.4000],
[0.1429, 0.1714, 0.2000, 0.2286, 0.2571],
[0.1667, 0.1833, 0.2000, 0.2167, 0.2333],
[0.1765, 0.1882, 0.2000, 0.2118, 0.2235]],
[[0.1818, 0.1909, 0.2000, 0.2091, 0.2182],
[0.1852, 0.1926, 0.2000, 0.2074, 0.2148],
[0.1875, 0.1937, 0.2000, 0.2062, 0.2125],
[0.1892, 0.1946, 0.2000, 0.2054, 0.2108]]])
tensor([[[ 0, 1, 3, 6, 10],
[ 5, 11, 18, 26, 35],
[ 10, 21, 33, 46, 60],
[ 15, 31, 48, 66, 85]],
[[ 20, 41, 63, 86, 110],
[ 25, 51, 78, 106, 135],
[ 30, 61, 93, 126, 160],
[ 35, 71, 108, 146, 185]]])
点积(Dot Product)
点积是给定两个向量x,y他们的点积是相同位置的按元素乘积的和:
y = torch.ones(4, dtype = torch.float32)
x, y, torch.dot(x, y)
(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))
除了dot函数也可以通过执行按元素乘法,然后进行求和来表示两个向量的点积:
torch.sum(x * y)
tensor(6.)
范数
线性代数中最有用的一些运算符是范数(norm)。
主要介绍三种范数:
L1范数表示为向量元素的绝对值之和
。
L2范数是向量元素平方和的平方根
。
Frobenius范数(Frobenius norm)是矩阵元素平方和的平方根
。
# L2范数是向量元素平方和的平方根
u = torch.tensor([3.0, -4.0])
print(torch.norm(u))
# L1范数,为向量元素的绝对值之和
print(torch.abs(u).sum())
# Frobenius范数(Frobenius norm)是矩阵元素平方和的平方根
print(torch.norm(torch.ones((4, 9))))
tensor(5.)
tensor(7.)
tensor(6.)
特殊矩阵