也就是PyTorch中BLAS和LAPACK模块的相关运算。

  PyTorch中并未设置单独的矩阵对象类型,因此PyTorch中,二维张量就相当于矩阵对象,并且拥有一系列线性代数相关函数和方法。
  在实际机器学习和深度学习建模过程中,矩阵或者高维张量都是基本对象类型,而矩阵所涉及到的线性代数理论也是深度学习用户必备的基本数学基础。因此,本节在介绍张量的线性代数运算时,也会回顾基本的矩阵运算,及其基本线性代数的数学理论基础,以期在强化张量的线性代数运算过程中,也进一步夯实同学的线性代数数学基础。
  另外,在实际的深度学习建模过程中,往往会涉及矩阵的集合,也就是三维甚至是四维张量的计算,因此在部分场景中,我们也将把二维张量计算拓展到更高维的张量计算。

import torch
import numpy as np

一、BLAS和LAPACK概览

  BLAS(Basic Linear Algeria Subprograms)和LAPACK(Linear Algeria Package)模块提供了完整的线性代数基本方法,由于涉及到函数种类较多,因此此处对其进行简单分类,具体包括:

  • 矩阵的形变及特殊矩阵的构造方法:包括矩阵的转置、对角矩阵的创建、单位矩阵的创建、上/下三角矩阵的创建等;
  • 矩阵的基本运算:包括矩阵乘法、向量内积、矩阵和向量的乘法等,当然,此处还包含了高维张量的基本运算,将着重探讨矩阵的基本运算拓展至三维张量中的基本方法;
  • 矩阵的线性代数运算:包括矩阵的迹、矩阵的秩、逆矩阵的求解、伴随矩阵和广义逆矩阵等;
  • 矩阵分解运算:特征分解、奇异值分解和SVD分解等。

相关内容如果涉及数学基础,将在讲解过程中逐步补充。

二、矩阵的形变及特殊矩阵构造方法

  矩阵的形变方法其实也就是二维张量的形变方法,在此基础上本节将补充转置的基本方法。另外,在实际线性代数运算过程中,经常涉及一些特殊矩阵,如单位矩阵、对角矩阵等,相关创建方法如下:

# 创建一个2*3的矩阵
t1 = torch.arange(1, 7).reshape(2, 3).float()
t1
#tensor([[1., 2., 3.],
#        [4., 5., 6.]])# 转置
torch.t(t1)
#tensor([[1., 4.],
#        [2., 5.],
#        [3., 6.]])t1.t()
#tensor([[1., 4.],
#        [2., 5.],
#        [3., 6.]])

矩阵的转置就是每个元素行列位置互换

torch.eye(3)
#tensor([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])t = torch.arange(5)
t
#tensor([0, 1, 2, 3, 4])torch.diag(t)
#tensor([[0, 0, 0, 0, 0],
#        [0, 1, 0, 0, 0],
#        [0, 0, 2, 0, 0],
#        [0, 0, 0, 3, 0],
#        [0, 0, 0, 0, 4]])# 对角线向上偏移一位
torch.diag(t, 1)
#tensor([[0, 0, 0, 0, 0, 0],
#        [0, 0, 1, 0, 0, 0],
#        [0, 0, 0, 2, 0, 0],
#        [0, 0, 0, 0, 3, 0],
#        [0, 0, 0, 0, 0, 4],
#        [0, 0, 0, 0, 0, 0]])# 对角线向下偏移一位
torch.diag(t, -1)
#tensor([[0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 1, 0, 0, 0, 0],
#        [0, 0, 2, 0, 0, 0],
#        [0, 0, 0, 3, 0, 0],
#        [0, 0, 0, 0, 4, 0]])t1 = torch.arange(9).reshape(3, 3)
t1
#tensor([[0, 1, 2],
#        [3, 4, 5],
#        [6, 7, 8]])# 取上三角矩阵
torch.triu(t1)
#tensor([[0, 1, 2],
#        [0, 4, 5],
#        [0, 0, 8]])# 上三角矩阵向左下偏移一位
torch.triu(t1, -1)
#tensor([[0, 1, 2],
#        [3, 4, 5],
#        [0, 7, 8]])# 上三角矩阵向右上偏移一位
torch.triu(t1, 1)
#tensor([[0, 1, 2],
#        [0, 0, 5],
#        [0, 0, 0]])# 下三角矩阵
torch.tril(t1)
#tensor([[0, 0, 0],
#        [3, 4, 0],
#        [6, 7, 8]])

三、矩阵的基本运算

  矩阵不同于普通的二维数组,其具备一定的线性代数含义,而这些特殊的性质,其实就主要体现在矩阵的基本运算上。课程中常见的矩阵基本运算如下所示:

矩阵的基本运算

  • dot\vdot:点积计算

注意,在PyTorch中,dot和vdot只能作用于一维张量,且对于数值型对象,二者计算结果并没有区别,两种函数只在进行复数运算时会有区别。更多复数运算的规则,我们将在涉及复数运算的场景中再进行详细说明。

t = torch.arange(1, 4)
t
#tensor([1, 2, 3])torch.dot(t, t)
#tensor(14)torch.vdot(t, t)
#tensor(14)# 不能进行除了一维张量以外的计算
torch.dot(t1, t1)
'''---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-38-5eafa2b4bbd3> in <module>1 # 不能进行除了一维张量以外的计算
----> 2 torch.dot(t1, t1)RuntimeError: 1D tensors expected, but got 2D and 2D tensors'''
  • mm:矩阵乘法

  再PyTorch中,矩阵乘法其实是一个函数簇,除了矩阵乘法以外,还有批量矩阵乘法、矩阵相乘相加、批量矩阵相乘相加等等函数。

t1 = torch.arange(1, 7).reshape(2, 3)
t1
#tensor([[1, 2, 3],
#        [4, 5, 6]])t2 = torch.arange(1, 10).reshape(3, 3)
t2
#tensor([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])# 对应位置元素相乘
t1 * t1
#tensor([[ 1,  4,  9],
#        [16, 25, 36]])# 矩阵乘法
torch.mm(t1, t2)
#tensor([[30, 36, 42],
#        [66, 81, 96]])

矩阵乘法执行过程如下所示:

  • mv:矩阵和向量相乘

PyTorch中提供了一类非常特殊的矩阵和向量相乘的函数,矩阵和向量相乘的过程我们可以看成是先将向量转化为列向量然后再相乘。

met = torch.arange(1, 7).reshape(2, 3)
met
#tensor([[1, 2, 3],
#        [4, 5, 6]])vec = torch.arange(1, 4)
vec
#tensor([1, 2, 3])'''在实际执行向量和矩阵相乘的过程中,需要矩阵的列数和向量的元素个数相同'''
torch.mv(met, vec)
#tensor([14, 32])vec.reshape(3, 1)             # 转化为列向量
#tensor([[1],
#        [2],
#        [3]])torch.mm(met, vec.reshape(3, 1))
#tensor([[14],
#        [32]])torch.mm(met, vec.reshape(3, 1)).flatten()
#tensor([14, 32])

        理解:mv函数本质上提供了一种二维张量和一维张量相乘的方法,在线性代数运算过程中,有很多矩阵乘向量的场景,典型的如线性回归的求解过程,通常情况下我们需要将向量转化为列向量(或者某些编程语言就默认向量都是列向量)然后进行计算,但PyTorch中单独设置了一个矩阵和向量相乘的方法,从而简化了行/列向量的理解过程和将向量转化为列向量的转化过程。

  • bmm:批量矩阵相乘

  所谓批量矩阵相乘,指的是三维张量的矩阵乘法。根据此前对张量结构的理解,我们知道,三维张量就是一个包含了多个相同形状的矩阵的集合。例如,一个(3, 2, 2)的张量,本质上就是一个包含了3个2*2矩阵的张量。而三维张量的矩阵相乘,则是三维张量内部各对应位置的矩阵相乘。由于张量的运算往往涉及二维及以上,因此批量矩阵相乘也有非常多的应用场景。

t3 = torch.arange(1, 13).reshape(3, 2, 2)
t3
#tensor([[[ 1,  2],
#         [ 3,  4]],
#
#        [[ 5,  6],
#         [ 7,  8]],
#
#        [[ 9, 10],
#         [11, 12]]])t4 = torch.arange(1, 19).reshape(3, 2, 3)
t4
#tensor([[[ 1,  2,  3],
#         [ 4,  5,  6]],
#
#        [[ 7,  8,  9],
#         [10, 11, 12]],
#
#        [[13, 14, 15],
#         [16, 17, 18]]])torch.bmm(t3, t4)
#tensor([[[  9,  12,  15],
#         [ 19,  26,  33]],
#
#        [[ 95, 106, 117],
#         [129, 144, 159]],
#
#        [[277, 296, 315],
#         [335, 358, 381]]])
''''1234左乘123456......'''

Point:

  • 三维张量包含的矩阵个数需要相同;
  • 每个内部矩阵,需要满足矩阵乘法的条件,也就是左乘矩阵的行数要等于右乘矩阵的列数。
  • addmm:矩阵相乘后相加

addmm函数结构:addmm(input, mat1, mat2, beta=1, alpha=1)
输出结果:beta * input + alpha * (mat1 * mat2)

t1
#tensor([[1, 2, 3],
#        [4, 5, 6]])t2
#tensor([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])t = torch.arange(3)
t
#tensor([0, 1, 2])torch.mm(t1, t2)                    # 矩阵乘法
#tensor([[30, 36, 42],
#        [66, 81, 96]])torch.addmm(t, t1, t2)              # 先乘法后相加
#tensor([[30, 37, 44],
#        [66, 82, 98]])torch.addmm(t, t1, t2, beta = 0, alpha = 10)
#tensor([[300, 360, 420],
#        [660, 810, 960]])
  • addbmm:批量矩阵相乘后相加

  和addmm类似,都是先乘后加,并且可以设置权重。不同的是addbmm是批量矩阵相乘,并且,在相加的过程中也是矩阵相加,而非向量加矩阵。

t = torch.arange(6).reshape(2, 3)
t
#tensor([[0, 1, 2],
#        [3, 4, 5]])t3
#tensor([[[ 1,  2],
#         [ 3,  4]],
#
#        [[ 5,  6],
#         [ 7,  8]],
#
#        [[ 9, 10],
#         [11, 12]]])t4
#tensor([[[ 1,  2,  3],
#         [ 4,  5,  6]],
#
#        [[ 7,  8,  9],
#         [10, 11, 12]],
#
#        [[13, 14, 15],
#         [16, 17, 18]]])torch.bmm(t3, t4)
#tensor([[[  9,  12,  15],
#         [ 19,  26,  33]],
#
#        [[ 95, 106, 117],
#         [129, 144, 159]],
#
#        [[277, 296, 315],
#         [335, 358, 381]]])torch.addbmm(t, t3, t4)
#tensor([[381, 415, 449],
#        [486, 532, 578]])
#        12+106+296+1 = 415

注:addbmm会在原来三维张量基础之上,对其内部矩阵进行求和

四、矩阵的线性代数运算

  如果说矩阵的基本运算是矩阵基本性质,那么矩阵的线性代数运算,则是我们利用矩阵数据类型在求解实际问题过程中经常涉及到的线性代数方法,具体相关函数如下:

矩阵的线性代数运算

同时,由于线性代数所涉及的数学基础知识较多,从实际应用的角度出发,我们将有所侧重的介绍实际应用过程中需要掌握的相关内容,并通过本节末尾的实际案例,来加深线性代数相关内容的理解。

1.矩阵的迹(trace)

  矩阵的迹的运算相对简单,就是矩阵对角线元素之和,在PyTorch中,可以使用trace函数进行计算。

A = torch.tensor([[1, 2], [4, 5]]).float()
A
#tensor([[1., 2.],
#        [4., 5.]])torch.trace(A)
#tensor(6.)'''当然,对于矩阵的迹来说,计算过程不需要是方阵'''
B = torch.arange(1, 7).reshape(2, 3)
B
#tensor([[1, 2, 3],
#        [4, 5, 6]])torch.trace(B)
#tensor(6)

2.矩阵的秩(rank)

  矩阵的秩(rank),是指矩阵中行或列的极大线性无关数,且矩阵中行、列极大无关数总是相同的,任何矩阵的秩都是唯一值,满秩指的是方阵(行数和列数相同的矩阵)中行数、列数和秩相同,满秩矩阵有线性唯一解等重要特性,而其他矩阵也能通过求解秩来降维,同时,秩也是奇异值分解等运算中涉及到的重要概念。

  • matrix_rank计算矩阵的秩
A = torch.arange(1, 5).reshape(2, 2).float()
A
#tensor([[1., 2.],
#        [3., 4.]])torch.matrix_rank(A)
#tensor(2)B = torch.tensor([[1, 2], [2, 4]]).float()
B
#tensor([[1., 2.],
#        [2., 4.]])'''对于矩阵B来说,第一列和第二列明显线性相关,最大线性无关组只有1组,因此矩阵的秩计算结果为1'''
torch.matrix_rank(B)
#tensor(1)

3.矩阵的行列式(det)

  所谓行列式,我们可以简单将其理解为矩阵的一个基本性质或者属性,通过行列式的计算,我们能够知道矩阵是否可逆,从而可以进一步求解矩阵所对应的线性方程。当然,更加专业的解释,行列式的作为一个基本数学工具,实际上就是矩阵进行线性变换的伸缩因子。

对于任何一个n维方正,行列式计算过程如下:

更为简单的情况,如果对于一个2*2的矩阵,行列式的计算就是主对角线元素之积减去另外两个元素之积

A = torch.tensor([[1, 2], [4, 5]]).float()     # 秩的计算要求浮点型张量
A
#tensor([[1., 2.],
#        [4., 5.]])torch.det(A)
#tensor(-3.)B
#tensor([[1., 2.],
#        [2., 4.]])torch.det(B)
#tensor(-0.)

A的行列式计算过程如下:

对于行列式的计算,要求二维张量必须是方正,也就是行列数必须一致。

B = torch.arange(1, 7).reshape(2, 3)
B
#tensor([[1, 2, 3],
#        [4, 5, 6]])torch.det(B)
#---------------------------------------------------------------------------
#RuntimeError                              Traceback (most recent call last)
#<ipython-input-5-beff1455abd9> in <module>
#----> 1 torch.det(B)
#
#RuntimeError: A must be batches of square matrices, but they are 3 by 2 matrices

3.线性方程组的矩阵表达形式

  在正式进入到更进一步矩阵运算的讨论之前,我们需要对矩阵建立一个更加形象化的理解。通常来说,我们会把高维空间中的一个个数看成是向量,而由这些向量组成的数组看成是一个矩阵。例如:(1,2),(3,4)是二维空间中的两个点,矩阵A就代表这两个点所组成的矩阵。

A = torch.arange(1, 5).reshape(2, 2).float()
A
#tensor([[1., 2.],
#        [3., 4.]])import matplotlib as mpl
import matplotlib.pyplot as plt
# 绘制点图查看两个点的位置
plt.plot(A[:,0], A[:, 1], 'o')

结果:

如果更进一步,我们希望在二维空间中找到一条直线,来拟合这两个点,也就是所谓的构建一个线性回归模型,我们可以设置线性回归方程如下:

带入(1,2)和(3,4)两个点之后,我们还可以进一步将表达式改写成矩阵表示形式,改写过程如下

而用矩阵表示线性方程组,则是矩阵的另一种常用用途,接下来,我们就可以通过上述矩阵方程组来求解系数向量x。

  首先一个基本思路是,如果有个和A矩阵相关的另一个矩阵,假设为

Lesson 4.张量的线性代数运算相关推荐

  1. Lesson 3.张量的广播和科学运算

    数学运算与算子   作为PyTorch中执行深度学习的基本数据类型,张量(Tensor)也拥有非常多的数学运算函数和方法,以及对应的一系列计算规则.在PyTorch中,能够作用与Tensor的运算,被 ...

  2. scipy.linalg.norm 线性代数运算 API

    线性代数运算 API https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.norm.html

  3. python3 矩阵运算_3.10 矩阵与线性代数运算

    ## 问题 你需要执行矩阵和线性代数运算,比如矩阵乘法.寻找行列式.求解线性方程组等等. ## 解决方案 NumPy库有一个矩阵对象可以用来解决这个问题.矩阵类似于3.9小节中数组对象,但是遵循线性代 ...

  4. 《Python Cookbook 3rd》笔记(3.10):矩阵与线性代数运算

    矩阵与线性代数运算 问题 你需要执行矩阵和线性代数运算,比如矩阵乘法.寻找行列式.求解线性方程组等等. 解法 NumPy 库有一个矩阵对象可以用来解决这个问题. 矩阵类似于 3.9 小节中数组对象,但 ...

  5. 3.10矩阵与线性代数运算

    问题: ​ 你需要执行矩阵和线性代数运算,比如矩阵乘法.寻找行列式.求解线性方程组等等. 解决方案: ​ Numpy库有一个矩阵对象可以用来解决这个问题. ​ 矩阵类似于3.9小节中数组对象,但是遵循 ...

  6. Lesson 2.张量的索引、分片、合并以及维度调整

    张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和Python原生的列表.NumPy中的数组基本一致,当然,所有不同的是,PyTorch中还定义了一种采用函数来进行索引的方式. 而作为Py ...

  7. 3-17Pytorch与线性代数运算

    二范数:欧氏距离 核范数:低秩问题的求解 计算机技术中有一种特点,图像有一种区域性,反应到数据上就是有相关性 范数作用:定义loss,参数约束 import torch a = torch.rand( ...

  8. Lesson 5.基本优化思想与最小二乘法

      在正式开始进行神经网络建模之前,我们还需要掌握一些基本数学工具,在PyTorch中,最核心的基础数学工具就是梯度计算工具,也就是PyTorch的AutoGrad(自动微分)模块.虽然对于任何一个通 ...

  9. 干货丨深度学习初学者必读:究竟什么是张量?

    今天很多现有的深度学习系统都是基于张量代数(tensor algebra)而设计的,但是张量代数不仅仅只能用于深度学习.本文对张量进行了详细的解读,能帮你在对张量的理解上更进一步.本文作者为 MapR ...

最新文章

  1. 面试题之发散思维能力:如何用非常规方法求1+2+···+n
  2. chrom浏览器-F2使用方法一
  3. Python学习笔记——glob模块【文件、路径操作】
  4. shell 查看磁盘和当前文件夹所有大小
  5. 59、crontab用法简介
  6. 不同设备屏幕尺寸和DPR适配
  7. python gui入门的例子_Python GUI编程之Tkinter入门之道
  8. C语言中用链表构建栈讲解,C语言数据结构之使用链表模拟栈的实例
  9. Millumin for Mac视频实时编辑软件
  10. 漫画:什么是二叉堆?
  11. 编译好的C一执行就崩溃,第一句输出都没有,是怎么回事?
  12. python列表的内置方法_python 基础之列表切片内置方法
  13. js html json 压缩工具,JS格式化/压缩JSON数据
  14. MAC删除自带ABC输入法
  15. TianMao订单数据分析
  16. 用java输入学生姓名查询成绩_java实现学生成绩录入系统
  17. 无线数据包的破解——跑包
  18. 常识——server-u显示无法访问网页
  19. LaTeX设置图片左对齐
  20. proe5.0启动失败,光标转了几圈后没有任何反应

热门文章

  1. java rest post list,Java RestTemplate.postForLocation方法代码示例
  2. python什么时候用框架_python时间模块的使用
  3. Qt中的QMainWindow
  4. mysql技术内幕innodb存储引擎——表索引算法和锁_(转)Mysql技术内幕InnoDB存储引擎-表索引算法和锁...
  5. 多元统计分析最短距离法_聚醚多元醇的合成
  6. android纯白背景加灰,Android背景颜色设置为灰色而不是@android:颜色/白色
  7. linux体验服务器,体验Ubuntu做服务器
  8. python2中为什么在进行类定义时最好要加object
  9. sql select
  10. pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换