属性统计是pytorch中常用的基本操作,常见的属性统计操作有:
(1)norm(求范数)
(2)Mean, sum (求均值、求和)
(3)prod (求元素乘积)
(4)Max, min, argmin, argmax (求最大、最小值,求最大值、最小值的位置)
(5)Kthvalue, topk (属性统计,求属性排在前面的操作)
下面依次介绍
Norm(范数)不同于normalize(正则化)
这里先解释一下范数的概念,范数可以认为是一种距离,只要满足非负、自反、三角不等式就可以称之为距离。而范数在定义上比距离多了一条数乘的运算法则。
在数学上,范数包括向量范数和矩阵范数,向量范数表征向量空间中向量的大小,矩阵范数表征矩阵引起变化的大小。一种非严密的解释就是,对应向量范数,向量空间中的向量都是有大小的,这个大小如何度量,就是用范数来度量的,不同的范数都可以来度量这个大小,就好比米和尺都可以来度量远近一样;对于矩阵范数,学过线性代数,我们知道,通过运算,可以将向量X变化为B,矩阵范数就是来度量这个变化大小的。
0范数,向量中非零元素的个数。
1范数,所有元素的绝对值之和。
2范数,所有元素绝对值的平方和再开根号
无穷范数,就是取向量的最大值。
以代码示例:
代码语言:javascript复制import torch
a = torch.full([8], 1)
b = a.view(2, 4)
c = a.view(2, 2, 2)
print('a:', a)
print('b:', b)
print('c:', c)
分别输出为
代码语言:javascript复制a: tensor([1., 1., 1., 1., 1., 1., 1., 1.])
b: tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.]])
c: tensor([[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]]])
分别输出他们的1范数、二范数、三范数。
代码语言:javascript复制# 按照之前定义,一范数为各个元素绝对值的和
print('a的一范数为:', a.norm(1))
print('b的一范数为:', b.norm(1))
print('c的一范数为:', c.norm(1))
分别输出为
代码语言:javascript复制a的一范数为:tensor(8.)
b的一范数为:tensor(8.)
c的一范数为:tensor(8.)
验证了之前提到的1范数定义:所有元素绝对值的平方和再开根号
输出2范数
代码语言:javascript复制# 按照之前定义,二范数为所有元素绝对值的平方和再开根号
print('a的二范数为:', a.norm(2))
print('b的二范数为:', b.norm(2))
print('c的二范数为:', c.norm(2))
分别输出为
代码语言:javascript复制a的二范数为:tensor(2.8284)
b的二范数为:tensor(2.8284)
c的二范数为:tensor(2.8284)
若对个别维度上进行求范数操作,需要加 dim=
代码语言:javascript复制# 对b的1维进行求范数操作
print(b.norm(1, dim=1))
# 因为b为:tensor([[1., 1., 1., 1.],
# [1., 1., 1., 1.]])
# 在dim=1求范数时,是4个1的绝对值加和,故为4
输出为
代码语言:javascript复制tensor([4., 4.])
同理对b的该维度下进行求二范数
代码语言:javascript复制# 对b的1维进行求范数操作
print(b.norm(2, dim=1))
# 因为b为:tensor([[1., 1., 1., 1.],
# [1., 1., 1., 1.]])
# 在dim=1求范数时,是4个1的绝对值加和的开根号,故为4的开根号,结果为2
输出
代码语言:javascript复制tensor([2., 2.])
这类操作较简单,不再赘述
下面介绍统计操作,当想进行clamping操作时,需要知道最小值与最大值
举例
代码语言:javascript复制a = torch.arange(10).view(2, 5).float()
print(a)
输出
代码语言:javascript复制tensor([[0., 1., 2., 3., 4.],
[5., 6., 7., 8., 9.]])
代码语言:javascript复制print('min', a.min())
print('max', a.max())
print('mean', a.mean())
print('prod', a.prod())
# .prod():类乘
print('sum', a.sum())
分别输出
代码语言:javascript复制min tensor(0.)
max tensor(9.)
mean tensor(4.5000)
prod tensor(0.)
sum tensor(45.)
求出里面最大值与最小值所对应的位置
代码语言:javascript复制print('argmax', a.argmax())
print('argmin', a.argmin())
输出
代码语言:javascript复制argmax tensor(9)
argmin tensor(0)
注意:由输出结果可注意到返回的是9和0,而不是9.0和0.0,说明与之前的输出有所区别,类似的细节还有很多,使用时要仔细甄别自己的输出是否有错误。
另外这里默认使用了打平操作,将[2, 5]矩阵打平成[1, 10]后找到的最大值和最小值所对应的位置。
若想输出各行和各列的最大值和最小值,举例
代码语言:javascript复制a = torch.rand(12).view(3, 4)
print(a)
print('argmax(dim=0)', a.argmax(dim=0))
print('argmax(dim=1)', a.argmax(dim=1))
输出
代码语言:javascript复制tensor([[0.0698, 0.9070, 0.2892, 0.2901],
[0.1018, 0.4904, 0.4492, 0.2303],
[0.3585, 0.1880, 0.2186, 0.7236]])
argmax(dim=0) tensor([2, 0, 1, 2])
argmax(dim=1) tensor([1, 1, 3])
由结果可看出,在dim=0时,每列的最大值分别是第2个、第0个、第1个、第2个。
而在dim=1时,每行的最大值分别是第1个、第1个、第3个。