(转)pytorch中的矩阵维度

pytorch中的矩阵维度 - PososAgapo的文章 - 知乎 https://zhuanlan.zhihu.com/p/63802393

pytorch中对于矩阵要进行的操作很多,但是初学者可能并不很清楚矩阵的维度,以及当矩阵维度变大时候,怎么知道我们要操作的维度在哪里。

1.学会观察中括号,了解你现在的输出数据到底是在几维空间。

tensor([[[0.1205, 0.1218],
         [0.1326, 0.1112],
         [0.1276, 0.1477],
         [0.1228, 0.1192],
         [0.1221, 0.1173],
         [0.1243, 0.1268],
         [0.1252, 0.1277],
         [0.1250, 0.1283]]], grad_fn=<SoftmaxBackward>)

第一眼一看,这个数据是一个8行2列的数据,但是实际上它的tensor维度是[1,8,2],这里就和我们的中括号有关,我们知道当只有一个scalar的时候tensor存在时我们的输出是这样的:

tensor(1).shape
output
torch.Size([1])

这里可以看到我们维度为一的tensor是只有一个括号的,那我们再看看当输入的tensor是两个的时候的结果:

a=torch.tensor([1,2])
a
tensor([1, 2])
a.shape
torch.Size([2])

我们看见,只要当输入的数据还是一个python的array时候,输出的size还是一个中括号。

那么我们再来看下面这个例子:

a=torch.tensor([[1,2],[3,4]])
a
tensor([[1, 2],
        [3, 4]])
a.shape
torch.Size([2, 2])

我们看见,这时候就有了两个中括号在这里,可以看见pytorch中的维度认为是垂直方向堆叠,同一个array数组里的处于同一个维度,比如[1,2]和[3,4],而不同array里的处于不同维度

那我们再看第一个例子:
tensor([[[0.1205, 0.1218],
         [0.1326, 0.1112],
         [0.1276, 0.1477],
         [0.1228, 0.1192],
         [0.1221, 0.1173],
         [0.1243, 0.1268],
         [0.1252, 0.1277],
         [0.1250, 0.1283]]], grad_fn=<SoftmaxBackward>)

我们看到,这里是有明显的三个中括号,表明的我们的数据是3维而不是二维,我们可以一层一层的拨开这个矩阵,里层有八个size是2的tensor被一个中括号包住,说明了这个这个维度是8维的,而我们把第二个括号里的都看成一个tensor,则它是被第三个括号包裹的,那么对于第三个括号来说,这只是一维的。

而根据pytorch的size输出为:

torch.Size([1, 8, 2])

正好验证了这个剥开的过程,每个tensor是size2的张量,而一共有8个这样的张量,而这8个被一个中括号括起来后,成了一个[8,2]的tensor,随后又被一个中括号括起来,相当于成了第三个维度的第一个数据。

2.如果索引和操作多维数组

知道了多维张量的分布之后,我们就要正确的知道如何正确的索引我们想要的数据,相比于矩阵是从内向外一层层包裹,而矩阵索引就是从外到内一层层的拆开,对于这个数组,第一若我们要索引[8,2]的那个8维2列的正确的数据,我们因该怎么索引呢?

实际上按从外向内索引的办法,我们应该在第一步索引就可以做到:

a=torch.tensor([[[0.1205, 0.1218],
        [0.1326, 0.1112],
        [0.1276, 0.1477],
        [0.1228, 0.1192],
        [0.1221, 0.1173],
        [0.1243, 0.1268],
        [0.1252, 0.1277],
        [0.1250, 0.1283]]])
a[0]
tensor([[0.1205, 0.1218],
        [0.1326, 0.1112],
        [0.1276, 0.1477],
        [0.1228, 0.1192],
        [0.1221, 0.1173],
        [0.1243, 0.1268],
        [0.1252, 0.1277],
        [0.1250, 0.1283]])

可以看到我们正确的把我们想要的[8,2]的数据切了出来,证明了包裹是从内往外一层一层包裹,而索引则是从外到内一层一层索引。

继续索引,加入我们要取出[8,2]数据中的第一维度的第二个值0.1218,我们应该从外到内如下索引:

a[0][0][1]
tensor(0.1218)

这一看见我们正确的索引出来了结果。

3.函数在矩阵上的使用

使用pytorch函数时,我们经常要制定维度,比如softmax这种函数,我们要制定维度才能够正确在我们想要的维度上归一化,那么对于这个数据,在最里层基本都是相等的,所以我们应该出来的都是0.5左右,那我们要怎么去使用softmax来归一化呢,在初始数组上我们知道我们的矩阵维度是[1,8,2]的,这就提供给我们三个维度可以使用softmax,我们如何指定正确的维度呢。

先看下面:

a.softmax(dim=0)
a.shape
torch.Size([1, 8, 2])
tensor([[[1., 1.],
         [1., 1.],
         [1., 1.],
         [1., 1.],
         [1., 1.],
         [1., 1.],
         [1., 1.],
         [1., 1.]]])

全部都是1,很奇怪吧,但是实际想想会觉得奇怪吗?

并不是这样,我们的数据的size是[1,8,2],那么我们在dim=0的维度索引,那么softmax也是在[1,8,2]中1这个方向索引,然后这个数组在三维上只有一个,所以softmax求出来必然是1.

在看下面:

a.softmax(dim=1)
tensor([[[0.1244, 0.1246],
         [0.1260, 0.1233],
         [0.1253, 0.1279],
         [0.1247, 0.1243],
         [0.1246, 0.1240],
         [0.1249, 0.1252],
         [0.1250, 0.1253],
         [0.1250, 0.1254]]])

可以看见基本上每个都是1/8,不那么奇怪了对吧。但是实际上也是符合pytorch的逻辑的,我们在[1,8,2]的[8]上求softmax,它自然是按列求解了,所以得到这样一个结果也并不奇怪。

再看最后的结果:

a.softmax(dim=2)
tensor([[[0.4997, 0.5003],
         [0.5053, 0.4947],
         [0.4950, 0.5050],
         [0.5009, 0.4991],
         [0.5012, 0.4988],
         [0.4994, 0.5006],
         [0.4994, 0.5006],
         [0.4992, 0.5008]]])

这我们就得到了我们想要的输出结果,我们在[1,8,2]的第三个维度在此时相当于[8,2]中的每个tensor求了,也就是我们包裹维度的最里层,可见pytroch的函数dim参数,从小到大分别对于了外层到里层的一个过程。

我们还可以做如下实验:

a=torch.tensor([[[0.1205, 0.1218],
        [0.1326, 0.1112],
        [0.1276, 0.1477],
        [0.1228, 0.1192],
        [0.1221, 0.1173],
        [0.1243, 0.1268],
        [0.1252, 0.1277],
        [0.1250, 0.1283]],
        [[0.1205, 0.1218],
        [0.1326, 0.1112],
        [0.1276, 0.1477],
        [0.1228, 0.1192],
        [0.1221, 0.1173],
        [0.1243, 0.1268],
        [0.1252, 0.1277],
        [0.1250, 0.1283]]])
a.shape
torch.Size([2, 8, 2])

我们复制了一个相同的数据组成了[2,8,2],我们再用softmax算呢?

a.softmax(dim=0)
tensor([[[0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000]],
        [[0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000],
         [0.5000, 0.5000]]])

这是一个并不意外的结果,在最外层上两个相同[1,8,2]组成的数据使用softmax必定都是0.5

a.softmax(dim=2)
tensor([[[0.4997, 0.5003],
         [0.5053, 0.4947],
         [0.4950, 0.5050],
         [0.5009, 0.4991],
         [0.5012, 0.4988],
         [0.4994, 0.5006],
         [0.4994, 0.5006],
         [0.4992, 0.5008]],
        [[0.4997, 0.5003],
         [0.5053, 0.4947],
         [0.4950, 0.5050],
         [0.5009, 0.4991],
         [0.5012, 0.4988],
         [0.4994, 0.5006],
         [0.4994, 0.5006],
         [0.4992, 0.5008]]])

同样的在dim=2上求,也是对最里层的进行求解,得到正确的结果。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值