详解torch.Tensor的4种乘法


Posted in Python onSeptember 03, 2020

torch.Tensor有4种常见的乘法:*, torch.mul, torch.mm, torch.matmul. 本文抛砖引玉,简单叙述一下这4种乘法的区别,具体使用还是要参照官方文档。

点乘

a与b做*乘法,原则是如果a与b的size不同,则以某种方式将a或b进行复制,使得复制后的a和b的size相同,然后再将a和b做element-wise的乘法

下面以*标量和*一维向量为例展示上述过程。

* 标量

Tensor与标量k做*乘法的结果是Tensor的每个元素乘以k(相当于把k复制成与lhs大小相同,元素全为k的Tensor).

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> a * 2
tensor([[2., 2., 2., 2.],
    [2., 2., 2., 2.],
    [2., 2., 2., 2.]])

* 一维向量

Tensor与行向量做*乘法的结果是每列乘以行向量对应列的值(相当于把行向量的行复制,成为与lhs维度相同的Tensor). 注意此时要求Tensor的列数与行向量的列数相等。

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3,4])
>>> b
tensor([1., 2., 3., 4.])
>>> a * b
tensor([[1., 2., 3., 4.],
    [1., 2., 3., 4.],
    [1., 2., 3., 4.]])

Tensor与列向量做*乘法的结果是每行乘以列向量对应行的值(相当于把列向量的列复制,成为与lhs维度相同的Tensor). 注意此时要求Tensor的行数与列向量的行数相等。

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3]).reshape((3,1))
>>> b
tensor([[1.],
    [2.],
    [3.]])
>>> a * b
tensor([[1., 1., 1., 1.],
    [2., 2., 2., 2.],
    [3., 3., 3., 3.]])

* 矩阵

经Arsmart在评论区提醒,增补一个矩阵 * 矩阵的例子,感谢Arsmart的热心评论!
如果两个二维矩阵A与B做点积A * B,则要求A与B的维度完全相同,即A的行数=B的行数,A的列数=B的列数

>>> a = torch.tensor([[1, 2], [2, 3]])
>>> a * a
tensor([[1, 4],
    [4, 9]])

broadcast

点积是broadcast的。broadcast是torch的一个概念,简单理解就是在一定的规则下允许高维Tensor和低维Tensor之间的运算。broadcast的概念稍显复杂,在此不做展开,可以参考官方文档关于broadcast的介绍. 在torch.matmul里会有关于broadcast的应用的一个简单的例子。

这里举一个点积broadcast的例子。在例子中,a是二维Tensor,b是三维Tensor,但是a的维度与b的后两位相同,那么a和b仍然可以做点积,点积结果是一个和b维度一样的三维Tensor,运算规则是:若c = a * b, 则c[i,*,*] = a * b[i, *, *],即沿着b的第0维做二维Tensor点积,或者可以理解为运算前将a沿着b的第0维也进行了expand操作,即a = a.expand(b.size()); a * b

>>> a = torch.tensor([[1, 2], [2, 3]])
>>> b = torch.tensor([[[1,2],[2,3]],[[-1,-2],[-2,-3]]])
>>> a * b
tensor([[[ 1, 4],
     [ 4, 9]],

    [[-1, -4],
     [-4, -9]]])
>>> b * a
tensor([[[ 1, 4],
     [ 4, 9]],

    [[-1, -4],
     [-4, -9]]])

其实,上面提到的二维Tensor点积标量、二维Tensor点积行向量,都是发生在高维向量和低维向量之间的,也可以看作是broadcast.

torch.mul

官方文档关于torch.mul的介绍. 用法与*乘法相同,也是element-wise的乘法,也是支持broadcast的。

下面是几个torch.mul的例子.

乘标量

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> a * 2
tensor([[2., 2., 2., 2.],
    [2., 2., 2., 2.],
    [2., 2., 2., 2.]])

乘行向量

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3,4])
>>> b
tensor([1., 2., 3., 4.])
>>> torch.mul(a, b)
tensor([[1., 2., 3., 4.],
    [1., 2., 3., 4.],
    [1., 2., 3., 4.]])

乘列向量

>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
    [1., 1., 1., 1.],
    [1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3]).reshape((3,1))
>>> b
tensor([[1.],
    [2.],
    [3.]])
>>> torch.mul(a, b)
tensor([[1., 1., 1., 1.],
    [2., 2., 2., 2.],
    [3., 3., 3., 3.]])

乘矩阵

例1:二维矩阵 mul 二维矩阵

>>> a = torch.tensor([[1, 2], [2, 3]])
>>> torch.mul(a,a)
tensor([[1, 4],
    [4, 9]])

例2:二维矩阵 mul 三维矩阵(broadcast)

>>> a = torch.tensor([[1, 2], [2, 3]])
>>> b = torch.tensor([[[1,2],[2,3]],[[-1,-2],[-2,-3]]])
>>> torch.mul(a,b)
tensor([[[ 1, 4],
     [ 4, 9]],

    [[-1, -4],
     [-4, -9]]])

torch.mm

官方文档关于torch.mm的介绍. 数学里的矩阵乘法,要求两个Tensor的维度满足矩阵乘法的要求.

例子:

>>> a = torch.ones(3,4)
>>> b = torch.ones(4,2)
>>> torch.mm(a, b)
tensor([[4., 4.],
    [4., 4.],
    [4., 4.]])

torch.matmul

官方文档关于torch.matmul的介绍. torch.mm的broadcast版本.

例子:

>>> a = torch.ones(3,4)
>>> b = torch.ones(5,4,2)
>>> torch.matmul(a, b)
tensor([[[4., 4.],
     [4., 4.],
     [4., 4.]],

    [[4., 4.],
     [4., 4.],
     [4., 4.]],

    [[4., 4.],
     [4., 4.],
     [4., 4.]],

    [[4., 4.],
     [4., 4.],
     [4., 4.]],

    [[4., 4.],
     [4., 4.],
     [4., 4.]]])

同样的a和b,使用torch.mm相乘会报错

>>> torch.mm(a, b)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
RuntimeError: matrices expected, got 2D, 3D tensors at /pytorch/aten/src/TH/generic/THTensorMath.cpp:2065

到此这篇关于详解torch.Tensor的4种乘法的文章就介绍到这了,更多相关torch.Tensor 乘法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
详细讲解Python中的文件I/O操作
May 24 Python
Python2中的raw_input() 与 input()
Jun 12 Python
python实现下载指定网址所有图片的方法
Aug 08 Python
利用Opencv中Houghline方法实现直线检测
Feb 11 Python
python梯度下降法的简单示例
Aug 31 Python
简单谈谈python基本数据类型
Sep 26 Python
对python中数组的del,remove,pop区别详解
Nov 07 Python
python+selenium实现自动化百度搜索关键词
Jun 03 Python
django使用xadmin的全局配置详解
Nov 15 Python
Python代码一键转Jar包及Java调用Python新姿势
Mar 10 Python
python redis存入字典序列化存储教程
Jul 16 Python
python3通过subprocess模块调用脚本并和脚本交互的操作
Dec 05 Python
详解pytorch tensor和ndarray转换相关总结
Sep 03 #Python
python开发入门——列表生成式
Sep 03 #Python
Pytorch之Tensor和Numpy之间的转换的实现方法
Sep 03 #Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
Sep 03 #Python
Python开发入门——迭代的基本使用
Sep 03 #Python
Python 整行读取文本方法并去掉readlines换行\n操作
Sep 03 #Python
Python多分支if语句的使用
Sep 03 #Python
You might like
利用递归把多维数组转为一维数组的函数
2006/10/09 PHP
php计算2个日期的差值函数分享
2015/02/02 PHP
php带抄送和密件抄送的邮件发送方法
2015/03/20 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
javascript Demo模态窗口
2009/12/06 Javascript
javascript两种function的定义介绍及区别说明
2013/05/02 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
JS增加行复制行删除行的实现代码
2013/11/09 Javascript
jQuery实现的原图对比窗帘效果
2014/06/15 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
JS实现表格数据各种搜索功能的方法
2015/03/03 Javascript
jquery使用经验小结
2015/05/20 Javascript
Struts2+jquery.form.js实现图片与文件上传的方法
2016/05/05 Javascript
很酷的星级评分系统原生JS实现
2016/08/25 Javascript
微信公众平台开发教程(五)详解自定义菜单
2016/12/02 Javascript
JS简单生成由字母数字组合随机字符串示例
2018/05/25 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
JSON.stringify()方法讲解
2019/01/31 Javascript
Vue如何实现验证码输入交互
2020/12/07 Vue.js
JavaScript 中的六种循环方法
2021/01/06 Javascript
Python操作列表之List.insert()方法的使用
2015/05/20 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
Python中的heapq模块源码详析
2019/01/08 Python
pytorch forward两个参数实例
2020/01/17 Python
Python识别验证码的实现示例
2020/09/30 Python
关于python中导入文件到list的问题
2020/10/31 Python
HTML5实现移动端点击翻牌功能
2020/10/23 HTML / CSS
巴西最大的家具及装饰用品店:Mobly
2017/10/11 全球购物
武汉高蓝德国际.net机试
2016/06/24 面试题
社团活动总结格式
2014/08/29 职场文书
第二次离婚起诉书
2015/05/18 职场文书
开工典礼致辞
2015/07/29 职场文书
银行柜员优质服务心得体会
2016/01/22 职场文书
Go语言-为什么返回值为接口类型,却返回结构体
2021/04/24 Golang
教你用python实现一个无界面的小型图书管理系统
2021/05/21 Python
nginx静态资源的服务器配置方法
2022/07/07 Servers