目录
前言
在实际应用中,我发现python中import Numpy后在Numpy array计算中axis指令与pytorch框架下import torch / torch.nn后Tensor计算中dim指令难以区分,原以为二者大差不差,其实也有较大的差别。经过查阅相关资料,大部分文章一是概念讲述苦涩难懂,无法用简洁的语言使其明了,二是分析片面,综合性差,不能举一反三,触内旁通,综上,本文将从两个方面提供更加全面准确的讲解。
Numpy array的axis指令
导入numpy后利用sum进行分析:
import numpy as np
a = np.array([[1,2,3],[2,2,2]])
n_1 = np.sum(a, axis=0)
n_2 = np.sum(a, axis=1)
print('dim=0的结果是:\n',n_1,"\n")
print('dim=1的结果是:\n',n_2,"\n")
dim=0的结果是:
[3 4 5]
dim=1的结果是:
[6 6]
可见dim = 0时可以理解为仅保存dim = 0对应的维度(即行),故最终结果为行向量,而当dim = 1时理解为仅保存dim = 1对应的维度(即列),故最终结果为列向量。
Tensor 的dim指令
1. 导入torch.nn中的Softmax进行分析:
import torch.nn as nn
import torch
y = torch.rand(size=[2,2,3])
print(y)
#y的size是2,2,3。可以看成有两张表,每张表2行3列
net_1 = nn.Softmax(dim=0)
net_2 = nn.Softmax(dim=1)
net_3 = nn.Softmax(dim=2)
print('dim=0的结果是:\n',net_1(y),"\n")
print('dim=1的结果是:\n',net_2(y),"\n")
print('dim=2的结果是:\n',net_3(y),"\n")
y = tensor([[[ 0.5450, -0.6264, 1.0446],
[ 0.6324, 1.9069, 0.7158]],
[[ 1.0092, 0.2421, -0.8928],
[ 0.0344, 0.9723, 0.4328]]])
# dim = 0 时的结果:
tensor([[[0.3860, 0.2956, 0.8741],
[0.6452, 0.7180, 0.5703]],
[[0.6140, 0.7044, 0.1259],
[0.3548, 0.2820, 0.4297]]])
dim=0时的计算原则即:
0.3860+0.6140=1 0.2956+0.7044=1 0.8741+0.1259=1.......
类似于:
# dim = 1 时的结果:
tensor([[[0.4782, 0.0736, 0.5815],
[0.5218, 0.9264, 0.4185]],
[[0.7261, 0.3251, 0.2099],
[0.2739, 0.6749, 0.7901]]])
dim=1时的计算原则即:
0.4782+0.5218=1 0.0736+0.9264=1 0.5815+0.4185=1......
类似于:
# dim = 2 时的结果:
tensor([[[0.3381, 0.1048, 0.5572],
[0.1766, 0.6315, 0.1919]],
[[0.6197, 0.2878, 0.0925],
[0.1983, 0.5065, 0.2953]]])
dim=2时的计算原则即:
0.3381+0.1048+0.5572=1.0001(四舍五入问题) 0.1766+0.6315+0.1919=1......
2. 仅利用torch中的Tensor进行sum运算:
import torch.nn as nn
import torch
y = torch.rand(size=[2,3,4])
print(y)
net_1 = y.sum(dim=0)# 经过尝试,dim = 0 可用axis = 0代替,真是神奇,以下部分也一样
net_2 = y.sum(dim=1)
net_3 = y.sum(dim=2)
print('dim=0的结果是:\n',net_1,"\n")
print('dim=1的结果是:\n',net_2,"\n")
print('dim=2的结果是:\n',net_3,"\n")
y的结果是:
tensor([[[0.3531, 0.6126, 0.7908, 0.7340],
[0.3432, 0.7925, 0.9733, 0.6881],
[0.3591, 0.6543, 0.3843, 0.7147]],
[[0.2275, 0.8611, 0.7870, 0.3049],
[0.6595, 0.8968, 0.5016, 0.9924],
[0.0793, 0.3451, 0.7671, 0.4755]]])
dim=0的结果是:
tensor([[0.5806, 1.4737, 1.5778, 1.0389],
[1.0027, 1.6892, 1.4749, 1.6805],
[0.4384, 0.9993, 1.1515, 1.1902]])
dim=1的结果是:
tensor([[1.0554, 2.0593, 2.1484, 2.1367],
[0.9664, 2.1029, 2.0557, 1.7729]])
dim=2的结果是:
tensor([[2.4905, 2.7970, 2.1124],
[2.1805, 3.0503, 1.6670]])
通过观察可以发现使用sum进行运算时,其运算原则与Softmax大差不差,但关键之处在于计算dim = 2时,怎样分析其维度呢?此时应这样理解:
当利用sum进行运算,dim = x(其中x = 0, 1, 2),x对应的维度被消去,剩下的维度分别组成行与列,显然这与Numpy中sum的axis指令相反,因为Numpy下axis所指定的维度将被保留,而此处则是被消去。
结论
Numpy array的axis指令所指定的维度将被保留,从而得到对应的行向量或者列向量,而Tensor 的dim指令计算原则可参照文中动图,但值得注意的是分析结果维度时dim所指定的维度将被消去,剩下的维度分别作为行与列从而构成最终结果的维度