【Pytorch】F.normalize计算理解

本文介绍了PyTorch中的torch.nn.functional.normalize函数,该函数用于对张量进行L2范数归一化。通过指定的维度(dim)对数据进行处理,确保每一行或每一列的元素除以其对应范数,从而实现单位化。举例说明了dim为0时的操作,解释了其计算过程。参考了官方文档和其他相关资源,有助于深入理解该函数的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、动机

最近多次看到该方法出现,于是准备了解一下,搜了后发现原来是所谓的L2 norm计算

2、简介

函数定义

torch.nn.functional.normalize(inputp=2.0dim=1eps=1e-12out=None)

功能:将某一个维度除以那个维度对应的范数(默认是2范数)。

使用:

F.normalize(data, p=2/1, dim=0/1/-1) 将某一个维度除以那个维度对应的范数(默认是2范数)

        data:输入的数据(tensor)

        p:L2/L1_norm运算

        dim:0表示按列操作,则每列都是除以该列下平方和的开方;1表示按行操作,则每行都是除以该行下所有元素平方和的开方

3、举例

 

 最后dim=0,是1/根号下1平方+1平方,2/根号下2平方+2平方,3/根号下3平方+3平方,所以都是0.7071

4、参考

官方学习手册

torch.nn.functional.normalize()函数解读

torch.nn.functional.normalize详解

理解PyTorch中维度的概念

def forward(self, feat_fv, feat_fi, feat_v, feat_i): batchSize = feat_fv.shape[0] dim = feat_fv.shape[1] T = 0.07 feat_fv = F.normalize(feat_fv, dim=1) feat_fi = F.normalize(feat_fi, dim=1) feat_v = F.normalize(feat_v, dim=1) feat_i = F.normalize(feat_i, dim=1) l_pos_v = torch.bmm(feat_fv.view(batchSize, 1, -1), feat_v.view(batchSize, -1, 1)) l_pos_v = l_pos_v.view(batchSize, 1) l_pos_i = torch.bmm(feat_fi.view(batchSize, 1, -1), feat_i.view(batchSize, -1, 1)) l_pos_i = l_pos_i.view(batchSize, 1) l_pos = torch.zeros((batchSize, 1)).to(self.device) l_neg = torch.zeros((batchSize, batchSize-1)).to(self.device) for b in range(batchSize): if l_pos_v[b] >= l_pos_i[b]: # pos logit l_pos_batch = l_pos_v[b].unsqueeze(0) l_pos = l_pos.scatter_add_(0, torch.tensor([[b]]).to(self.device), l_pos_batch) # neg logit feat_v_without_pos = feat_v[torch.arange(feat_v.size(0)) != b] index_base = [b for _ in range(batchSize-1)] index = torch.tensor([index_base]).to(self.device) l_neg_batch = torch.bmm(feat_fv[b].unsqueeze(0).unsqueeze(0), feat_v_without_pos.view(1, -1, dim).transpose(2, 1)) l_neg_batch = l_neg_batch.view(-1, batchSize-1) l_neg = l_neg.scatter_add_(0, index, l_neg_batch) else: # pos logit l_pos_batch = l_pos_i[b].unsqueeze(0) l_pos = l_pos.scatter_add_(0, torch.tensor([[b]]).to(self.device), l_pos_batch) # neg logit feat_i_without_pos = feat_i[torch.arange(feat_i.size(0)) != b] index_base = [b for _ in range(batchSize-1)] index = torch.tensor([index_base]).to(self.device) l_neg_batch = torch.bmm(feat_fi[b].unsqueeze(0).unsqueeze(0), feat_i_without_pos.view(1, -1, dim).transpose(2, 1)) l_neg_batch = l_neg_batch.view(-1, batchSize-1) l_neg = l_neg.scatter_add_(0, index, l_neg_batch) out = torch.cat((l_pos, l_neg), dim=1) / T loss = self.cross_entropy_loss(out, torch.zeros(out.size(0), dtype=torch.long, device=feat_fv.device)) return loss
最新发布
03-21
<think>好的,我现在需要分析用户提供的这段PyTorch代码,并解释其功能和实现细节。首先,我会仔细阅读代码,理解每个部分的作用。 这段代码是一个神经网络的前向传播函数,属于自定义的PyTorch模块中的forward方法。输入参数包括四个特征张量:feat_fv、feat_fi、feat_v、feat_i。首先,这些特征被归一化处理,这可能是在计算相似度前常见的步骤,比如在对比学习中。 接下来,计算正样本的相似度。l_pos_v和l_pos_i分别是feat_fv与feat_v、feat_fi与feat_i的批量矩阵乘法结果,然后调整形状。这说明可能在计算两种模态之间的正例对,比如视觉和文本特征的对齐。 然后,初始化l_pos和l_neg为零张量,用于存储正例和负例的相似度得分。循环遍历每个样本,根据正例得分的高低选择不同的路径。如果视觉的正例得分更高,就使用视觉特征计算负例,否则使用其他模态的特征。这里可能是为了选择更可靠的正例对,动态调整负例的采样来源。 在负例计算中,排除当前样本的特征,与其他样本进行矩阵乘法,得到负例相似度,并使用scatter_add_方法将结果填充到l_neg中。这可能是在构建对比损失中的负样本对,每个样本的正例与其他所有样本作为负例。 最后,将正负例得分拼接,除以温度系数T,计算交叉熵损失。这里的交叉熵损失可能采用了一种对比损失的形式,比如InfoNCE损失,其中正例作为目标类别,模型需要区分正例和大量负例。 可能的问题包括:归一化的目的、矩阵乘法的意义、scatter_add_的作用、温度系数的影响,以及整体损失函数的设计意图。需要逐一解释这些部分,并指出可能的优化点或潜在问题,比如循环可能影响效率,是否有更向量化的实现方式。</think>这段代码实现了一个对比学习框架中的损失计算过程,主要用于处理多模态特征对齐。以下是核心功能的逐层解释: 1. **输入归一化** ```python feat_fv = F.normalize(feat_fv, dim=1) # 归一化视觉特征 feat_fi = F.normalize(feat_fi, dim=1) # 归一化跨模态特征 feat_v = F.normalize(feat_v, dim=1) # 归一化视觉全局特征 feat_i = F.normalize(feat_i, dim=1) # 归一化跨模态全局特征 ``` 目的:将特征投影到单位球面,使余弦相似度计算等价于点积运算 2. **正样本相似度计算** ```python l_pos_v = torch.bmm(feat_fv.view(batchSize, 1, -1), feat_v.view(batchSize, -1, 1)) l_pos_i = torch.bmm(feat_fi.view(batchSize, 1, -1), feat_i.view(batchSize, -1, 1)) ``` 作用:计算每个样本的视觉-视觉和跨模态-跨模态的相似度得分 3. **动态负样本选择** ```python for b in range(batchSize): if l_pos_v[b] >= l_pos_i[b]: # 选择更可靠的特征来源 # 使用视觉特征计算负样本 feat_v_without_pos = feat_v[torch.arange(feat_v.size(0)) != b] ... else: # 使用跨模态特征计算负样本 feat_i_without_pos = feat_i[torch.arange(feat_i.size(0)) != b] ... ``` 创新点:根据正样本相似度的比较结果,动态选择不同模态的特征进行负样本挖掘 4. **损失计算** ```python out = torch.cat((l_pos, l_neg), dim=1) / T loss = self.cross_entropy_loss(out, torch.zeros(...)) ``` 核心机制:构建InfoNCE损失,温度系数T用于调节概率分布的尖锐程度
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

静静喜欢大白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值