长尾分布系列论文解析(三)On Multi-Domain Long-Tailed Recognition, Imbalanced Domain Generalization and Beyond

多域长尾学习
针对多域长尾分布问题,提出BoDA算法,通过优化域间类别信息的可转移性,提升模型在不同域间的表现及泛化能力。

引言

 本文是长尾分布系列论文解析的第三篇,前两篇分别关注了传统分类问题中的长尾分布:长尾分布系列论文解析(一)Decoupling Representation and Classifier for Long-Tailed Recognition以及回归问题中的长尾分布长尾分布系列论文解析(二)Delving into Deep Imbalanced Regression本篇要介绍的是多域学习任务中的长尾分布问题,相关论文为:

多域学习中的长尾分布

 分类问题和回归问题中的长尾都旨在解决同一个域的问题,也就是训练集和测试集的数据都来自于同一个总体(但实际上还是很疑惑为什么要在balance的测试集上进行测试,这种情况下训练集和测试集真的算来自于同一分布吗?)。而现实中不同域间往往存在着不同、但是又可以彼此借鉴的长尾分布,比如说同样的动物分类数据集,素描的图像和拍摄的图像可能有着不同的长尾分布,但从分类的角度来看二者的知识是可以迁移的。本文所研究的问题就是这一条件下的MDLT(Muliti-Domain Long-Tailed Recognition),旨在训练模型从含有不同不平衡标签分布的域中学习共通的信息,并将训练出的模型迁移到同一系列域但是标签分布的测试集中。
 MDLT算是MDL(Multi-Domain Learing)的子课题,这里需要稍微区分一下MDL和DA(domain adaptation)以及DG(Domain Generalization)的区别。DA旨在提升模型在单一的目标域上的表现,也就是存在着源域和目标域的区别;而MDL旨在提升模型在所有域上的表现;DG则是期望将模型泛化到一个全新的域中,这一域只会在测试时出现。本文则主要关注于MDL中不同域可能存在的不平衡标签分布问题,同时进一步将这一问题拓展到了DG方向,证明了DG领域也需要考虑域内不平衡分布差异性的问题。
 文章的主要贡献在于:

  1. 定义了MDDLT问题,并给出了相应的优化方法BoDA,同时在理论和实验上都证明了BoDA算法的有效性。
  2. 将BoDA算法应用至DG问题上,证明了DG方向的域内不平衡分布差异性同样值得关注。

域间类别信息可转移性图

 在单域的不平衡分布中,最基本的单元是类别,而在MDLT问题中,最基本的单元是域-类对 ( d , c ) (d,c) (d,c)。作为迁移学习的子问题,MDLT关心的是利用同类的域类对获得相应类别的典型信息,其核心问题是如何进行域间的信息整合,而这一点在MDL问题中已经得到了广泛的研究。MDLT则是将其更细化的考量到如果不同域间分布不同,那么该如何依据这一差异性做出不同的迁移,这就设计到了度量不同域-类对间的可转移性。作者定义了域-类对间的可转移性为:
t r a n s ( ( d , c ) , ( d ′ , c ′ ) ) ≜ E z ∈ Z d , c [ d ( z , μ d ′ c ′ ) ] trans((d,c),(d',c'))\triangleq \mathbb{E}_{z\in \mathbf{Z}_{d,c}}[\mathbf{d}(z,\mu_{d'c'})] trans((d,c),(d,c))EzZd,c[d(z,μd

### 解耦表示与分类器的实现细节 在论文 *Decoupling Representation and Classifier for Long-Tailed Recognition* 中,作者提出了一种解耦特征表示和分类器的训练策略,以应对长尾数据分布带来的类别不平衡问题。论文的实现细节主要围绕两个阶段展开:**联合训练阶段** 和 **解耦训练阶段**。 #### 联合训练阶段(Joint Training) 在联合训练阶段,网络的特征提取器(backbone)和分类器(classifier)同时进行训练。此阶段的目标是学习一个能够区分各类别的通用特征表示,同时训练一个初步的分类器。训练过程中使用了不同的采样策略,包括: - **实例平衡采样(Instance-balanced sampling)**:对所有样本均匀采样。 - **类别平衡采样(Class-balanced sampling)**:对每个类别采样相同数量的样本。 - **平方根采样(Square root sampling)**:每个类别的采样概率与其样本数的平方根成正比。 - **渐进平衡采样(Progressive-balanced sampling)**:先使用实例平衡采样,再切换到类别平衡采样。 损失函数使用的是标准的交叉熵损失(Cross-Entropy Loss),即: ```python criterion = nn.CrossEntropyLoss() ``` 在 PyTorch 中,联合训练的代码结构大致如下: ```python for epoch in range(joint_epochs): for images, labels in train_loader: features = backbone(images) outputs = classifier(features) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() ``` #### 解耦训练阶段(Decoupled Training) 在解耦训练阶段,特征提取器被冻结,仅对分类器进行微调。该阶段的目的是通过调整分类器来适应长尾数据分布,而不影响已经学习到的特征表示。 ##### 1. **类别均值分类器(NCM:Nearest Class Mean)** 在该策略中,首先计算每个类别的特征均值,然后在测试阶段使用最近邻方法(如欧氏距离或余弦相似度)进行分类。 ```python # 计算每个类别的特征均值 class_means = compute_class_means(backbone, train_loader) # 测试阶段使用最近邻分类 def predict(feature): distances = [torch.norm(feature - mean) for mean in class_means] return torch.argmin(distances) ``` ##### 2. **τ-归一化分类器(τ-normalized classifier)** τ-归一化分类器通过归一化分类器权重来调整决策边界,缓解类别不平衡问题。归一化后的权重计算如下: $$ \tilde{w_i} = \frac{w_i}{||w_i||^{\tau}} $$ 其中 $\tau$ 是一个可调参数,通常设置为 1,即 L2 归一化。 在 PyTorch 中,τ-归一化可以通过以下方式实现: ```python def apply_tau_normalization(classifier, tau=1.0): with torch.no_grad(): weights = classifier.weight norm = torch.norm(weights, dim=1, keepdim=True) normalized_weights = weights / (norm ** tau) classifier.weight.copy_(normalized_weights) ``` 随后,使用类别均等采样重新训练分类器,通常不使用偏置项: ```python for epoch in range(decoupled_epochs): for images, labels in class_balanced_loader: features = backbone(images).detach() # 冻结特征提取器 outputs = classifier(features) loss = criterion(outputs, labels) optimizer_decoupled.zero_grad() loss.backward() optimizer_decoupled.step() ``` ##### 3. **LWS(Learnable Weight Scaling)** LWS 是 τ-归一化的扩展,其中缩放因子 $f_i$ 是可学习参数。该方法通过在解耦阶段学习每个类别的缩放因子来优化分类器的决策边界。 ```python # 定义可学习的缩放因子 scaling_factors = nn.Parameter(torch.ones(num_classes)) # 在损失反向传播时,仅更新 scaling_factors optimizer_lws = torch.optim.SGD([scaling_factors], lr=lw_lr) for epoch in range(lws_epochs): for images, labels in class_balanced_loader: features = backbone(images).detach() logits = classifier(features) scaled_logits = logits * scaling_factors.unsqueeze(0) loss = criterion(scaled_logits, labels) optimizer_lws.zero_grad() loss.backward() optimizer_lws.step() ``` #### 代码结构总结 整个训练流程可以分为以下几个步骤: 1. **联合训练特征提取器和分类器**,使用不同的采样策略。 2. **冻结特征提取器**,进入解耦阶段。 3. **使用类别均等采样重新训练分类器**,采用 τ-归一化或 LWS 策略。 4. **在测试集上评估模型性能**,使用 NCM、τ-归一化或 LWS 分类器。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值