pytorch的维度问题
解释pytorch的维度
https://blog.csdn.net/qq_40994016/article/details/117391132(这个博客的讲解,强推)
x = torch.tensor([
[1,2,3],
[4,5,6]
])
# 我们可以看到"行"是dim=0, "列"是dim=1
print(x.shape)
>> torch.Size([2, 3])
于是, 我们会认为, torch.sum(x, dim=0)就是(1+2+3, 4+5+6)=tensor([6, 15]), 但是实际情况却不是这个样子的.
- torch.sum(x, dim=0)
- >> tensor([5, 7, 9])
我们可以看到按照 dim=0 求和, 其实是在按列相加, 也就是 (1+4, 2+5, 3+6) =tensor([5, 7, 9]), 和我们想象的完全不一样. 我们再看一下按照 dim=1 进行求和.
- torch.sum(x, dim=1)
- >> tensor([ 6, 15])
可以看到, 在按照 dim=1 的时候求和的时候, 其实在按照按行进行求和, (1+2+3, 4+5+6)=tensor([6, 15]), 这就让人很困惑, 明明上面说的是 dim=0 代表是行。
于是, 原文作者在一篇介绍 numpy 维度的文章中, 找到了问题的关键所在. 也就是下面的这段话( numpy 中的 axis 也就是这里的 dim).
The way to understand the "axis" of numpy sum is that it collapses the specified axis. So when it collapses the axis 0 (the row), it becomes just one row (it sums column-wise).
上面的话简单翻译就是, 当按照axis=0进行求和的时候, 其实可以想象为对axis=0这个维度进行挤压, 最后只剩下一行, 那一行就是结果, 也就是按列在相加.
是不是还是会有一些困惑, 我们还是对于上面的例子(tensor([[1,2,3], [4,5,6]])), 看一下在dim=0的时候, 为什么是列相加, 以及上面的collapse the specific axis(dim)的含义.
如上面的动图所示, 当dim=0的时候, 按每一行的元素进行相加, 最后的结果就是和按列求和.
对于三维向量
下面我们更进一步, 来看一下对于三维的tensor, 在各个维度进行sum操作的结果. 首先我们看一下每一个dim代表的含义.
# 看一下三维的
x = torch.tensor([
[
[1,2,3],
[4,5,6]
],
[
[1,2,3],
[4,5,6]
],
[
[1,2,3],
[4,5,6]
]
])
# 我们可以看到第三维是dim=0, "行"是dim=1, 列是dim=2
print(x.shape)
>> torch.Size([3, 2, 3])
可以看到此时dim=0是第三个维度, dim=1是行, dim=2是列.
- torch.sum(x, dim=0)
- >>
- tensor([[ 3, 6, 9],
- [12, 15, 18]])
我们可以将其看成是各个二维平面对应元素求和, 还是有点绕, 还是直接看下面的动图.

接着是对dim=1进行求和.
- torch.sum(x, dim=1)
- >>
- tensor([[5, 7, 9],
- [5, 7, 9],
- [5, 7, 9]])
还是直接看下面的动图, 来进行理解.

最后按照dim=2来进行求和.
- torch.sum(x, dim=2)
- >>
- tensor([[ 6, 15],
- [ 6, 15],
- [ 6, 15]])
还是使用动图来进行解释.

pytorch的乘法(高维矩阵运算)
【全面理解多维矩阵运算】多维(三维四维)矩阵向量运算-超强可视化
shape=[2,2,2,3]的四维矩阵,可以视为2个shape=[2,2,3]的三维矩阵堆叠在一起!!然后三维的最后是用二维的堆叠组成的!!第一个2表示的是batchsize!!最后两维才是有数据的矩阵,前面的维度只是矩阵的排列而已!
从上面可以得出结论:所有大于二维的,最终都是以二维为基础堆叠在一起的!!
所以在矩阵运算的时候,其实最后都可以转成我们常见的二维矩阵运算,遵循的原则是:在多维矩阵相乘中,需最后两维满足shape匹配原则,最后两维才是有数据的矩阵,前面的维度只是矩阵的排列而已!
举个例子:比如两个三维的矩阵相乘,分别为shape=[2,2,3]和shape=[2,3,2]
a =
[[[ 1. 2. 3.]
[ 4. 5. 6.]]
[[ 7. 8. 9.]
[10. 11. 12.]]]
b =
[[[ 1. 2.]
[ 3. 4.]
[ 5. 6.]]
[[ 7. 8.]
[ 9. 10.]
[11. 12.]]]
上面说了,a可以表示成2个shape=[2,3]的矩阵,b可以表示成2个shape=[3,2]的矩阵,前面的额表示的是矩阵排列情况。
计算的时候把a的第一个shape=[2,3]的矩阵和b的第一个shape=[3,2]的矩阵相乘,得到的shape=[2,2],即

同理,再把a,b个字的第二个shape=[2,3]的矩阵相乘,得到的shape=[2,2]。

最终把结果堆叠在一起,就是2个shape=[2,2]的矩阵堆叠在一起,结果为:
[[[ 22. 28.]
[ 49. 64.]]
[[220. 244.]
[301. 334.]]]
也就是shape=[2,2,3]和shape=[2,3,2]矩阵相乘,最后答案的shape为:把第一维表示矩阵排情况的2,直接保留作为结果的第一维,再把后面两维的通过矩阵运算,得到shape=[2,2]的矩阵,合起来结果shape=[2,2,2]。
四维的同理!拆成多个三维矩阵来运算即可!!
需要注意的是,四维中,前两维是矩阵排列,相乘的话保留前的最大值。
比如a:shape=[2,1,4,5],b:shape=[1,1,5,4]相乘,输出的结果中,前两维保留的是[2,1],最终结果shape=[2,1,4,4]
更多推荐


所有评论(0)