torch中的矩阵乘法与广播机制

这篇具有很好参考价值的文章主要介绍了torch中的矩阵乘法与广播机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 广播机制 broadcast

1. 两个张量“可广播”规则:

  • 每个张量至少有一个维度。

  • 当迭代维度大小时,从最后一个维度开始,满足以下条件:(1)维度大小相等,(2)其中一个维度为1,(3)或者其中一个维度不存在。

举例:

x=torch.empty((0,))
y=torch.empty(2,2)
# x,y不可广播,因为x至少没有一个维度


x=torch.empty(5,7,3)
y=torch.empty(5,7,3)
# 相同的形状总是可广播的


x=torch.empty(5,3,4,1)
y=torch.empty(  3,1,1)
# 第一个尾维度:大小都为1
# 第二个尾维度:y的大小为1
# 第三个尾维度:x的大小== y的大小
# 第四个尾维度,y维不存在
# 满足可广播规则,因此X和y是可广播的。

x=torch.empty(5,2,4,1)
y=torch.empty(  3,1,1)
# x和y是不可广播的,因为在第三个尾维度中2 != 3

2. 可广播张量计算规则:

如果两个张量可以广播,则得到的张量大小计算如下:

  • 如果x和y的维数不相等,在维数较少的张量的维数前加上1,使它们长度相等。

  • 对于每个维度大小,生成的维度大小是该维度上x和y大小的最大值。

举例:

>>> x=torch.empty(5,1,4,1)
>>> y=torch.empty(  3,1,1)
>>> (x+y).size()
torch.Size([5, 3, 4, 1])


>>> x=torch.empty(1)
>>> y=torch.empty(3,1,7)
>>> (x+y).size()
torch.Size([3, 1, 7])

>>> x=torch.empty(5,2,4,1)
>>> y=torch.empty(3,1,1)
>>> (x+y).size()
RuntimeError: The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1

注意1:原地操作不允许原地张量因广播而改变形状。 

>>> x=torch.empty(5,3,4,1)
>>> y=torch.empty(3,1,1)
>>> (x.add_(y)).size()
torch.Size([5, 3, 4, 1])

# but:
>>> x=torch.empty(1,3,1)
>>> y=torch.empty(3,1,7)
>>> (x.add_(y)).size() # in_place
RuntimeError: The expanded size of the tensor (1) must match the existing size (7) at non-singleton dimension 2.

>>> (x+y).size()
torch.Size([3,3,7])

注意2:在两个张量没有相同形状,但可广播且具有相同数量的元素的情况下,广播的引入可能导致向后不兼容的变化。 

以前会产生一个大小为torch.Size([4,1])的张量,但现在产生一个大小为torch.Size([4,4])的张量。为了帮助识别代码中可能存在广播引入的向后不兼容的情况,可以设置torch.utils.backcompat_broadcast_warning。enabled为True,在这种情况下将生成python警告。

>>> torch.utils.backcompat.broadcast_warning.enabled=True
>>> torch.add(torch.ones(4,1), torch.ones(4))
__main__:1: UserWarning: self and other do not have the same shape, but are broadcastable, and have the same number of elements.
Changing behavior in a backwards incompatible manner to broadcasting rather than viewing as 1-dimensional.

二. torch的各种乘法操作 

1. torch.dot(vec1,vec2)

         用来计算两个向量的点积,不支持broadcast操作,要求两个一维张量的元素个数相同。

 

import torch

vec1 = torch.Tensor([1,2,3,4])
vec2 = torch.Tensor([5,6,7,8])
print(torch.dot(vec1, vec2))
# tensor(70.)

2. torch.mm(mat1,mat2)

        用来计算两个二维矩阵的矩阵乘法,不支持broadcast操作,要求两个Tensor的维度满足矩阵乘法的要求。

mat1 = torch.randn(3, 4)
mat2 = torch.randn(4, 5)
out = torch.mm(mat1, mat2)
print(out.shape)
# torch.Size([3, 5])

3. torch.bmm(mat1,mat2)

        用来计算两个三维带Batch矩阵乘法,不支持broadcast操作,要求该函数的两个输入必须是三维矩阵且第一维相同(表示Batch维度)。

mat1 = torch.randn(2, 3, 4)
mat2 = torch.randn(2, 4, 5)
out = torch.bmm(mat1, mat2)
print(out.shape)
# torch.Size([2, 3, 5])

4. torch.mv(mat,vec) 

        用于计算矩阵和向量之间的乘法(矩阵在前,向量在后),不支持broadcast操作,要求矩阵与向量满足矩阵乘法的要求。

 

mat = torch.randn(3, 4)
vec = torch.randn(4)
output = torch.mv(mat, vec)
print(output.shape)
# torch.Size([3])

5. torch.mul(a,b)

        troch.multiply()等同于torch.mul();

        用于计算矩阵逐元素(Element-wise)乘法(点乘),支持broadcast操作,只要a,b的维度满足broadcast条件,就可以进行逐元素乘法操作。

A = torch.randn(2,1,4)
B = torch.randn(3, 1) # 矩阵
print(torch.mul(A,B).shape)
# torch.Size([2, 3, 4])
b0 = 2 # 标量
print(torch.mul(A,b0).shape)
# torch.Size([2, 1, 4])
b1 = torch.tensor([1,2,3,4]) # 行向量
print(torch.mul(A,b1).shape)
# torch.Size([2, 1, 4])
b2 = torch.Tensor([1,2,3]).reshape(-1,1) # 列向量
print(torch.mul(A,b2).shape)
# torch.Size([2, 3, 4])

6. torch.matmul(mat1,mat2)

        几乎可用于计算所有矩阵/向量相乘的情况,支持broadcast操作,可以理解为torch.mm的broadcast版本,其乘法规则视参与乘法的两个张量的维度而定。

        特别的,针对多维数据 matmul()乘法,可以认为该 matmul()乘法使用两个参数的后两个维度来计算,其他的维度都可以认为是batch维度。

mat1 = torch.randn(2,1,4,5)
mat2 = torch.randn(2,1,5,2)
out = torch.matmul(mat1, mat2)
print(out.shape)
# torch.Size([2, 1, 4, 2])

若两个矩阵是一维的,那么该函数的功能与torch.dot()一样,返回两个一维tensor的点乘结果;

vec1 = torch.Tensor([1,2,3,4])
vec2 = torch.Tensor([5,6,7,8])
print(torch.matmul(vec1, vec2))
# tensor(70.)
print(torch.dot(vec1, vec2))
# tensor(70.)

若两个矩阵是二维的,那么该函数的功能与torch.mm()一样,返回两个二维矩阵的矩阵乘法;

mat1 = torch.randn(3, 4)
mat2 = torch.randn(4, 5)
out = torch.mm(mat1, mat2)
print(out.shape)
# torch.Size([3, 5])

out1 = torch.matmul(mat1, mat2)
print(out1.shape)
# torch.Size([3, 5])

若第一个参数是二维张量(矩阵),第二个参数是一维张量(向量),那么将返回矩阵×向量的积。那么该函数的功能与torch.mv()一样,要求矩阵和向量满足矩阵乘法的要求;

mat = torch.randn(3, 4)
vec = torch.randn(4)
output = torch.mv(mat, vec)
print(output.shape)
# torch.Size([3])

output1 = torch.matmul(mat, vec)
print(output1.shape)
# torch.Size([3])

若第一个参数是一维张量,第二个参数是二维张量,那么在一维张量的前面增加一个维度(broadcast),然后进行矩阵乘法;

vec = torch.randn(4)
mat = torch.randn(4,2)
print(torch.matmul(vec, mat).shape)
# torch.Size([2])

7. 运算符

@  运算符 : 其作用类似于torch.matmul。

mat1 = torch.randn(2,1,4,5)
mat2 = torch.randn(2,1,5,2)
out = torch.matmul(mat1, mat2)
print(out.shape)
# torch.Size([2, 1, 4, 2])
out1 = mat1 @ mat2
print(out1.shape)
# torch.Size([2, 1, 4, 2])

 *   运算符 :   其作用类似于torch.mul。

A = torch.randn(2,1,4)
B = torch.randn(3, 1) # 矩阵
print(torch.mul(A,B).shape)
# torch.Size([2, 3, 4])

print((A * B).shape)
# torch.Size([2, 3, 4])

8.扩展:torch.einsum():爱因斯坦求和约定

放个链接: einsum is all you need!

        如果你像我一样,发现记住PyTorch/TensorFlow中那些计算点积、外积、转置、矩阵-向量乘法、矩阵-矩阵乘法的函数名字和签名很费劲,那么einsum记法就是我们的救星。einsum记法是一个表达以上这些运算,包括复杂张量运算在内的优雅方式,基本上,可以把einsum看成一种领域特定语言。一旦你理解并能利用einsum,除了不用记忆和频繁查找特定库函数这个好处以外,你还能够更迅速地编写更加紧凑、高效的代码。而不使用einsum的时候,容易出现引入不必要的张量变形或转置运算,以及可以省略的中间张量的现象。

仅为学习记录!文章来源地址https://www.toymoban.com/news/detail-463247.html

到了这里,关于torch中的矩阵乘法与广播机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python中@运算符和*运算符在矩阵乘法中的区别与作用

      我们在看python程序时,经常可以看到@运算符和*运算符,其中@运算符在传统python中通常是作为装饰器使用的。但是在Python 3.5之后,它又具备了矩阵乘法运算的功能。下面使用示例来对比这两个运算符对矩阵运算的影响:   导入用到numpy包:   创建一个维度为2×3×3的

    2024年02月12日
    浏览(47)
  • 【矩阵乘法】C++实现外部矩阵乘法

    ​ 使用文件和内存模拟系统缓存,并利用矩阵乘法验证实际和理论情况。 设计一个 Matrix 类,其中 Matrix 是存在磁盘中的一个二进制文件,类通过保存的矩阵属性来读取磁盘。前八个字节为两个 int32 ,保存矩阵的行列数。 Matrix中有一个 buffer 成员为读取到的数据缓存,通过

    2024年02月11日
    浏览(39)
  • [Pytorch]Broadcasting广播机制

    Broadcasting机制用于在不同维度的张量进行运算时进行维度的自动增加与扩展,Broadcasting机制使用的前提是两个参与运算的张量是可broadcastable的。 怎样的两个向量是Broadcastable的,也就是可使用Broadcasting机制的? 规定右边的维度为小维度,即shape(2,32,13,13)中右边的13为最小的维

    2024年02月11日
    浏览(36)
  • CH7-广播机制

    熟悉 广播机制的概述 ,能够归纳广播机制的实现流程 掌握 广播接收者的创建方式 ,能够独立创建广播接收者 掌握 自定义广播的方式 ,能够通过自定义广播实现饭堂小广播案例 熟悉 广播的类型 ,能够归纳 有序广播 与 无序广播 的工作流程 ​ 在Android系统中, 广播是一种

    2024年02月05日
    浏览(28)
  • python矩阵乘法全面解读,python矩阵乘法常用代码

      矩阵乘法,顾名思义是矩阵的乘法,矩阵相乘的含义是两个向量的积,在 Python中一般以乘号或括号表示。与常用的加、减、乘、除运算不同,矩阵乘法只能用于对给定矩阵进行乘法运算,不能进行除法运算。若要计算矩阵乘法的值,必须先进行矩阵分解。 在上一篇文章中

    2024年02月08日
    浏览(43)
  • 矩阵乘法(矩阵乘矩阵)

    首先理了解矩阵是什么: 矩阵是一个按照长方阵列排列的复数或实数集合。(相信大家都懂) 关于矩阵的基本概念: 1.方阵:n 阶方阵 (正方形嘛) 2.同型矩阵:两个矩阵,行数与列数对应相同,称为同型矩阵 矩阵加减法: 在了解矩阵乘法前先看看矩阵加减法: 1.两个矩阵

    2024年02月08日
    浏览(59)
  • 深度学习·理论篇(2023版)·第002篇深度学习和计算机视觉中的基础数学知识01:线性变换的定义+基于角度的线性变换案例(坐标变换)+点积和投影+矩阵乘法的几何意义+图形化精讲

    💕 恭喜本博客浏览量达到两百万,CSDN内容合伙人,CSDN人工智能领域实力新星~ 🧡 本文章为2021版本迭代更新版本,在结合有效知识的基础上对文章进行合理的增加,使得整个文章时刻顺应时代需要 🧡 本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理

    2023年04月08日
    浏览(56)
  • 矩阵算法之矩阵乘法

    矩阵算法在图像处理、神经网络、模式识别等领域有着广泛的用途。 在矩阵乘法中,A矩阵和B矩阵可以做乘法运算必须满足A矩阵的列的数量等于B矩阵的行的数量。 运算规则:A的每一行中的数字对应乘以B的每一列的数字把结果相加起来。 1、当矩阵A的列数(column)等于矩阵

    2024年02月11日
    浏览(40)
  • 【数据分析之道-NumPy(四)】numpy广播机制

    ✍ 作者简介: i阿极 ,CSDN Python领域新星创作者, 专注于分享python领域知识。 ✍ 本文录入于《数据分析之道》 ,本专栏针对大学生、初级数据分析工程师精心打造,对python基础知识点逐一击破,不断学习,提升自我。 ✍ 订阅后,可以阅读《数据分析之道》中全部文章内容

    2023年04月19日
    浏览(49)
  • 7.物联网LWIP之DNS,超时机制,组播,广播

    一。DNS域名解析 1.DNS作用       DNS是计算机域名系统(Domain Name System 或 Domain Name Service)的缩写,它是由解析器和域名服务器组成的,作用是把域名转换成为网络可以识别的ip地址。举一个简单的例子,域名相当于门牌号,而IP地址相当于具体的地理位置。       DNS是用来做

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包