Fine-grained Recognition with Learnable Semantic Data Augmentation
Abstract
- 细粒度图像识别是一个长期的计算机视觉挑战,其重点是区分属于同一元类别内多个从属类别的对象。由于属于同一元类别的图像通常具有相似的视觉外观,挖掘有区别的视觉线索是区分细粒度类别的关键。虽然常用的图像级数据增强技术在一般的图像分类问题上取得了巨大的成功,但它们很少应用于细粒度的场景,因为它们的随机编辑区域行为容易破坏驻留在微妙区域中的有区别的视觉线索。在本文中,我们提出在特征级多样化训练数据,以缓解区分区域丢失问题。具体来说,我们通过沿着语义有意义的方向翻译图像特征来产生多样化的增强样本。语义方向通过协方差预测网络来估计,该网络预测样本协方差矩阵以适应细粒度图像中固有的大的类内变化。此外,协方差预测网络以元学习的方式与分类网络联合优化,以缓解退化解问题。在四个有竞争力的细粒度识别基准(CUB200-2011,Stanford Cars,FGVC Aircrafts,NABirds)上的实验表明,我们的方法显著提高了几个流行的分类网络(如ResNets,DenseNets,EfficientNets,RegNets和ViT)的泛化性能。结合最近提出的方法,我们的语义数据增强方法在CUB-2002011数据集上实现了最先进的性能。源代码将会发布 [GitHub - LeapLabTHU/LearnableISDA: IEEE TIP] Fine-grained Recognition with Learnable Semantic Data Augmentation。
- 论文地址:[2309.00399] Fine-grained Recognition with Learnable Semantic Data Augmentation
- 核心思想是在特征空间中对训练样本进行增强,而非在图像空间中进行传统的数据增强操作。通过这种方式,可以避免图像级数据增强可能带来的判别区域损失问题。具体来说,该方法通过协方差预测网络(CovNet)预测每个训练样本的语义方向,然后沿着这些方向在特征空间中对样本进行变换,从而生成多样化的增强样本。这种方法不仅能够保留图像中的判别性细节,还能提高模型对细粒度类别差异的识别能力。
- 该方法的数学原理主要基于隐式语义数据增强(ISDA)框架。对于每个训练样本,其深度特征被表示为向量,协方差预测网络预测该样本的协方差矩阵,该矩阵定义了特征空间中的语义方向。通过在这些方向上对特征进行变换,可以生成增强后的特征。具体来说,对于样本 i,其增强后的特征 a m i am_i ami 服从高斯分布 N ( a i , λ Σ g i ) N(ai, λΣg_i) N(ai,λΣgi),其中 ai 是原始特征,λ是增强强度, Σ g i Σg_i Σgi 是由协方差预测网络预测的协方差矩阵。通过优化ISDA损失函数,可以学习到合适的协方差矩阵,从而实现有效的特征级数据增强。
- 图像级数据增强的局限性:传统的图像级数据增强技术(如随机裁剪、混合、擦除等)在细粒度图像分类任务中存在判别区域损失问题,可能导致模型性能下降。特征级数据增强的优势:通过在特征空间中进行数据增强,可以避免图像级增强的弊端,保留图像中的判别性细节,提高模型对细粒度类别差异的识别能力。可学习语义数据增强的必要性:通过协方差预测网络自动学习样本特定的语义方向,能够更好地适应细粒度图像的类内变异和类间相似性,提高数据增强的效果。
INTRODUCTION
-
细粒度图像识别旨在区分同一大类中视觉外观有细微差异的对象,例如不同种类的动物 ,不同型号的飞机 ,不同种类的零售产品 。因此,关键的挑战在于理解细粒度的视觉差异,这些差异足以区分整体外观高度相似但细微特征不同的对象 。近年来,深度学习 已经成为学习区分性图像表示的强大工具,并在细粒度视觉识别领域取得了巨大成功 。
-
随着深度神经网络主导视觉对象识别领域 ,数据增强技术进一步增强了神经网络在通用图像分类场景中的泛化能力。流行的数据增强技术,如Mixup 、CutMix 、RandAugment 和随机擦除 ,已经成为训练现代卷积网络 和视觉 Transformer 的标准方法。然而,在细粒度图像识别的场景中,由于区分性区域丢失问题,这些数据扩充技术很少被应用。具体地,如图1所示,图像级数据增强方法的随机编辑行为具有破坏区别区域的风险,这在执行细粒度识别中具有重要意义。
-
-
图一。区别性区域丢失问题的一个例子。(a)原始图像分别属于北极燕鸥和普通燕鸥类别。它们之间的主要视觉差异是喙的颜色(普通燕鸥的喙尖是黑色的,而北极燕鸥没有)。(b)通过一些流行的图像级数据增强技术增强的图像样本。这些技术中继承的随机编辑区域行为可能会损害细粒度图像的区分区域(例如tern的bill)。此外,CutMix的随机裁剪和粘贴行为甚至可以用另一个类的临界区域替换临界区域。因此,图像级别的数据扩充方法可能会导致嘈杂的标签,从而降低细粒度场景中的模型性能。
-
-
例如,基于随机丢弃的数据扩充,如剪切、随机擦除,有可能丢弃细粒度对象的区分区域。包含在AutoAugment 和RandAugment 中的几何变换也很可能导致辨别视觉线索的损失。此外,基于混合的技术(例如Mixup ,CutMix )甚至会通过用另一类的区别区域替换当前图像的区别区域而导致噪声标签问题。图2 (a)进一步显示了图像级增强技术在特征空间中的这种局限性:图像级增强图像的深层特征可能分布在分类边界上,甚至侵入另一类别的特征空间。
-
-
图二.图像级数据增强和特征级数据增强之间的区别。图像级数据增强的随机编辑行为容易破坏细粒度图像的可分辨细微区域。特征级数据扩充通过直接将深层特征转换成特征空间中有意义的方向来缓解这个问题。
-
-
为了解决上述问题,我们建议在特征级(图2 (b))而不是在图像级增加训练样本。通过在深度特征空间中沿着它们相应的有意义的语义方向平移数据样本,特征级数据增强将产生多样化的增强图像特征,其对应于像素空间中的语义有意义的图像。以这种方式,隐式数据增强方法减轻了由图像级数据增强技术的随机编辑方式引起的区别性区域丢失问题。
-
隐式数据增强技术的性能很大程度上依赖于语义方向的质量。现有的特征级数据增强方法(隐式语义数据增强,ISDA )证实,在通用图像分类问题中,所有类别共享的全局语义方向集不如为每个类别维护多个语义方向集。因此,ISDA 将深度特征的类别条件协方差矩阵作为每个类别的候选语义方向,并以在线方式统计估计协方差矩阵。然而,在细粒度场景中,ISDA 中的增强方法的限制是双重的:1)由于每个类中训练数据的数量有限,在线估计策略是次优的;2)类别条件语义方向由于其大的类内变化和小的类间变化而不适合于细粒度识别。具体地,由于大的类内方差,同一子类内的图像样本的有意义的语义方向不同。例如,在图3中,降落的鸟具有一些有意义的语义方向,而飞翔的鸟没有,反之亦然。因此,沿着同一组语义方向扩充一个子类别中的所有样本是不合适的。直观上,沿着它们相应的语义方向多样化不同的训练样本是优选的。
-
-
图3。同一从属类别(北极燕鸥)内不同图像样本的语义方向示例。(A)着陆的北极燕鸥有低头、张开翅膀和进食的语义转换,而飞行的燕鸥没有。这是因为一只飞翔的鸟在展开翅膀后不能吃东西、低头或展开翅膀。(b)飞行的北极燕鸥具有着陆、潜水和捕鱼的语义转换,而陆地上的鸟类不能在湖中捕鱼、在空中潜水或再次着陆。
-
-
本文针对细粒度图像识别问题,提出了一种可学习的语义数据扩充方法。基于协方差矩阵预测网络(CovNet ),以样本方式自动学习有意义的语义方向,而不是使用统计方法估计类别条件。CovNet接受每个训练样本的深层特征,并预测它们有意义的语义方向。协方差矩阵预测网络和分类网络以元学习的方式联合训练。元学习框架以不同的目标以交替的方式优化这两个网络,这解决了当联合优化它们时的退化问题(参见第2节中的理论和经验分析)。III-B和Sec。分别是IV-D)。与在线估计方法[ISDA ]相比,我们提出的基于样本的预测方法可以有效地为每个训练样本产生适当的语义方向,从而提高细粒度图像分类任务中的网络性能。
-
我们在四个流行的细粒度图像识别基准(即CUB-200-2011 、Stanford Cars 、FGVC air carts 和 NABirds )上评估了我们的方法。实验结果表明,我们的方法有效地增强了学习特征的类内紧密性,并显著提高了主流分类网络(如ResNet ,DenseNet ,EfficientNet ,RegNet 和ViT )在各种细粒度分类数据集上的性能。结合最近提出的细粒度识别方法(P2P-Net ),提出的方法在CUB-200-2011上实现了最先进的性能。
RELATED WORK
-
细粒度的识别。细粒度图像识别旨在区分众多视觉上相似的从属类别,这些类别属于同一基本类别。由于区分性区域定位和细粒度特征学习的挑战,识别细粒度类别是困难的。概括地说,现有的细粒度识别方法可以分为两种主要模式:定位方法和特征编码方法。前者通常创建模型来捕获细粒度对象的区别性语义部分,然后构建与这些部分对应的中间层表示以用于最终分类。常见的方法可分为采用检测或分割技术、利用深度过滤器 和利用注意力机制 。特征编码方法旨在学习一种统一但有区别的图像表示,用于对细粒度类别之间的细微差异进行建模。常见的做法包括执行高阶特征交互 和设计新颖的损失函数[The devil is in the channels: Mutual-channel loss for fine-grained image classification]、[Maximum-entropy fine grained classification;Fine-grained recognition: Accounting for subtle differences between similar classes;Learning attentive pairwise interaction for fine-grained classification]。然而,由于图像级数据增强技术往往对细粒度图像的细微区分区域有害,因此很少探索针对细粒度视觉任务的数据增强策略的设计。
-
数据增强。近年来,数据增强技术已广泛用于训练深度神经网络 。基本的数据扩充,如旋转、平移、裁剪、翻转,通常用于增加训练样本的多样性。除此之外,Cutout 、Mixup 和CutMix 是利用领域知识手工设计。最近,受神经架构搜索算法的启发,一些工作试图自动学习数据增强策略,如AutoAugment 和RandAugment 。虽然这些数据扩充方法是常用的,并且其中一些甚至已经成为在一般分类问题中训练深度神经网络的例行程序,但是它们很少在细粒度场景中被采用,因为图像级的随机裁剪、混合和变形操作将容易破坏细粒度对象的区分信息。
-
受最近提出的技术[Implicit semantic data augmentation for deep networks]的启发,最近的研究通过应用特征级数据增强来增强长尾识别问题中的少数类(MetaSAug ),并通过生成与目标语义一致的源特征来增强分类器在域适应中的适应性(TSA ),从而取得了重大成功。这些方法展示了在他们的问题中实现最先进性能的能力。相比之下,本文重点关注长期存在的细粒度识别问题,并提出了ISDA 的一个重要扩展,旨在通过在特征级别增加训练数据来解决区别性区域丢失问题。
-
元学习。近几年来,元学习领域引起了人们极大的兴趣。与用固定学习算法解决优化问题的传统深度学习方法相反,元学习旨在改进学习算法本身。在元学习框架下,机器学习模型可以通过多次学习获得经验,并使用这种经验来提高其未来的学习性能。元学习已被证明在多任务场景和单任务场景中都是有用的,在多任务场景中,从一系列任务中提取任务不可知的知识,并用于改进该系列任务中新任务的学习,在单任务场景中,单个问题被重复解决并在多个情节中得到改进。成功的应用已经在横跨少数样本图像识别,无监督学习,数据高效 和自我导向 强化学习,超参数优化,领域概化人ReID 和神经架构搜索的领域中得到证明。本文设计了一种单任务元学习算法,在分类模型训练过程中,为每个训练样本学习有意义的语义方向。
-
元学习(学习如何学习):教会模型快速适应新任务(类似 “学习能力”),少量数据即可快速适应新任务,减少对大规模标注数据的依赖;需要大量 “元训练数据”(各种不同任务),模型复杂度高。常与小样本学习结合使用
-
迁移学习(知识搬家):把 A 任务的知识迁移到 B 任务,用识别动物的模型改进人脸识别(底层特征如边缘检测可复用),节省时间和计算资源,解决数据不足问题;领域差异大时效果下降(如从图片迁移到文本),可能引入负迁移。与小样本学习结合(预训练模型 + 少量新数据)
-
度量学习(相似性测量):让模型学会衡量事物相似度,比如人脸识别系统判断两张照片是否同一人,能够提升分类 / 检索精度,适用于图像、文本等多模态;依赖高质量特征工程,对噪声敏感
METHOD
- 在本节中,我们首先介绍我们方法的预备知识,隐式语义数据增强(ISDA) 及其协方差矩阵的在线估计算法。然后,我们将介绍基于元学习的框架。我们进一步给出了我们提出的元学习算法的收敛性证明。为了提高可读性,我们在表1中列出了本文中使用的符号。
-
-
表一本文中使用的符号
-
A. Implicit Semantic Data Augmentation
-
大多数传统的数据扩充方法直接在训练图像上进行修改。相比之下,ISDA在特征级执行数据扩充,即,沿着有意义的语义方向翻译图像特征。基于深度特征的协方差矩阵来确定这样的方向。具体来说,对于C类分类问题,ISDA 统计估计了类协方差矩阵 ∑ ^ = { ∑ ^ 1 , ∑ ^ 2 , . . . , ∑ ^ C } \hat\sum= \{\hat\sum_1,\hat\sum_2,...,\hat\sum_C \} ∑^={∑^1,∑^2,...,∑^C} 在每个训练迭代中以在线方式进行。对于具有基本事实 yi 的第 i 个样本 xi,ISDA从高斯分布 N ( 0 , λ ∑ ^ y i ) N (0,λ\hat\sum y_i) N(0,λ∑^yi) 随机采样变换方向,以增强深度特征 ai,其中 ai 是将被馈送到深度网络中的最后全连接层的学习特征,λ 是控制增强强度的超参数。应该对 N ( 0 , λ ∑ ^ y i ) N (0,λ\hat\sum y_i) N(0,λ∑^yi) 中的大量(M个)方向进行采样,以获得充分增强的特征 a i m ~ N ( a i , λ ∑ ^ y i ) , m = 1 , 2 , . . . , M a^m_i~N(a_i,λ\hat\sum y_i),m = 1,2,...,M aim~N(ai,λ∑^yi),m=1,2,...,M。这些增强数据上的修改的交叉熵损失可以写为
-
ℓ M = 1 M ∑ m = 1 M − l o g ( e x p ( w y i T a i m + b y i ) ∑ j = 1 C e w j T a i m + b j ) , ( 1 ) ℓ_M =\frac 1 M\sum ^M _{m=1} − log (\frac {exp(w^T _{y_i} a^m_i +b_{yi})} {\sum^C _{j=1} e ^{w^T _j a^m_ i +b_j}}) , (1) ℓM=M1m=1∑M−log(∑j=1CewjTaim+bjexp(wyiTaim+byi)),(1)
-
其中 [ w 1 , . . . , w C ] T [w_1,...,w_C ]^ T [w1,...,wC]T 和 [ b 1 , . . . , b C ] T [b_1,...,b_C ]^ T [b1,...,bC]T 是最后一个全连接层的可训练参数,M 是采样方向的数量。更进一步,如果对无限个方向进行采样,ISDA 推导出所有增强特征的预期交叉熵损失的上限:
-
-
其中 v j y i = w j − w y i v_{jy_i} = w_j -w_{y_i} vjyi=wj−wyi ,上限定义为 ISDA 损失 ℓ ISDA。通过优化上限 ℓ ISDA,有效地实现了特征级语义增强过程。等价地,ISDA可以被视为一种新的鲁棒损失函数,它与任何具有交叉熵损失的神经网络结构训练兼容。
-
-
class ISDALoss(nn.Module): def __init__(self, feature_num, class_num, local_rank): super(ISDALoss, self).__init__() self.class_num = class_num self.cross_entropy = nn.CrossEntropyLoss().cuda(local_rank) self.local_rank = local_rank def isda_aug(self, linear_layer, features, labels, cv_matrix, ratio): N = features.size(0) # batch size C = self.class_num # number of class (200 for CUB-200-2011) A = features.size(1) # feature dimension (2048 for ResNet50) weight_m = list(linear_layer.parameters())[0] # weight of Linear, shape = [200, 2048] = [C, A] NxW_ij = weight_m.expand(N, C, A) # shape=[8, 200, 2048] = [N, C, A] (copy weight_m for N times) NxW_kj = torch.gather(NxW_ij,1,labels.view(N, 1, 1).expand(N, C, A)) # shape = [8, 200, 2048] = [N, C, A] CV_temp = cv_matrix sigma2 = ratio \ * torch.mul( (weight_m - NxW_kj).pow(2), CV_temp.view(N, 1, A).expand(N, C, A), ).sum(2) logits = torch.nn.functional.linear(features, weight=linear_layer.weight, bias=linear_layer.bias) aug_logits = logits + 0.5 * sigma2 return logits, aug_logits def forward(self, linear_layer, features, labels, ratio, cv_matrix): # # 隐式扰动生成 logits, aug_logits = self.isda_aug(linear_layer, features, labels, cv_matrix, ratio) # 扰动增强后的分类 loss = self.cross_entropy(aug_logits, labels) return loss, logits # Δ = Σ_c^(1/2) * N(0,I) # 传统ISDA # Δ_learnable = M(features) # 本方案改进,其中M为元网络,将固定协方差Σ替换为特征自适应的动态矩阵
B. Covariance Matrix Prediction Network
-
前述 ISDA 的性能严重依赖于估计的类方式协方差矩阵,这直接影响语义方向的质量。在细粒度视觉识别场景中,有限的训练数据量及其大的类内方差和小的类间方差特性,对协方差估计提出了巨大的挑战。不令人满意的协方差矩阵会进一步导致模型性能的有限改善。为此,我们提出基于协方差矩阵预测网络自动学习样本语义方向,而不是像现有方法中那样统计估计类别协方差矩阵。我们的协方差矩阵预测网络(CovNet)建立为多层感知(MLP),记为 g ( ⋅ ; θ g ) g(·;θg) g(⋅;θg) 由 θg 参数化。CovNet以深度特征 ai 作为输入,并预测其样本语义方向: ∑ i g = g ( a i ; θ g ) \sum^g_i = g(ai;θg) ∑ig=g(ai;θg)。因此,具有我们预测的协方差矩阵的ISDA损失函数可以重写为
-
-
其中 a i = f b ( x i ; θ f b ) a_i = f ^b(x_i;θ_{f ^b}) ai=fb(xi;θfb) 是 fb 提取的深度特征, θ f h = { [ w 1 , . . . , w C ] T , [ b 1 , . . . , b C ] T } θ_{f^h} = \{[w_1,...,w_C ] ^T,[b_1,...,b_C ]^ T \} θfh={[w1,...,wC]T,[b1,...,bC]T} 是指分类头(全连接层)的参数。在实践中,由于GPU内存限制,CovNet仅预测协方差矩阵的对角元素,我们按照将所有其他元素设置为零。我们在g的最后一层使用Sigmoid激活来确保产生的协方差矩阵是正定的。
-
-
值得注意的是,如果我们用等式中的损失函数同时优化协方差矩阵预测网络 g 和分类网络 f。由于协方差矩阵 ∑ i \sum_i ∑i 是正定的,将项 λ 2 v j y i T ∑ I g v j y i \frac λ2v ^T _{jyi}\sum ^g _I v_{jy_i} 2λvjyiT∑Igvjyi 添加到分母将总是增加损失值:
-
-
因此,简单的联合训练策略将微不足道地鼓励 CovNet 产生零值矩阵 ∑ i g \sum^g_i ∑ig,并且将获得分类准确度的有限改进(参见IV-D部分中的结果)。
-
C. The Meta-learning Method
-
我们提出了一个基于元学习的方法来处理退化解决方案的问题,如方程式(4).通过设置元学习目标并用元梯度优化 g,CovNet g 可以通过从元数据中挖掘元知识来学习产生适当的协方差矩阵。在这一小节中,我们首先分别制定分类网络 f 和 CovNet g 的正向传递和训练目标。然后给出了两个网络的详细优化流程。
-
1)元学习目标:利用我们的学习协方差矩阵方案,分类网络参数θf的优化目标是在学习协方差矩阵下最小化ISDA损失。用训练数据优化分类网络 θf。给定一个训练样本 xi,特征提取器 fb (分类网络 f 的主干)产生它的特征 a i = f b ( x i ; θ f b ) a_i = f^b(x_i;θ_{f_b}) ai=fb(xi;θfb)。对应的协方差矩阵 ∑ i g = g ( a i ; θ g ) \sum^g_i = g(ai;θg) ∑ig=g(ai;θg) 通过将深度特征ai馈入CovNet来预测,并作为ISDA损失函数的参数。训练样本的损失可以公式化为 l I S D A ( x i , y i ; ∑ i g ( θ g ) , θ f ) l^{ISDA}(x_i,y_i;\sum^g_i(θg),θf) lISDA(xi,yi;∑ig(θg),θf)。因此,整个训练数据集的训练损失为
-
-
其中N1是训练数据的数量。分类网络 θf 的优化目标是在学习协方差矩阵 ∑ i g \sum^g_i ∑ig 下最小化训练损失
-
θ f ∗ ( θ g ) = a r g min θ f L t r a i n ( θ f ; θ g ) . θ ^∗ _f (θ_g) = arg \min _{θ_f} L ^{train}(θf ; θg). θf∗(θg)=argθfminLtrain(θf;θg).
-
从等式(6)可以观察到。优化的 θ f ∗ \theta^*_f θf∗ 是CovNet θg的参数的函数
-
CovNet θg的网络参数是用元学习方法学习的。我们使用来自元数据集 { x i ( m e t a ) , y i ( m e t a ) } i = 1 N 2 \{x ^{(meta)}_ i,y ^{(meta)}_ i \} ^{N_2} _{i=1} {xi(meta),yi(meta)}i=1N2 的元数据来优化CovNet。元损失是网络预测 y ^ i ( m e t a ) \hat y^{(meta)}_i y^i(meta) 和相应的基本事实 y i ( m e t a ) y^{(meta)}_i yi(meta)之间的交叉熵损失
-
其中 N2 表示元集的样本数, y ( m e t a ) I = f ( x ( m e t a ) I ; θ f ( θ g ) ) y(meta)I = f(x(meta)I;θf (θg)) y(meta)I=f(x(meta)I;θf(θg)) 是元样本x (meta) i的网络输出,ℓ CE(,)表示交叉熵损失。因此,通过最小化元学习目标L meta来获得CovNet θg的最优参数
- θ g ∗ = a r g min θ g L m e t a ( θ f ( θ g ) ) . ( 8 ) θ^ ∗ _g = arg \min _{θg} L^ {meta} (θ_f (θ_g)).(8) θg∗=argθgminLmeta(θf(θg)).(8)
-
由于CovNet g是通过元目标中的梯度算子反向传播元梯度来优化的,并且元目标是通过交叉熵损失而不是ISDA损失来建立的,因此退化问题(在等式(4)中示出)。当在一个梯度步骤中训练θf和θg时,具有相同优化目标的情况不会发生。
-
2)优化管道:在我们的元学习框架下,分类网络 θf 和协方差预测网络 θg 以嵌套的方式联合优化。具体地,CovNet θg由元数据在伪更新的分类网络\θf的基础上更新。构造伪更新分类网络\θf不仅是为了训练数据提供的梯度,也是为了在当前训练数据下找到合适的θg。在更新θg之后,分类网络使用由更新的θg预测的协方差矩阵进行实际更新。为了清楚起见,我们将元学习算法总结为三个阶段(如图5所示):分类网络的伪更新过程、CovNet的元更新过程和分类网络的实际更新过程。学习迭代中的详细优化过程如下所示。
-
-
图5。迭代 t 中的优化流水线,它包含三个步骤:(1)用训练样本伪更新分类网络θf;(2)协方差预测网络θg由伪更新的θˇf的梯度更新;(3) θf根据新的CovNet θ (t+1) g预测的协方差矩阵采取实际更新步骤
-
-
伪更新过程用训练数据更新分类网络。伪更新分类网络\θf仅作为每次优化迭代中的瞬态。它帮助元更新阶段的CovNet在当前一批训练数据下找到合适的参数,并提供梯度以构建元更新过程的计算图来计算元梯度。从第t次迭代的初始状态θ (t) f开始,分类网络使用训练数据在当前CovNet参数θ (t) g下采取伪更新步骤
-
θ f ∗ ( θ g ( t ) ) = a r g min θ f L t r a i n ( θ f ; θ g ( t ) ) . θ ^∗ _f (θ^{ (t)}_ g ) = arg \min _{θ_f} L ^{train}(θ_f ; θ ^{(t) }_g ). θf∗(θg(t))=argθfminLtrain(θf;θg(t)).
-
通过梯度下降更新的参数是
-
-
其中,αt是分类网络在当前时间步长t的学习速率。注意,伪更新过程仅更新分类网络。梯度不会反向传递到CovNet。参见图4(灰色虚线),该伪更新的梯度流。
-
-
图4。用于更新分类模型f和CovNet g的前向数据流和后向梯度流。我们首先计算ISDA损失(等式(5))并后退一步得到伪更新分类网络 θ ^ f \hat θ_ f θ^f (步骤1~3)。然后,计算元损失以更新θg(等式)。(7)、步骤4和5)。注意,分类头的参数θf h隐含地包含在ISDA损失中(等式3)。在步骤1中。
-
-
真正的更新过程基于更新的CovNet θ (t+1) g的预测来更新分类网络。更新的CovNet有助于预测每个训练样本的语义方向,并促进采用特征级数据增强的优化过程
-
θ f ∗ ( θ g ( t + 1 ) ) = a r g min θ f L t r a i n ( θ f ; θ g ( t + 1 ) ) . θ ^∗ _f (θ^{ (t+1)}_ g ) = arg \min _{θ_f} L ^{train}(θ_f ; θ ^{(t+1) }_g ). θf∗(θg(t+1))=argθfminLtrain(θf;θg(t+1)).
-
最后,通过采取优化步骤,我们可以得到更新的分类网络参数θ (t+1) f
-
θ f t + 1 ( θ g ( t + 1 ) ) = θ f ( t ) − α t Δ θ f L t r a i n ( θ f , θ g t + 1 ) ∣ θ g ( t ) \theta^{t+1}_f(θ^{ (t+1)}_ g ) = \theta^{(t)}_f-\alpha_t\Delta_{\theta_f}L^{train}(\theta_f,\theta^{t+1}_g)|_{\theta^{(t)}_g} θft+1(θg(t+1))=θf(t)−αtΔθfLtrain(θf,θgt+1)∣θg(t)
-
-
简而言之,在每次优化迭代中,CovNet通过由\θf提供的伪梯度来更新。然后,分类网络使用更新的CovNet获得真正的优化步骤。这两个网络在我们提出的元学习方法下交替优化。与需要独立元数据集的现有元学习方法相反,遵循最近的元学习技术,我们简单地重用训练数据集作为我们的元数据集。在我们的基于批的优化算法中,训练批和元批是完全不同的。具体来说,在每次训练迭代中,我们从训练集中采样一批数据X,并将其分成训练批X和元批X(meta)。在一次优化迭代之后,我们交换X和X(meta)来重用它们。我们总结了算法1中的学习算法,并在图5中示出了训练流水线。
D. Convergence of The Meta-learning Algorithm
- 提出的基于元学习的算法涉及一个双层优化过程。我们证明了在一定的条件下,我们的方法收敛于训练损失和元损失的临界点。具体来说,我们证明了元损失梯度的期望在有限步内将小于一个无穷小量,并且训练损失梯度的期望将收敛到零。这些定理被证明如下。完整的证据在附录a中。
- 定理1。假设ISDA损失函数ℓ ISDA和交叉熵损失函数ℓ CE都是可微的,具有常数l的Lipschitz连续的,并且相对于训练/元数据具有ρ有界的梯度。学习率满足
a
t
=
m
i
n
{
1
,
k
T
}
a_t = min\{1,\frac k T \}
at=min{1,Tk},对于某些k > 0,使得
k
T
<
1
\frac k T < 1
Tk<1。元学习率βt(1 < t < N)是单调下降序列。
β
t
=
m
i
n
{
1
L
,
c
σ
√
T
}
βt = min\{ \frac 1 L,\frac c {σ √ T} \}
βt=min{L1,σ√Tc} 对于某些c > 0,使得
σ
√
T
c
≥
L
\frac{σ √ T} c ≥ L
cσ√T≥L 且
∑
t
=
1
∞
β
t
≤
∞
,
∑
t
=
1
∞
β
t
2
≤
∞
\sum^∞ _{t=1} βt ≤ ∞,\sum^∞ _{t=1} β ^2_ t ≤ ∞
∑t=1∞βt≤∞,∑t=1∞βt2≤∞。然后
-
1)所提出的算法总是能够实现 ,in T steps.
-
-
2)训练损失是收敛的
-
-
E. Accelerating the meta-learning framework
-
元更新过程的成本相对较高,因为更新θg需要计算二阶梯度(见等式)。(12)).为了使训练过程更有效,我们采用了一种近似方法,通过冻结部分分类网络来加速元更新过程。在伪更新过程中,我们冻结前几个块,只有后面的块才会有梯度。因此,在元更新过程中,元梯度将仅根据伪网络子集的梯度来计算。这样,算法在不牺牲模型性能的情况下,显著提高了训练效率。
-
学习流程主要包括三个阶段:分类网络的伪更新、协方差预测网络(CovNet)的元更新以及分类网络的真实更新。这三个阶段在每次迭代中交替进行,共同优化分类网络和CovNet,以实现有效的特征级数据增强和细粒度图像分类。
-
分类网络的伪更新:在每次迭代中,首先使用训练数据对分类网络进行伪更新。这一步骤的目的是基于当前的CovNet参数,对分类网络的参数进行临时调整,以便为后续的元更新提供一个更新后的状态。具体操作是通过计算ISDA损失函数的梯度,对分类网络的参数进行一次梯度下降更新,得到伪更新后的分类网络参数。
-
协方差预测网络(CovNet)的元更新:在分类网络伪更新的基础上,使用元数据对CovNet进行更新。这一步骤的目的是优化CovNet,使其能够生成更有利于分类任务的语义方向。通过计算元损失函数(通常是交叉熵损失)的梯度,对CovNet的参数进行更新。元损失函数基于伪更新后的分类网络在元数据上的表现。
-
分类网络的真实更新:在CovNet更新后,使用更新后的CovNet对分类网络进行真实更新。这一步骤的目的是基于新的语义方向,对分类网络进行实际的参数优化,以提高其分类性能。具体操作是通过计算ISDA损失函数的梯度,对分类网络的参数进行梯度下降更新,这次更新使用的是更新后的CovNet参数。
-
for epoch in epochs: for batch in loader: # 阶段1:p1训练,p2验证 pseudo_net = clone(model) # 参数复制 generate cv_matrix = meta_net(p1_features.detach()) compute pseudo_loss = ISDA(pseudo_net, p1, cv_matrix) pseudo_grads = grad(pseudo_loss, create_graph=True) pseudo_net = meta_step(pseudo_net, pseudo_grads) # 内环更新 meta_loss = CE_loss(pseudo_net(p2)) # 外环损失 update meta_net via meta_loss # 阶段2:交换数据角色 repeat with p2 training, p1 validation # 更新主网络 update model with combined losses
-
-
协方差预测网络(Covariance Prediction Network, CovNet):CovNet是一个多层感知机(MLP),用于根据分类网络提取的深度特征,预测每个训练样本的协方差矩阵。协方差矩阵定义了特征空间中的语义方向,用于指导特征级的数据增强。CovNet的输入是分类网络提取的特征向量,输出是一个协方差矩阵。在代码仓库中,CovNet的结构可以通过参数
meta_net_hidden_size
和meta_net_num_layers
进行设置。 -
元学习框架(Meta-learning Framework):元学习框架负责交替优化分类网络和CovNet。通过在元数据上进行优化,元学习框架确保CovNet能够生成有助于分类任务的语义方向。在每次迭代中,首先对分类网络进行伪更新,然后基于伪更新后的分类网络在元数据上的表现,更新CovNet的参数。最后,使用更新后的CovNet对分类网络进行真实更新。
EXPERIMENTS
- 在第本节中,我们在不同的细粒度视觉识别数据集上对我们的语义数据增强方法进行了经验评估。我们首先在IV-A部分介绍详细的实验设置,包括数据集和训练配置。然后在第IV-B节中展示了我们的方法在不同数据集上使用各种主干架构的主要结果。最后,消融研究(IV-D部分)、一般识别任务的实验结果(第七部分)和可视化结果(第四部分)进一步验证了所提出方法的有效性。
A. Experiment settings
-
数据集。我们在四个广泛使用的细粒度基准上评估了我们提出的方法,即CUB-200-2011 ,FGVC飞机,斯坦福汽车和NABirds 。CUB200-2011 是用于细粒度视觉分类任务的最广泛使用的数据集,它包含属于鸟类的200个子类别的11,788张照片,5,994张用于训练,5,794张用于测试。FGVC飞机数据集包含10,200张飞机图像,102种不同的飞机模型变体各有100张图像,其中大部分是飞机。斯坦福汽车 数据集包含196类汽车的16,185幅图像,并被分成8,144幅训练图像和8,041幅测试图像。NABirds数据集收集了北美常见的400种鸟类的48,000张带注释的照片。在我们的实验中,我们只使用类别标签作为监督,尽管一些数据集有额外的可用注释。
-
对于所有细粒度数据集,我们首先将图像大小调整为600 × 600像素,并将其裁剪为448 × 448分辨率(随机裁剪用于训练,中心裁剪用于测试),随后是随机水平翻转操作。实施细节对于所有的分类网络结构,我们从torchvision库加载预训练的网络,除了ViT 预训练的权重是在TransFG 之后取得的。我们使用随机梯度下降(SGD)优化器来训练分类网络θf,动量为0.9,权重衰减为0.0。分类网络的学习率被初始化为0.03,批量大小为64,以余弦形状衰减。除了与P2P-Net的组合实验以秒为单位之外,所有模型都被训练了100个时期。IV-C遵循[Fine-grained object classification via self-supervised pose alignment]中的设置。
-
协方差预测网络 θg 被建立为具有一个隐藏层的多层感知器。隐藏层的宽度设置为最终特征尺寸的四分之一。我们还提供了对 CovNet 结构的消融研究。由于高分辨率图像上的GPU内存限制,遵循原始隐式数据扩充方法[Implicit semantic data augmentation for deep networks]的实践,我们通过对角线近似协方差矩阵,即特征的每个维度的方差。我们还采用学习率为0.001的SGD优化器来优化θg。covnet仅用于训练,在推理过程中不会带来额外的计算开销。
B. Effectiveness with different datasets and architectures
-
我们在ResNet-50上将我们提出的特征级数据增强方法与仅使用基本数据增强(即随机水平翻转)的方法进行了比较。在上述细粒度数据集上的实验结果如表II所示。从结果中,我们发现我们的方法显著提高了分类网络在各种细粒度场景中的泛化能力,包括鸟类、飞机和汽车。具体来说,在最受欢迎的细粒度数据集CUB-200-2011上,与基线方法相比,所提出的方法在Top-1准确率上实现了2.2%的提高。在其他流行的细粒度数据集上,我们的方法也获得了超过1.2%的前1名精度改进。与使用类别方式估计的语义方向的语义数据增强相比,我们的样本方式预测方法显示了其在提高网络性能方面的优势。
-
-
表2,我们的方法在四个流行的细粒度数据集(CUB-200-2011,FGVC飞机,斯坦福汽车和NABIRDS)上的实验结果。表中的基本数据扩充是指随机水平翻转。
-
-
我们还将我们的方法应用于各种流行的分类网络架构,即 DenseNet ,EfficientNet ,MobileNetV2 ,RegNet ,Vision trans promer(ViT)。表III中的结果表明,我们的方法可以提高各种神经网络架构之间的细粒度分类精度的性能。具体来说,我们的方法可以将为服务器设计的网络(ResNet、DenseNet和EfficientNet)的性能提高超过1.0%的顶级准确性。对于面向移动设备的网络,我们的方法也可以获得显著的改善(对于MobileNetV2,准确率提高了1.7%;对于RegNetX400MF,准确率提高了1.2%)。我们的方法对最近提出的视觉 Transformer 架构也有效(ViT-B 16的精度提高了0.4%)。结果还表明,在细粒度的情况下,在各种神经网络架构中,基于样本的预测语义方向方法比基于类别的估计方法更有效。
-
-
表III 我们的方法在CUB-200-2011数据集上用不同的网络结构实现时的实验结果。
-
C. Comparisons with Competing Methods
-
与最先进技术的比较和兼容性。我们将我们提出的基于样本的预测语义数据增强方法与最近提出的细粒度识别技术P2P-Net 相结合。除了来自图像标签的监督之外,P2P-Net 还利用局部的有区别的部分来促进图像表示的区别,并且学习用于部分对准的图形匹配,以便减轻对象姿态的变化。P2P-Net 使用ResNet 作为基础模型,在CUB-200-2011数据集上实现了最先进的性能。
-
在P2P-Net 中,总共有S+1个分类器,其中前 S-1 个分类器附加到基本模型的 S-1 个中间特征图,第 S 个分类器将最终分类特征作为输入,最后一个分类器根据前面提到的所有特征的组合进行预测。为简单起见,我们仅将我们的方法与最终分类器的交叉熵损失相结合,并保持其他设置与P2P-Net相同。我们将增强强度 λ 0 λ_0 λ0 设置为5.0,并将CovNet构造为具有一个隐藏层的MLP,其大小是深度特征大小的一半。等式(12)中的元更新过程。出于训练效率的考虑,每十次迭代才出现一次。
-
实验结果见表4 。实验表明,结合我们提出的方法,P2P-Net在CUB-200-2011上取得了91.0%的Top-1准确率,比原始P2P-Net提高了0.8个百分点。这一结果验证了我们的方法与其他竞争方法相结合的有效性。
-
-
表4 在CUB-200-2011数据集上我们的方法与最先进的(SOTA)方法的比较
-
-
优于在线估计协方差。我们将基于元学习的样本协方差矩阵预测方法与ISDA 提出的类别在线估计技术进行了比较。当与P2P-Net 结合时,我们的方法显示出比ISDA 的在线估计技术更优越的性能(如表4所示)。我们进一步在CUB-200-2011上对不同深度的ResNets进行实验,结果如图6所示。我们可以从结果中观察到,虽然ISDA可以提高基线方法的泛化能力,但我们提出的策略可以进一步大幅度超过它。这一现象验证了我们的样本协方差矩阵预测优于细粒度场景下在线估计协方差的ISDA。
-
-
图6。在CUB-200-2011上与基本数据扩充(基线)、在线估计协方差矩阵的ISDA和我们的方法(ISDA与CovNet)进行比较。实验在不同深度的ResNet上进行(ResNet-{18,34,50,101,152})。
-
-
与图像级数据增强的比较。在表V中,我们比较了我们的方法和一些流行的图像级数据增强方法的性能。可以发现,在细粒度场景中,所提出的方法比图像级方法更有效。
-
-
表V 在CUB-200-2011数据集上我们的方法与图像级数据增强技术的比较
-
D. Ablation Studies
-
我们对我们的方法进行消融研究,以分析其变体如何影响细粒度视觉分类结果。我们首先展示同时优化协方差矩阵预测网络和分类网络(在第III-B节中提到)将如何产生零值输出。然后,我们消融增强λ的强度、λ的增长调度和所提出的CovNet的结构。最后,展示了通过冻结伪网络的一部分来加速元更新过程的效果。
-
1)没有元学习的朴素联合训练:我们用与第III-B节中描述的相同的目标来训练θf和θg,并且将θg的学习速率调整为θf的学习速率的比例。在图7(a)中,我们从两个角度显示了结果:每个时期结束时CovNet输出的平均值和相应的最终精度。如果学习率很大,CovNet输出的均值将很快收敛到零,并且在学习率很小的情况下趋于零,这验证了我们在第III-B节中的主张。虽然最终的分类精度略高于基线训练方法,但它不如ISDA ,并且明显差于我们提出的样本预测语义数据增强方法。
-
-
图7。(a)初次联合训练的消融研究。图中,lr表示θf的学习率,lr后面的数字是θg的学习率比例,acc表示实验结果。(b)关于数据增强强度λ0的消融研究。最好的数据增强强度在10.0左右。
-
-
2)增强强度λ的影响:在我们的工作中,增强强度λ随着训练历元 λ t = ( t / T ) × λ 0 λt = (t/T) × λ0 λt=(t/T)×λ0 线性增加,其中 λt 是当前历元的增强强度,T是当前历元的索引,T 是总训练历元,λ0是控制总增强强度的超参数。我们通过使用三种不同的模型(即,ResNet-50、DenseNet-161和MobileNetV2)在CUB-200-2011上进行实验来消除语义数据增强的强度。如图7(b)所示,随着 λ0 从零开始增加,精度逐渐增加,并在λ0 = 10.0附近达到峰值。因此,在我们的实验中,除了 P2P网络,我们简单地将λ0设置为10.0。尽管所提出的方法的性能受到增强强度λ0的影响,但是我们的方法总是优于基线(图7(b)中λ0 = 0)。
-
3 )λ的增长调度的影响:考虑到λ的简单线性增长策略可能不是最优的,我们通过调整调度函数 λ t = ( t / T ) α × λ 0 λt = (t/T) ^α × λ0 λt=(t/T)α×λ0 中的超参数α来消融λ的增长调度。图11 (a)示出了不同α的调度,图11 (b)示出了在具有CUB-200-2011的ResNet-50模型上演示的相应结果。结果表明,简单线性增长程序优于凸增长或凹增长程序。因此,我们为所有的实验选择了线性增长程序。
-
-
图11。增强强度λ增长计划的烧蚀研究。(a)是λ的不同调度策略的图解。调度函数为λt = (t/T) α × λ0,其中α控制调度曲线的形状。设置α = 1.0导致λ的线性增长计划。(b)通过在ResNet-50上改变α,不同λ调度的网络性能。
-
-
4)冻结块的影响:元学习框架引入了额外的训练成本,因为它有两个额外的更新步骤。伪更新过程与最终的真实更新过程花费大约相同的时间,而元更新过程花费更多的时间,因为它需要计算二阶梯度。在4个Nvidia V100 GPU服务器中,普通元学习算法需要6.5小时来训练CUB-200-2011中的ResNet-50模型100个历元,而基线方法需要1.7小时。我们冻结ResNet-50网络主干和前n个残差块,并在CUB-200-2011数据集上记录相应的精度和训练时间。图12中的结果表明,当0 ≤ n ≤ 12时,网络性能类似于没有冻结的对应物,而总训练时间是单调递减的。因此,我们冻结了ResNet-50的前十个残差块,用于所有细粒度的识别实验,以获得良好的准确性和效率的折衷。这样,CUB-2002-2011年的培训成本从6.5小时减少到4.5小时。值得一提的是,我们的方法没有增加任何额外的推理成本。对于其他神经网络结构,包括P2P-Net ,我们不冻结网络结构的任何部分,因为找到适当数量的冻结块需要额外的实验。
-
-
图12。冷冻块数的消融研究。水平坐标为 0 表示我们只冻结网络主干,水平坐标为16表示我们冻结整个网络,包括主干和ResNet-50的所有16个残差块,最后一个头除外。
-
-
5)covnet结构的影响:我们通过改变协方差矩阵预测网络的深度(隐藏层的数量)和宽度(隐藏层的神经元的数量)来消融其结构。使用ResNet-50在CUB-200-2011数据集上的实验结果(如表VI所示)表明,尽管不同的CovNet结构会影响结果,但整个方法仍然是有效的。实际上,对于所有模型架构,我们将隐藏层的深度设置为1,宽度设置为最终特征尺寸的四分之一,除非另有说明。
-
-
表六 COVNET结构的消融研究
-
E. Evaluation on Generic Recognition Benchmark
- 由于所提出的基于样本的特征级增强方法不依赖于额外的细粒度注释(如边界框、部分注释和层次标签),因此它可以很容易地适用于一般的图像分类。我们使用ResNet-50模型在ImageNet 上评估我们提出的方法。为了公平比较,我们保持与ISDA 相同的训练配置,其中模型从零开始训练120个时期,动量为0.9,权重衰减为0.0001。增强强度设定为7.5,也与ISDA相同。CovNet θg的架构配置与CUB-200-2011相同,每100次迭代优化一次,学习率为0.0005。表VII中的结果表明,在一般的图像识别问题上,我们的基于样本的语义数据增强方法也比基于类别的估计语义方向方法有效。
-
-
表7 IMAGENET上的实验结果。
-
F. Visualization Results
-
像素空间中的扩充样本。为了证明我们的方法能够生成有意义的语义增强样本,我们在四个细粒度数据集(CUB-200-2011、FGVC Aircraft、Stanford Cars和NABirds)上呈现了图像空间中增强特征的前5个最近邻居。如图8所示,我们的特征级数据扩充策略能够调整训练样本的语义,例如视觉角度、背景、鸟的姿态、飞机的绘画、汽车的颜色。
-
-
图8. 语义增强图像的可视化。在每个子图中,第一列是对应于原始特征的图像,接下来的列是对应于增强的原始特征的前5个最近特征的图像。
-
-
学习特征的质量。我们比较了使用基本数据扩充(基线)的训练和使用我们的方法的训练之间的学习特征质量。我们在CUB200-2011上选择包含五个以上子类的元类。我们分别使用基线方法和我们的特征级数据扩充方法学习的预训练网络来提取深层特征。使用t-SNE 对这些高维度深层特征进行降尺度,结果如图9所示。我们可以发现,我们的方法有效地提高了学习特征的类内紧密性和类间可分性。
-
-
图9.使用t-SNE 在CUB-200-2011上对基线训练和我们的特征级增强训练之间的特征质量进行可视化。每个子图对应一个元类别(例如捕蝇草),不同的颜色表示具有相同元类别的不同子类(例如阿卡迪亚霸鹟、大冠霸鹟、最小霸鹟等)。在每个子图中,左边是基线结果,右边是我们的结果,这表明我们的方法增强了学习特征的类内紧密性和类间可分性。
-
-
与图像级数据增强的比较。最后,我们可视化了不同数据增强方法的特征,包括随机擦除,随机增强和我们的方法。为了公平比较,我们使用相同的特征提取器,用基本增强进行预训练。对于图像级增强(随机擦除和随机增强),我们提取原始图像和增强图像的特征,并通过t-SNE降低其维数。对于我们的特征级数据增强方法,我们提取原始图像的特征,用预训练的CovNet对它们进行多样化,然后使用t-SNE对它们进行降维。图10 (a) (b)中的结果揭示了图像级增强样本的一部分将失去其辨别区域,因此被聚类在一起以形成新的聚类中心。这一现象验证了我们在图1中提出的区别性区域丢失问题。此外,我们的特征级数据扩充方法总是产生适当的语义方向,并帮助训练样本被翻译到合理的位置。我们的方法提供了一个巧妙的解决方案,以避免图像级数据增强方法在细粒度图像上引起的区别性区域丢失问题。
-
-
图10。原始图像特征(◦)和使用不同数据增强技术的增强特征(△)的可视化。不同颜色指的是不同子类别的样品。这些数据是从CUB-200-2011数据集的相同元类别(Wren)中获得的。
-
CONCLUSION
-
本文提出了一种基于元学习的隐式数据扩充方法,用于细粒度的图像识别。我们的方法旨在解决细粒度场景中的区别性区域丢失问题,这是由图像级数据增强技术的随机编辑行为引起的。我们在特征空间而不是图像空间多样化训练样本来缓解这个问题。样本方面有意义的语义方向由协方差预测网络预测,该网络以元学习的方式与分类网络联合优化。在多个细粒度基准和神经网络结构上的实验结果表明了该方法在细粒度识别问题上的有效性。
-
元学习(Meta-learning)旨在通过在多个学习任务中提取通用知识,提高模型的学习能力和泛化性能。在本文中,元学习用于优化协方差预测网络(CovNet),使其能够生成有助于分类任务的语义方向。具体来说,元学习通过以下方式助力模型表现:
- 优化CovNet:通过在元数据上优化CovNet,确保其生成的协方差矩阵能够指导分类网络在特征空间中进行有效的数据增强。
- 交替更新:分类网络和CovNet在训练过程中交替更新,分类网络的伪更新为CovNet的优化提供了一个更新后的状态,而CovNet的更新又指导分类网络的真实更新。
- 泛化能力提升:元学习框架通过在多个任务(如不同的训练批次和元数据批次)中提取通用知识,提高模型对未见数据的泛化能力。
-
针对目标检测和实例分割任务的复杂数据增强方法。它包含了多种增强技术,如 Mosaic、MixUp、随机透视变换 等。Mosaic 增强:将多张图片拼接成一张大的图片,并调整标注信息。MixUp 增强:将两张图片按一定比例混合,并融合它们的标签。随机透视变换:对图像进行旋转、缩放、剪切等几何变换,同时调整标注框、分割区域和关键点的位置。
-
class RandomPerspective: """ 实现随机透视变换和仿射变换。 包括旋转、平移、缩放、剪切和透视变换。 """ def __init__(self, degrees, translate, scale, shear, perspective, border, pre_transform=None): # 初始化参数 self.degrees = degrees # 旋转角度范围 self.translate = translate # 平移比例 self.scale = scale # 缩放因子 self.shear = shear # 剪切强度 self.perspective = perspective # 透视变形因子 self.border = border # 边界填充 self.pre_transform = pre_transform # 预处理变换 def affine_transform(self, img, border): """ 应用一系列仿射变换。 """ C = np.eye(3, dtype=np.float32) # 中心变换矩阵 C[0, 2] = -img.shape[1] / 2 # x 方向平移 C[1, 2] = -img.shape[0] / 2 # y 方向平移 # 透视变换 P = np.eye(3, dtype=np.float32) P[2, 0] = random.uniform(-self.perspective, self.perspective) # x 透视 P[2, 1] = random.uniform(-self.perspective, self.perspective) # y 透视 # 旋转和缩放 R = np.eye(3, dtype=np.float32) a = random.uniform(-self.degrees, self.degrees) # 随机旋转角度 s = random.uniform(1 - self.scale, 1 + self.scale) # 随机缩放因子 R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s) # 组合变换矩阵 M = T @ S @ R @ P @ C # 按顺序组合变换 if self.perspective: img = cv2.warpPerspective(img, M, dsize=self.size, borderValue=(114, 114, 114)) else: img = cv2.warpAffine(img, M[:2], dsize=self.size, borderValue=(114, 114, 114)) return img, M, s
-
affine_transform
方法实现了从中心变换到最终仿射变换的完整流程。使用了 OpenCV 的warpPerspective
和warpAffine
函数来实现图像变换。 -
class Mosaic(BaseMixTransform): """ 实现 Mosaic 数据增强。 将多张图片拼接成一张大图,并调整标注信息。 """ def __init__(self, dataset, imgsz=640, p=0.5, n=4): super().__init__(dataset=dataset, p=p) self.imgsz = imgsz # 单张图片的尺寸 self.border = (-imgsz // 2, -imgsz // 2) # 边界填充 self.n = n # 拼接网格大小 (4 或 9) def _mosaic4(self, labels): """ 创建 2x2 的 Mosaic 图像。 """ mosaic_labels = [] s = self.imgsz yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.border) # Mosaic 中心坐标 for i in range(4): # 遍历 4 张图片 labels_patch = labels if i == 0 else labels["mix_labels"][i - 1] img = labels_patch["img"] h, w = labels_patch.pop("resized_shape") # 根据位置计算拼接区域 if i == 0: # 左上角 x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h elif i == 1: # 右上角 x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h elif i == 2: # 左下角 x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h) x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h) elif i == 3: # 右下角 x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h) x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h) # 将图片拼接到大图中 img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] padw = x1a - x1b padh = y1a - y1b # 更新标注信息 labels_patch = self._update_labels(labels_patch, padw, padh) mosaic_labels.append(labels_patch) # 合并所有标注信息 final_labels = self._cat_labels(mosaic_labels) final_labels["img"] = img4 return final_labels
-
_mosaic4
方法实现了 2x2 的 Mosaic 拼接逻辑。通过padw
和padh
调整标注框的位置,确保拼接后的标注信息正确。 -
class MixUp(BaseMixTransform): """ 实现 MixUp 数据增强。 将两张图片按一定比例混合,并融合它们的标签。 """ def __init__(self, dataset, pre_transform=None, p=0.0): super().__init__(dataset, pre_transform, p) def _mix_transform(self, labels): """ 应用 MixUp 增强。 """ r = np.random.beta(32.0, 32.0) # 混合比例 labels2 = labels["mix_labels"][0] labels["img"] = (labels["img"] * r + labels2["img"] * (1 - r)).astype(np.uint8) labels["instances"] = Instances.concatenate([labels["instances"], labels2["instances"]], axis=0) labels["cls"] = np.concatenate([labels["cls"], labels2["cls"]], 0) return labels
-
_mix_transform
方法实现了两张图片的线性混合。使用 Beta 分布生成混合比例r
,确保混合效果更加自然。 -
ToTensor:将图像从 NumPy 数组转换为 PyTorch 张量(范围从
[0, 255]
转换为[0, 1]
)。Normalize:使用指定的均值 (mean
) 和标准差 (std
) 对图像进行归一化处理。
-