# 范数(norm) 几种范数的简单介绍 & data.norm()使用
# 1. 范数 (norm) 的简单介绍
什么是范数?
我们知道距离的定义是一个宽泛的概念,只要满足非负、自反、三角不等式就可以称之为距离。范数是一种强化了的距离概念,它在定义上比距离多了一条数乘的运算法则。有时候为了便于理解,我们可以把范数当作距离来理解。
在数学上,范数包括向量范数和矩阵范数,向量范数表征向量空间中向量的大小,矩阵范数表征矩阵引起变化的大小。
一种非严密的解释就是,对应向量范数,向量空间中的向量都是有大小的,这个大小如何度量,就是用范数来度量的,不同的范数都可以来度量这个大小,就好比米和尺都可以来度量远近一样;对于矩阵范数,学过线性代数,我们知道,通过运算,可以将向量 X 变化为 B,矩阵范数就是来度量这个变化大小的。
这里简单地介绍以下几种向量范数的定义和含义:
# 1.1 L-P 范数
与闵可夫斯基距离的定义一样,L-P 范数不是一个范数,而是一组范数,其定义如下:
根据 P 的变化,范数也有着不同的变化,一个经典的有关 P 范数的变化图如下:
上图表示了 p 从无穷到 0 变化时,三维空间中到原点的距离(范数)为 1 的点构成的图形的变化情况。以常见的 L-2 范数(p=2)为例,此时的范数也即欧氏距离,空间中到原点的欧氏距离为 1 的点构成了一个球面。
# 1.2 L0 范数
当 P=0 时,也就是 L0 范数,由上面可知,L0 范数并不是一个真正的范数,它主要被用来度量向量中非零元素的个数。
# 1.3 L1 范数
L1 范数是我们经常见到的一种范数,它的定义如下:
表示向量 x 中非零元素的绝对值之和。
L1 范数有很多的名字,例如我们熟悉的曼哈顿距离、最小绝对误差等。使用 L1 范数可以度量两个向量间的差异,如绝对误差和(Sum of Absolute Difference):
# 1.4 L2 范数
L2 范数是我们最常见最常用的范数了,我们用的最多的度量距离欧氏距离就是一种 L2 范数,它的定义如下:
Euclid 范数(欧几里得范数,常用计算向量长度),即向量元素绝对值的平方和再开方,pytorch 调用函数 norm (x, 2)。
像 L1 范数一样,L2 也可以度量两个向量间的差异,如平方差和(Sum of Squared Difference): SSD
L2 范数通常会被用来做优化目标函数的正则化项,防止模型为了迎合训练集而过于复杂造成过拟合的情况,从而提高模型的泛化能力。
# 1.5 ∞- 范数
即所有向量元素绝对值中的最小值,matlab 调用函数 norm (x, -inf)。
# 2. 矩阵范数
# 2.1 1 - 范数
列和范数,即所有矩阵列向量绝对值之和的最大值,matlab 调用函数 norm (A, 1)。
# 2.2 2 - 范数
对于实矩阵 A,它的谱范数定义为:
其中,eig (X) 为计算方阵 特征值,它返回特征值向量:谱范数,即 A’A 矩阵的最大特征值的开平方。matlab 调用函数 norm (x, 2)。
# 2.3 ∞- 范数
行和范数,即所有矩阵行向量绝对值之和的最大值,matlab 调用函数 norm (A, inf)。
# 2.4 F - 范数
Frobenius 范数,即矩阵元素绝对值的平方和再开平方,matlab 调用函数 norm (A, ’fro‘)。
# 2.6 核范数
是 A 的奇异值,核范数即奇异值之和。
# 3. pytorch 中 x.norm (p=2,dim=1,keepdim=True) 的理解
# 3.1 方法介绍
代码:x.norm (p=2,dim=1,keepdim=True)
功能:求指定维度上的范数
函数原型:返回输入张量给定维 dim 上每行的 p 范数
torch.norm(input, p, dim, out=None,keepdim=False) → Tensor
注:范数求法:对 N 个数据求 p 范数(上面已介绍)
# 3.2 函数参数
- input (Tensor) – 输入张量
- p (float) – 范数计算中的幂指数值
- dim (int) – 缩减的维度,dim=0 是对 0 维度上的一个向量求范数,返回结果数量等于其列的个数,也就是说有多少个 0 维度的向量,将得到多少个范数。dim=1 同理。
- out (Tensor, optional) – 结果张量
- keepdim(bool)– 保持输出的维度 。当 keepdim=False 时,输出比输入少一个维度(就是指定的 dim 求范数的维度)。而 keepdim=True 时,输出与输入维度相同,仅仅是输出在求范数的维度上元素个数变为 1。这也是为什么有时我们把参数中的 dim 称为缩减的维度,因为 norm 运算之后,此维度或者消失或者元素个数变为 1。
# 3.3 实例演示
import torch |
data = torch.tensor([ | |
[1., 2., 3., 4.], | |
[ 2., 4., 6., 8.], | |
[ 3., 6., 9., 12.] | |
]) |
# 3.3.1 dim 参数
分别对其行和列分别求 2 范数:
# 按行 | |
torch.norm(data, p=2, dim=1, keepdim=True) |
tensor([[ 5.4772], | |
[10.9545], | |
[16.4317]]) |
# 按列 | |
torch.norm(data, p=2, dim=0, keepdim=True) |
tensor([[ 3.7417, 7.4833, 11.2250, 14.9666]]) |
# 3.3.2 keepdim 参数
torch.norm(data, p=2, dim=1, keepdim=False) |
tensor([ 5.4772, 10.9545, 16.4317]) |
可以看到输出少了一维,其实就是 dim=1(求范数)那一维 (列) 少了,因为从 4 列变成 1 列,就是 3 行中求每一行的 2 范数,就剩 1 列了,不保持这一维不会对数据产生影响。或者也可以这么理解,就是数据每个数据有没有用 [] 扩起来。
不写 keepdim,则默认不保留 dim 的那个维度
torch.norm(data, p=2, dim=1) |
tensor([ 5.4772, 10.9545, 16.4317]) |
不写 dim,则计算 Tensor 中所有元素的 2 范数
torch.norm(data, p=2) |
tensor(20.4939) |
与上面一样的效果,默认是 L2 范数
torch.norm(data) |
tensor(20.4939) |
首先,它对张量 y 每个元素进行平方,然后对它们求和,最后取平方根。 这些操作计算就是所谓的 L2 或欧几里德范数。
参考:Link Link Link Link
加油!
感谢!
努力!