pytorch之线性代数

矩阵

1. 矩阵初始化

Tensor的初始化

# 全零矩阵

In [1]: import torch

In [2]: myZero = torch.zeros(3,3)

In [3]: myZero
Out[3]: 
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

In [4]: type(myZero)
Out[4]: torch.Tensor

In [5]: myZero.dtype
Out[5]: torch.float32

# 全一矩阵

In [6]: myOnes = torch.ones(3,3)

In [8]: myOnes
Out[8]: 
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])

# 单位矩阵

In [9]: myEye = torch.eye(5)

In [10]: myEye
Out[10]: 
tensor([[1., 0., 0., 0., 0.],
        [0., 1., 0., 0., 0.],
        [0., 0., 1., 0., 0.],
        [0., 0., 0., 1., 0.],
        [0., 0., 0., 0., 1.]])

# 对称矩阵

In [11]: a1 = [1,2,3,4,5]

In [13]: a1 = torch.tensor(a1)

In [14]: a1
Out[14]: tensor([1, 2, 3, 4, 5])

In [15]: myDiag = torch.diag(a1)

In [16]: myDiag
Out[16]: 
tensor([[1, 0, 0, 0, 0],
        [0, 2, 0, 0, 0],
        [0, 0, 3, 0, 0],
        [0, 0, 0, 4, 0],
        [0, 0, 0, 0, 5]]) 

# 随机矩阵

In [17]: myRand = torch.rand(3,3)

In [18]: myRand
Out[18]: 
tensor([[0.9588, 0.0139, 0.2303],
        [0.4332, 0.1916, 0.4152],
        [0.4848, 0.3361, 0.9799]])
  • 直接创建tensor
In [19]: a = torch.tensor([[1,2,3],[4,5,6]])

In [20]: a
Out[20]: 
tensor([[1, 2, 3],
        [4, 5, 6]])
  • 通过from_numpy() 函数将ndarray数据类型转化成矩阵(tensor)
In [21]: import numpy as np

In [22]: a = np.arange(12).reshape(3,4)

In [23]: b = torch.from_numpy(a)

In [24]: b
Out[24]: 
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]], dtype=torch.int32)
2. 矩阵元素运算

矩阵的元素运算是指矩阵在元素级别的加、减、乘、除运算。
(1)元素相加和相减。
条件:矩阵的行数和列数必须相同。
数学公式: ( A ± B ) i , j = A i , j ± B i , j (A±B)_i,_j=A_i,_j±B_i,_j

In [27]: myOnes = torch.ones(4,4)

In [28]: myOnes
Out[28]: 
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])

In [29]: myEye = torch.eye(4)

In [30]: myEye
Out[30]: 
tensor([[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.],
        [0., 0., 0., 1.]])

In [31]: myOnes + myEye
Out[31]: 
tensor([[2., 1., 1., 1.],
        [1., 2., 1., 1.],
        [1., 1., 2., 1.],
        [1., 1., 1., 2.]])

In [32]: myOnes - myEye
Out[32]: 
tensor([[0., 1., 1., 1.],
        [1., 0., 1., 1.],
        [1., 1., 0., 1.],
        [1., 1., 1., 0.]])

(2)矩阵数乘:一个数乘以一个矩阵。

数学公式: ( c A ) i , j = c A i , j (cA)_i,_j=c·A_i,_j

In [37]: b 
Out[37]: 
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]], dtype=torch.int32)

In [39]: b*10
Out[39]: 
tensor([[  0,  10,  20,  30],
        [ 40,  50,  60,  70],
        [ 80,  90, 100, 110]], dtype=torch.int32)

(3)矩阵所有元素求和。
数学公式:
sum ( A ) = i = 1 m j = 1 n A i , j = 1 , 1 < i < m , 1 < j < n \operatorname{sum}(A)=\sum_{i=1}^{m} \sum_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

In [40]: torch.sum(b)
Out[40]: tensor(66)

(4)矩阵所有元素之积

数学公式:
product ( A ) = i = 1 m j = 1 n A i , j = 1 , 1 < i < m , 1 < j < n \operatorname{product}(A)=\prod_{i=1}^{m} \prod_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

In [47]: a = torch.arange(4).reshape(2,2)+1

In [48]: a
Out[48]: 
tensor([[1, 2],
        [3, 4]])

In [49]: torch.prod(a)
Out[49]: tensor(24)

(5)矩阵各元素的n次幂:n=3。
数学公式:
A i j 3 = A i j × A i j × A i j A_{ij}^3=A_{ij}×A_{ij}×A_{ij}

In [50]: a
Out[50]: 
tensor([[1, 2],
        [3, 4]])

In [52]: torch.pow(a,3)
Out[52]: 
tensor([[ 1,  8],
        [27, 64]])
3. 矩阵的乘法

(1)矩阵各元素的积:矩阵的点乘同维对应元素的相乘。当矩阵的维度不同时,会根据一定的广播规则将维数扩充到一致的形式。
数学公式:
( A × B ) i , j = A i , j × B i , j (A×B)_i,_j =A_i,_j×B_i,_j

In [64]: a
Out[64]: 
tensor([[1, 2],
        [3, 4]])

In [65]: b
Out[65]: 
tensor([[0, 1],
        [2, 3]])
#torch.mul(a,b)
In [66]: a*b
Out[66]: 
tensor([[ 0, 2],
        [ 6, 12]])

(2)矩阵内积

数学公式:
[ A , B ] i , j = A i , 1 B 1 , j + A i , 2 B 2 , j + + A i n B n j = r = 1 n A i , r B r , j [\boldsymbol{A}, \boldsymbol{B}]_{i, j}=\boldsymbol{A}_{i, 1} \boldsymbol{B}_{1, j}+\boldsymbol{A}_{i, 2} \boldsymbol{B}_{2, j}+\cdots+\boldsymbol{A}_{i n} \boldsymbol{B}_{n j}=\sum_{r=1}^{n} \boldsymbol{A}_{i, r} \boldsymbol{B}_{r, j^{\circ}}

In [68]: a
Out[68]: 
tensor([[1, 2],
        [3, 4]])

In [69]: b
Out[69]: 
tensor([[0, 1, 2],
        [3, 4, 5]])

In [70]: torch.dot(a,b)
Traceback (most recent call last):

  File "<ipython-input-70-5682e150e844>", line 1, in <module>
    torch.dot(a,b)
# 报错,只允许一维的tensor,只适合向量内积
RuntimeError: 1D tensors expected, got 2D, 2D tensors at C:\w\1\s\tmp_conda_3.6_045031\conda\conda-bld\pytorch_1565412750030\work\aten\src\TH/generic/THTensorEvenMoreMath.cpp:723

#官方提示此功能不广播。有关广播的矩阵乘法,请参见torch.matmul()
In [71]: torch.mm(a,b) 
Out[71]: 
tensor([[ 6,  9, 12],
        [12, 19, 26]])

In [72]: torch.matmul(a,b)
Out[72]: 
tensor([[ 6,  9, 12],
        [12, 19, 26]])

(3)向量内积、外积

x = ( x 1 , x 1 , . . . , x m ) x=\left(x_{1}, x_{1}, ...,x_{m}\right)
y = ( y 1 , y 2 , . . . , y n ) y=\left(y_{1}, y_{2},...,y_{n}\right)

向量内积: x y T = i = 1 n x i y i x y^{T}=\sum_{i=1}^{n} x_{i} y_{i}

向量外积: x T y = ( x 1 y 1 x 1 y n x m y 1 x m y n ) x ^{T}y=\left(\begin{array}{ccc}{x_{1} y_{1}} & {\cdots} & {x_{1} y_{n}} \\ {\vdots} & {} & {\vdots} \\ {x_{m} y_{1}} & {\cdots} & {x_{m} y_{n}}\end{array}\right)

In [73]: a1  = torch.tensor([2,1,0])

In [74]: a2 = torch.tensor([-1,2,1])

In [75]: a1
Out[75]: tensor([2, 1, 0])

In [76]: a2
Out[76]: tensor([-1,  2,  1])

In [77]: torch.dot(a1,a2)
Out[77]: tensor(0)

In [78]: torch.outer(a1,a2)
Traceback (most recent call last):
# 在pytorch中没有outer函数
  File "<ipython-input-78-cc115fea0111>", line 1, in <module>
    torch.outer(a1,a2)

AttributeError: module 'torch' has no attribute 'outer'
# 解决办法,先将一维的向量转换为二维,再利用矩阵内积方法计算
In [86]: a1 = a1.reshape(1,3)

In [87]: a2 = a2.reshape(1,3)
# 转置
In [88]: a1.T
Out[88]: 
tensor([[2],
        [1],
        [0]])

In [89]: torch.mm(a1.T,a2)
Out[89]: 
tensor([[-2,  4,  2],
        [-1,  2,  1],
        [ 0,  0,  0]])

(4)向量叉乘(叉积):运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量组成的坐标平面垂直。

数学公式:

a = ( x 1 , y 1 , z 1 ) a=\left(x_{1}, y_{1}, z_{1}\right)
b = ( x 2 , y 2 , z 2 ) b=\left(x_{2}, y_{2}, z_{2}\right)
a × b = i j k x 1 y 1 z 1 x 2 y 2 z 2 = ( y 1 z 2 y 2 z 1 ) i ( x 1 z 2 x 2 z 1 ) j + ( x 1 y 2 x 2 y 1 ) k a \times b=\left|\begin{array}{ccc}{\mathrm{i}} & {\mathrm{j}} & {\mathrm{k}} \\ {x_{1}} & {y_{1}} & {z_{1}} \\ {x_{2}} & {y_{2}} & {z_{2}}\end{array}\right|=\left(y_{1} z_{2}-y_{2} z_{1}\right) i-\left(x_{1} z_{2}-x_{2} z_{1}\right) j+\left(x_{1} y_{2}-x_{2} y_{1}\right) k
其中
i = ( 1 , 0 , 0 ) j = ( 0 , 1 , 0 ) k = ( 0 , 0 , 1 ) i=(1,0,0) \quad j=(0,1,0) \quad \mathrm{k}=(0,0,1)
根据i、j、k间关系,有:
a × b = ( y 1 z 2 y 2 z 1 , ( x 1 z 2 x 2 z 1 ) , x 1 y 2 x 2 y 1 ) a \times b=\left(y_{1} z_{2}-y_{2} z_{1},-\left(x_{1} z_{2}-x_{2} z_{1}\right), x_{1} y_{2}-x_{2} y_{1}\right)

例1、已知,a =(2,1,0),b =(-1,2,1),试求(1) a × b a\times b (2) b × a b\times a
解:(1) a × b a\times b =(1,-2,5)
(2) b × a b\times a =(-1,2,5)

In [79]: torch.cross(a1,a2)
Out[79]: tensor([ 1, -2,  5])

In [80]: torch.cross(a2,a1)
Out[80]: tensor([-1,  2, -5])
4. 矩阵的转置

数学公式: ( A T ) i j = A i j (A^T)_{ij} = A_{ij}

In [90]: a
Out[90]: 
tensor([[1, 2],
        [3, 4]])

In [91]: a.T
Out[91]: 
tensor([[1, 3],
        [2, 4]])

In [92]: a.transpose(1,0)
Out[92]: 
tensor([[1, 3],
        [2, 4]])
5. 矩阵对应列行的最大值,最小值,和
In [99]: b 
Out[99]: 
tensor([[0, 1, 2],
        [3, 4, 5]])
# 计算矩阵中最大值的对应索引
In [100]: b.argmax()
Out[100]: tensor(5)
# 计算矩阵列中最大值对应的行索引
In [101]: b.argmax(axis=0)
Out[101]: tensor([1, 1, 1])
# 计算矩阵行中最大值对应的列索引
In [102]: b.argmax(axis=1)
Out[102]: tensor([2, 2])
# 矩阵中的最大值
In [103]: b.max()
Out[103]: tensor(5)
# 矩阵列中的最小值
In [104]: b.min()
Out[104]: tensor(0)
# 矩阵列求和
In [105]: b.sum(axis=0)
Out[105]: tensor([3, 5, 7])
6. 矩阵的其他操作:行列数、切片、复制、非0元素的下标
In [106]: a
Out[106]: 
tensor([[1, 2],
        [3, 4]])
# 行列数
In [107]: m,n = a.shape

In [108]: m,n
Out[108]: (2, 2)

In [109]: b
Out[109]: 
tensor([[0, 1, 2],
        [3, 4, 5]])
# 切片
In [111]: b[1:]
Out[111]: tensor([[3, 4, 5]])

In [112]: b[:,1:]
Out[112]: 
tensor([[1, 2],
        [4, 5]])
# 复制
In [114]: c = torch.clone(b)

In [115]: c
Out[115]: 
tensor([[0, 1, 2],
        [3, 4, 5]])
# 随机生成0-8,大小4*4
In [116]: d = torch.randint(0,9,(4,4))

In [117]: d
Out[117]: 
tensor([[3, 1, 2, 2],
        [4, 8, 3, 6],
        [5, 4, 4, 6],
        [0, 3, 0, 5]])
# 帅选出大于3的数
In [118]: d[d>3]
Out[118]: tensor([4, 8, 6, 5, 4, 4, 6, 5])

In [119]: d
Out[119]: 
tensor([[3, 1, 2, 2],
        [4, 8, 3, 6],
        [5, 4, 4, 6],
        [0, 3, 0, 5]])
# 非0元素的下标
In [120]: torch.nonzero(d)
Out[120]: 
tensor([[0, 0],
        [0, 1],
        [0, 2],
        [0, 3],
        [1, 0],
        [1, 1],
        [1, 2],
        [1, 3],
        [2, 0],
        [2, 1],
        [2, 2],
        [2, 3],
        [3, 1],
        [3, 3]])
7. 矩阵的行列式
In [127]: a
Out[127]: 
tensor([[1, 2],
        [3, 4]])

In [128]: a = a.float()

In [129]: a
Out[129]: 
tensor([[1., 2.],
        [3., 4.]])
# a必须为浮点型,否则会报错
In [130]: torch.det(a)
Out[130]: tensor(-2.0000)
    
In [132]: d
Out[132]: 
tensor([[3, 1, 2, 2],
        [4, 8, 3, 6],
        [5, 4, 4, 6],
        [0, 3, 0, 5]])

In [133]: torch.det(d.float())
Out[133]: tensor(43.0000)
8. 矩阵的逆和伪逆

矩阵的逆

In [134]: a
Out[134]: 
tensor([[1., 2.],
        [3., 4.]])
# 矩阵的逆
In [135]: torch.inverse(a)
Out[135]: 
tensor([[-2.0000,  1.0000],
        [ 1.5000, -0.5000]])

注意:矩阵不满秩,则会报错

矩阵的伪逆

In [143]: e = e.double()
# 最好使用float64,
In [144]: e
Out[144]: 
tensor([[3., 3., 3.],
        [3., 3., 3.],
        [3., 3., 3.]], dtype=torch.float64)
# 伪逆
In [145]: torch.pinverse(e)
Out[145]: 
tensor([[0.0370, 0.0370, 0.0370],
        [0.0370, 0.0370, 0.0370],
        [0.0370, 0.0370, 0.0370]], dtype=torch.float64)

In [146]: f = torch.ones((4,4),dtype=torch.float64)+3

In [147]: f
Out[147]: 
tensor([[4., 4., 4., 4.],
        [4., 4., 4., 4.],
        [4., 4., 4., 4.],
        [4., 4., 4., 4.]], dtype=torch.float64)

In [148]: torch.pinverse(f)
Out[148]: 
tensor([[0.0156, 0.0156, 0.0156, 0.0156],
        [0.0156, 0.0156, 0.0156, 0.0156],
        [0.0156, 0.0156, 0.0156, 0.0156],
        [0.0156, 0.0156, 0.0156, 0.0156]], dtype=torch.float64)
9. 矩阵的对称
In [149]: a
Out[149]: 
tensor([[1., 2.],
        [3., 4.]])

In [150]: a*a.T
Out[150]: 
tensor([[ 1.,  6.],
        [ 6., 16.]])
10. 矩阵的秩、迹

矩阵的秩

In [151]: a
Out[151]: 
tensor([[1., 2.],
        [3., 4.]])
# 秩
In [152]: torch.matrix_rank(a)
Out[152]: tensor(2)

In [153]: e
Out[153]: 
tensor([[3., 3., 3.],
        [3., 3., 3.],
        [3., 3., 3.]], dtype=torch.float64)

In [154]: torch.matrix_rank(e)
Out[154]: tensor(1)

矩阵的迹

In [156]: a
Out[156]: 
tensor([[1., 2.],
        [3., 4.]])
# 迹
In [157]: torch.trace(a)
Out[157]: tensor(5.)

In [158]: b
Out[158]: 
tensor([[0, 1, 2],
        [3, 4, 5]])

In [159]: torch.trace(b)
Out[159]: tensor(4)
11. 矩阵求解

可逆矩阵的求解
A X = B AX=B

In [174]: A = torch.randint(0,10,(4,4),dtype=torch.float64)

In [175]: A
Out[175]: 
tensor([[1., 0., 9., 1.],
        [8., 5., 5., 6.],
        [9., 1., 0., 4.],
        [2., 0., 4., 0.]], dtype=torch.float64)

In [177]: B = torch.tensor([[1,10,0,1]],dtype=torch.float64)

In [178]: B
Out[178]: tensor([[ 1., 10.,  0.,  1.]], dtype=torch.float64)
# 求解
In [180]: (X,LU) = torch.solve(B.T,A)

In [181]: X
Out[181]: 
tensor([[ 0.0989],
        [ 2.7260],
        [ 0.2006],
        [-0.9040]], dtype=torch.float64)
# 验证
In [182]: torch.mm(A,X)
Out[182]: 
tensor([[ 1.0000],
        [10.0000],
        [ 0.0000],
        [ 1.0000]], dtype=torch.float64)

12. 矩阵的特征值与特征向量(EVD)

矩阵的特征向量和特征值:
A v = λ v Av=\lambda v
这里 A A 是实对称矩阵, v v 是特征向量, λ \lambda 是特征值。下面我们使用Pytorch求取矩阵的特征值和特征向量。

In [200]: A = torch.tensor([[-1,1,0],[-4,3,0],[1,0,2]],dtype=torch.float64) 
# 求解特征值与特征向量
In [205]: (evals,evecs) = torch.eig(A,eigenvectors=True)
# 特征值
In [206]: evals
Out[206]: 
tensor([[2., 0.],
        [1., 0.],
        [1., 0.]], dtype=torch.float64)
# 特征向量
In [207]: evecs
Out[207]: 
tensor([[ 0.0000,  0.4082,  0.4082],
        [ 0.0000,  0.8165,  0.8165],
        [ 1.0000, -0.4082, -0.4082]], dtype=torch.float64)
发布了82 篇原创文章 · 获赞 39 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_28368377/article/details/105052039