【Pytorch】F.normalize学习笔记

1.函数介绍

import torch.nn.functional as F
F.normalize(input: Tensor, p: float = 2.0, dim: int = 1) -> Tensor

input: 是一个任意维度的Tensor类型的数据
p:默认为2,表示2范数;同理,p=1表示1范数
dim:(后面我会总结,先这样解释,方便大家理解,看完例子再看我总结的,会很清楚)
	默认 dim=1,在输入数据input的shape是二维的且p=2情况下,表示对行进行操作,即每行元素除以对应行元素的根号下平方和;
    dim=0 时,在输入数据input的shape是二维的且p=2情况下,表示对列进行操作,即每列元素除以对应列元素的根号下平方和;
    dim=2 时,我们通过例子分析...

normalize的参数不止这三个,其他的可以参考官方文档。

2.例子

2.1 输入一维的Tensor
c = torch.Tensor([1, 2, 3])
print(F.normalize(c, dim=0))

'''
输出:
tensor([0.2673, 0.5345, 0.8018])
torch.Size([3])
解释:
我们说过,默认dim=1,是按行操作,但是一维的Tensor是列向量,所以必须指定dim=0
默认p=2,所以这个一维的Tensor(列向量)每个元素都除以sqrt(1**2 + 2**2 + 3**2)
'''
2.2 输入二维的Tensor
b = torch.Tensor([[1, 2, 3], [4, 5, 6]])
print(F.normalize(b, dim=0))
print(F.normalize(b, dim=1))
print(b.shape)

'''
输出:
tensor([[0.2425, 0.3714, 0.4472],
        [0.9701, 0.9285, 0.8944]])
tensor([[0.2673, 0.5345, 0.8018],
        [0.4558, 0.5698, 0.6838]])
torch.Size([2, 3])
解释:
dim=0,按列操作,每行元素除以第一列元素的根号下平方和,即sqrt(1**2 + 4**2)
dim=1,按行操作,每列元素除以第一行元素的根号下平方和,即sqrt(1**2 + 2**2 + 3**2)
'''
2.3 输入三维Tensor
a = torch.Tensor([[[1, 2, 3], [4, 5, 6]], [[10, 20, 30], [40, 50, 60]]])

'''
默认p=2,dim=1,按列操作,每列元素除以sqrt(a[i][0][k]**2 + a[i][1][k]**2)
比如: 
1(a[0][0][0]) 和 4(a[0][1][0]) 所在的列,结果为列中每个元素(1、4)除以sqrt(a[0][0][0]**2 + a[0][1][0]**2)
20(a[1][0][1]) 和 50(a[1][1][1]) 所在的列,结果为列中每个元素(20、50)除以sqrt(a[1][0][1]**2 + a[1][1][1]**2)
'''
print(F.normalize(a))  

'''
dim=0,按新添加维度操作,新添加的维度(1->10这个方向的维度)方向的每个元素除以sqrt(a[0][j][k]**2 + a[1][j][k]**2)
比如:
1 和 10 除以sqrt(1**2 + 10**2)
2 和 20 除以sqrt(2**2 + 20**2)
6 和 60 除以sqrt(6**2 + 60**2)
'''
print(F.normalize(a, dim=0))  

'''
dim=2,按行操作,每行元素除以sqrt(a[i][j][0]**2 + a[i][j][1]**2 + a[i][j][2]**2),
比如:
1、2、3 除以 sqrt(1**2 + 2**2 + 3**2)
40、50、60 除以 sqrt(40**2 + 50**2 + 60**2)
'''
print(F.normalize(a, dim=2))

'''
输出:
tensor([[[0.2425, 0.3714, 0.4472],
         [0.9701, 0.9285, 0.8944]],

        [[0.2425, 0.3714, 0.4472],
         [0.9701, 0.9285, 0.8944]]])
tensor([[[0.0995, 0.0995, 0.0995],
         [0.0995, 0.0995, 0.0995]],

        [[0.9950, 0.9950, 0.9950],
         [0.9950, 0.9950, 0.9950]]])
tensor([[[0.2673, 0.5345, 0.8018],
         [0.4558, 0.5698, 0.6838]],

        [[0.2673, 0.5345, 0.8018],
         [0.4558, 0.5698, 0.6838]]])
解释:
这个不好解释,烦请大家看我的总结!
'''

3.总结

不知大家发现没有,通过dim的数值来判定是按行操作还是按列操作很容易搞混,尤其是当Tensor是高维(≥3)的时候,很难看是哪里是行,哪里是列,哪里是第三个或者更高的维度。

所以,接下来,我谈谈我的理解:(p=2在二范数的情况下,其他范数也类似)

  • 一维Tensor

当Tensor只有一个维度的时候,默认的normalize就是除以这个维度所有元素的根号下平方和(dim只能等于0);

  • 二维Tensor

当Tensor是二维的时候,dim=0表示所有元素除以新添加的维度(刚开始只有一维的列向量,现在多了行,所以行是新添加的维度)的每行元素根号下平方和;dim=1跟Tensor是一维的时候一样。
总的来看,是不是相当于:在之前的维度上,新添加的维度(行)往前插入,成为新的dim=0,而原来的维度(列)往后变成dim=1。

  • 三维Tensor

当Tensor是三维的时候,一样的道理,新添加的维度是在二维Tensor的基础上,多了一个z维(这里我不知道该怎么称呼第三个维度,所以我把一维的叫x维,二维就是x和y维,三维就是x,y和z维),如2.3中我们举的例子,多了[1, 10]这个方向的维度,所以dim=0就表示的是新添加维度(z维)的每个元素除以其对应z方向的根号下平方和,即a[0][j][k] / sqrt(a[0][j][k] ** 2 + a[1][j][k] ** 2),a[1][j][k] / sqrt(a[0][j][k] ** 2 + a[1][j][k] ** 2) ;dim=1和dim=2依次对应Tensor是二维的时候的dim=0和dim=1。
总的来看是不是相当于:把新添加的维度(z维)往前插入成了dim=0,其他维度(二维时候dim=0的行和dim=1的列)依次向后成了dim=1和dim=2。

以上是我对dim维度的理解,有不对的地方欢迎大家指正!

  • 15
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值