函数的默认情况:
torch.nn.functional.normalize(input, p=2, dim=1, eps=1e-12, out=None)
含义:返回在指定维度上的输入数据input的L-p范数的标准化后的数据。(在指定维度上,该数据的每个元素除以其L-p范数)
L-p范数:数学上的范数是指一个向量 x = ( x 1 , x 2 , . . . , x n ) x=(x_1,x_2,...,x_n) x=(x1,x2,...,xn)的模。公式如下。
如果数学概念不理解的话:
- 每个向量(1维还是多维)都具有“方向”和“长度”两个特征。在实数空间内,正负性表示“方向”,实数的绝对值 ∣ a ∣ |a| ∣a∣表示“长度”,该长度成为数学上的模(或者范数)。
- 对于二维向量(a,b)来说,同样具有一个“方向”[比如,向量与x轴的夹角,可以用内积表示],以及“长度”[通常用 ( a 2 + b 2 ) 2 \sqrt[2] {(a^2+b^2)} 2(a2+b2)表示,即为L-2范数。]
- 同理在三维或者多维向量下,类推得到L-p范数。
∣ ∣ x ∣ ∣ = ∑ 1 n ( ( ∣ x i ∣ ) p ) 1 p ||x||=\sum_1^n ((|x_i|)^p)^{\frac{1}{p}} ∣∣x∣∣=1∑n((∣xi∣)p)p1
思维误区:不表示,L-2空间内的二维向量只能用L-2范数,也是可以用L-1范数的。当然高于L-2的范数也能说,只是毫无意义。因此,往往在L-p空间内使用 ≤ p \leq p ≤p的范数。
此外,L-2范数其实类似于机器学习上的RSME,L-1范数类似于MAE.
参数解析:
- input:输入任何形式的torch.tensor
- p :理解了L-p范数的定义,显然这里的p是用来指代L-p范数的。
- eps: 因为要除以L-p范数,为避免分母过于小,因此设定了一个阈值,其默认为1e-12
import math
a = torch.Tensor([1,2,3])
# a的L1范数为 6=1+2+3;L2的范数为 sqrt(14)=sqrt(1^2+2^2+3^2)
a1 =torch.nn.functional.normalize(a, p=1,dim=0)
a2=torch.nn.functional.normalize(a, dim=0)#p默认为2
print(a1,a2)
print(torch.div(a,6),torch.div(a,math.sqrt(14)))
out:
tensor([0.1667, 0.3333, 0.5000]) tensor([0.2673, 0.5345, 0.8018])
tensor([0.1667, 0.3333, 0.5000]) tensor([0.2673, 0.5345, 0.8018])
b = torch.Tensor([[1,2,3], [4,5,6]]) # shape=(2,3)
b0=torch.nn.functional.normalize(b,p=1, dim=0)
b1=torch.nn.functional.normalize(b,p=1, dim=1)
print("dim=0 outset's shape:",b0.shape)
print(b0)
print("dim=1 outset's shape:",b1.shape)
print(b1)
在理解dim的时候,为方便运算和验证,我这里设置的是L-1范数。
out:
dim=0 outset's shape: torch.Size([2, 3])
tensor([[0.2000, 0.2857, 0.3333],
[0.8000, 0.7143, 0.6667]])
dim=1 outset's shape: torch.Size([2, 3])
tensor([[0.1667, 0.3333, 0.5000],
[0.2667, 0.3333, 0.4000]])
解析:
对于轴的理解可以参考:https://mathpretty.com/12065.html
我的规律,不明白看图(左侧是一维扩展到二维的情况。右侧是具体轴维度的运算情况):
规律:
- 判断:确定好轴方向(dim为哪个维度)
- 简化:沿轴方向的(一堆)数据看作一个新数据,不妨取一堆的第一个命名为新数据
- 运算:对新数据们进行当前的运算
- 扩维:沿轴方向进行逐一运算
b00 = torch.div(b,torch.Tensor([5,7,9])) #有广播机制
b11 = torch.div(b,torch.Tensor([[6,6,6],[15,15,15]]))
print(b0==b00)
print(b1==b11)
out:
tensor([[True, True, True],
[True, True, True]])
tensor([[True, True, True],
[True, True, True]])