一、简介
题目: Class-Incremental Novel Class Discovery
会议: ECCV 2022
任务: 最初,有一个有标签的数据集(其数据均属已知类),出于隐私保护,使用该数据集训练过模型后,数据会被变得不可获取,之后会有一个无标签的数据集(其数据均属于新类/未知类,与已知类不相交),要求模型保留对已知类的分类能力同时对无标签样本进行聚类,或称新类发现(Novel Category Discovery)。这样该无标签数据集就有了标签,训练模型后又变得不可获取,再对另一个无标签数据集进行新类发现,如此往复。
Note: 确定类别数量对神经网络的搭建来说是极其重要的,该方法没有提供评估类别数量的方法,有理由认为作者假设新类数据的类别数是已知的。
方法:
(1)建立网络学习有标签数据。以ResNet-18为backbone,加一个有监督的分类头(大小等于已知类数量)搭建一个神经网络,以交叉熵为损失在有标签数据集上进行网络训练。保留训练后的模型并对每个类计算由backbone提取出的特征的均值(文中称为原型)和方差。
(2)建立网络准备学习无标签数据。同样以ResNet-18为backbone,新建一个网络,加两个分类头(一个分类头大小=已知类数量+新类数量,另一个分类头大小=新类数量)。已知类部分网络权重由(1)中模型参数初始化。
(3)学习无标签数据并减少对已学信息的遗忘(此时有标签数据不可获取)。为保证对新类的学习效率,作者将
L
b
c
e
+
w
self
(
t
)
L
self
+
w
self
(
t
)
L
mse
\mathcal L_{bce}+w_{\text{self}}(t)\mathcal L_{\text{self}}+w_{\text{self}}(t)\mathcal L_{\text{mse}}
Lbce+wself(t)Lself+wself(t)Lmse作为损失函数的一部分,为保留模型对已知类的识别能力(减少遗忘),作者将
L
r
e
p
l
a
y
+
λ
L
KD
feat
\mathcal L_{replay}+\lambda\mathcal L_{\text{KD}}^{\text{feat}}
Lreplay+λLKDfeat作为损失的另一部分。
该方法结构图,如上所示。
二、详情
1. 学习有标签数据
最初,有提供了标签的已知类数据集 D [ L ] \mathcal D^{[\text L]} D[L]。此时任务为常规分类任务,记作 T [ L ] \mathcal T^{[\text L]} T[L]。
A. 有监督训练
最常见的有监督分类训练任务。以ResNet-18为backbone,加一个有监督的分类头(大小等于已知类数量)搭建一个神经网络,以交叉熵为损失函数:
其中, x [ L ] \textbf x^{[\text L]} x[L]和 y [ L ] \textbf y^{[\text L]} y[L]为有标签样本和对应的真实标签, C [ L ] C^{[\text L]} C[L]为已知类类别数量, σ k ( ∗ ) \sigma_k(*) σk(∗)为softmax函数, g ( ∗ ) g(*) g(∗)和 h ( ∗ ) h(*) h(∗)分别特征提取器(backbone)和分类头。训练后的特征提取器(记作 g [ L ] ( ∗ ) g^{[\text L]}(*) g[L](∗))会被保存用于之后的增量学习。
显然, L ce \mathcal L_{\text{ce}} Lce的作用是将属于同一个已知类的数据放到一起。
B. 保留原型和特征方差
在模型训练之后,在数据不可获取之前,需要保留原型和特征方差用于后续训练,以减少在当前任务中学习的知识的遗忘。
其中, μ c [ L ] \pmb\mu_c^{[\text L]} μc[L]为原型(作者用的是均值), v c [ L ] 2 {\pmb v_c^{[\text L]^2}} vc[L]2为方差。各类别的 μ c [ L ] \pmb\mu_c^{[\text L]} μc[L]和 v c [ L ] 2 {\pmb v_c^{[\text L]^2}} vc[L]2会被保留并在增量学习时被使用。
2. 学习无标签数据
之后,有标签的已知类数据集 D [ L ] \mathcal D^{[\text L]} D[L]变得不可获取,新增任务 T [ U ] \mathcal T^{[\text U]} T[U],即给定无标签数据 D [ U ] \mathcal D^{[\text U]} D[U]对其进行聚类,同时保留模型执行 T [ L ] \mathcal T^{[\text L]} T[L]的能力。
仍以ResNet-18为backbone,记作 g ( ∗ ) g(*) g(∗),增加两个分类头,其中一个大小=新类别数量,用来专门针对无标签数据,记作 h [ U ] ( ∗ ) h^{[\text U]}(*) h[U](∗),另一个大小=已知类数量+新类数量,用来保留对已知类的分类能力并完成针对新类的聚类任务,记作 h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)。另外,backbone和已知类部分按照在有标签数据上训练出的模型的参数进行初始化。
A. 伪标签生成
为了更好的学习无标签数据,作者采用了AutoNovel的方法(我们对AutoNovel也做了分析,点击链接即可查看)。
该方法会首先给数据打上一个伪标签,伪标签定义如下:
其中, z i [ U ] \textbf z_i^{[\text U]} zi[U]和 z j [ U ] \textbf z_j^{[\text U]} zj[U]分别为两个无标签样本经backbone提取出来的特征。它会匹配两个特征的前 k k k个最大值的索引,如果索引相同(不考虑顺序)则标签为1,否则为0。
上图可方便理解。图中, s i j s_{ij} sij即为 y ~ i j [ U ] \tilde y_{ij}^{[\text U]} y~ij[U]。
有了标签,就可以训练 h [ U ] ( ∗ ) h^{[\text U]}(*) h[U](∗)和 g ( ∗ ) g(*) g(∗)了,损失函数如下:
这是一个二元交叉熵公式,标签为通过AutoNovel方法分配的伪标签。其中,
p i j = σ ( ⟨ h [ U ] ( g ( x i [ U ] ) ) , h [ U ] ( g ( x j [ U ] ) ) ⟩ ) p_{ij}=\sigma(\langle h^{[\text U]}(g(\textbf x_i^{[\text U]})),h^{[\text U]}(g(\textbf x_j^{[\text U]}))\rangle) pij=σ(⟨h[U](g(xi[U])),h[U](g(xj[U]))⟩)
其中, σ ( ∗ ) \sigma(*) σ(∗)为logistic函数。 p i j p_{ij} pij可理解为分类器对于 x i [ U ] \textbf x_i^{[\text U]} xi[U]和 x j [ U ] \textbf x_j^{[\text U]} xj[U]的预测的相似性,相似性越高值越接近1。
显然, L bce \mathcal L_{\text{bce}} Lbce的作用是将无标签样本中相似的样本放到一起。
这样, h [ U ] ( ∗ ) h^{[\text U]}(*) h[U](∗)和 g ( ∗ ) g(*) g(∗)被训练后,输入一个无标签数据 x i [ U ] \textbf x^{[\text U]}_i xi[U]便可得到一个预测 h [ U ] ( g ( x i [ U ] ) ) h^{[\text U]}(g(\textbf x^{[\text U]}_i)) h[U](g(xi[U]))。该预测是以簇的形式存在的,比如总共有3个新类,那么结果就应该是簇1-簇3。而实际新类应该从 C [ L ] C^{[\text L]} C[L]起始,比如原本已知类有4个,类1-4就被占用了,簇1-3应该放到类5-7。于是作者将预测标签定义如下:
B. h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)、 g ( ∗ ) g(*) g(∗)的优化
之后,作者将预测标签 y ^ [ U ] \hat y^{[\text U]} y^[U]作为伪标签,用于优化 h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)和 g ( ∗ ) g(*) g(∗),损失函数如下:
这也是一个有监督的交叉熵损失。 ∣ C [ A ] ∣ = ∣ C [ L ] ∣ |C^{[\text A]}|=|C^{[\text L]}| ∣C[A]∣=∣C[L]∣+ ∣ C [ U ] ∣ |C^{[\text U]}| ∣C[U]∣为类别总数, σ k ( ∗ ) \sigma_k(*) σk(∗)为softmax函数。
显然, L self \mathcal L_{\text{self}} Lself的作用是将属于同一个伪标签的无标签数据放到一起。
此外,为了保持无标签数据两个相关的视图的预测一致性,AutoNovel还引入了如下均方误差损失:
其中, σ k ( ∗ ) \sigma_k(*) σk(∗)为softmax函数, x ˉ [ U ] \bar{\textbf x}^{[\text U]} xˉ[U]为 x [ U ] {\textbf x}^{[\text U]} x[U]随机增强后的样本。
显然, L mse \mathcal L_{\text{mse}} Lmse的作用是让同一样本的不同视图的预测结果尽可能接近。
于是,形成如下用于学习新类的损失:
其中, ω self ( t ) \omega_{\text{self}}(t) ωself(t)和 ω mse ( t ) \omega_{\text{mse}}(t) ωmse(t)为ramp-up函数,用来控制学习稳定性的。
综上, L bce \mathcal L_{\text{bce}} Lbce被用于优化 h [ U ] ( ∗ ) h^{[\text U]}(*) h[U](∗)和 g ( ∗ ) g(*) g(∗),生成伪标签。之后,伪标签结合 L novel \mathcal L_{\text{novel}} Lnovel用于优化 h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)和 g ( ∗ ) g(*) g(∗),使模型实现对新类的学习。
3. 基于特征回放的增量学习
增量学习的目标为保留对旧类(已知类)的识别能力并逐渐掌握对新类的识别。
之前,我们在对已知类进行有监督学习时保留了特征提取器( g [ L ] ( ∗ ) g^{[\text L]}(*) g[L](∗))、原型( μ c [ L ] \pmb\mu_c^{[\text L]} μc[L])、方差( v c [ L ] 2 {\pmb v_c^{[\text L]^2}} vc[L]2)。
首先,原型( μ c [ L ] \pmb\mu_c^{[\text L]} μc[L])和方差( v c [ L ] 2 {\pmb v_c^{[\text L]^2}} vc[L]2)被用于特征回放。根据高斯分布 N ( μ c [ L ] , v c [ L ] 2 ) \mathcal N(\pmb\mu_c^{[\text L]},{\pmb v_c^{[\text L]^2}}) N(μc[L],vc[L]2)进行各类别的特征采样,并计算它们的交叉熵损失:
其中, z [ L ] \textbf z^{[\text L]} z[L]为采样特征,因为它是根据各类别的高斯分布采样所得所以是有标签的,标签为 y [ L ] y^{[\text L]} y[L], σ k ( ∗ ) \sigma_k(*) σk(∗)为softmax函数, h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)为全类别分类头。
显然, L replay \mathcal L_{\text{replay}} Lreplay的作用是将属于同一已知类的采样特征放到一起。
此外,为了保证特征回放的有效性,作者还采用了特征蒸馏损失:
它在限制当前特征提取器 g ( ∗ ) g(*) g(∗)的更新,使其与之前保存的 g [ L ] ( ∗ ) g^{[\text L]}(*) g[L](∗)的结果接近,
显然, L KD feat \mathcal L^{\text{feat}}_{\text{KD}} LKDfeat的作用从而保证根据 N ( μ c [ L ] , v c [ L ] 2 ) \mathcal N(\pmb\mu_c^{[\text L]},{\pmb v_c^{[\text L]^2}}) N(μc[L],vc[L]2)采样的特征在 h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)中仍然适用。
于是,形成如下用于保留旧类识别能力的损失:
其中, λ \lambda λ为一个权重常数。
综上, L past \mathcal L_{\text{past}} Lpast用于优化 h [ A ] ( ∗ ) h^{[\text A]}(*) h[A](∗)和 g ( ∗ ) g(*) g(∗),使模型保留了对旧类的识别能力。
最终形成如下整体损失:
在假设未知类的数量已知的情况下,该方法可以实现增量式的新类别发现任务,既保留对旧类的识别能力又能逐渐学习新类的知识。
4. 评估指标
此外,作者还提供了一个更合理的性能评估策略,如下图:
如左图所示,旧类为0、1,新类为2、3。对于聚类任务,通常评估指标计算是采用Hungarian algorithm,将簇与实际类进行序号匹配,最后取最大准确率。
但是如果预测结果为 [ 2 , 3 , 0 , 1 ] [2,3,0,1] [2,3,0,1],真实标签为 [ 0 , 1 , 2 , 3 ] [0,1,2,3] [0,1,2,3],那么常规计算方式的预测精度为100%。但这是不合理的,因为它将新类预测为了旧类,旧类预测为了新类。
所以作者提出右图的方案,先只考虑新类的预测结果,结果必然在(0,新类数量-1)之间。之后采用Hungarian算法与真实标签进行匹配,得到簇0 ↔ \leftrightarrow ↔类3、簇1 ↔ \leftrightarrow ↔类2。接着,在簇序号的基础上加上旧类数量的值,这里旧类有2个就+2。于是重排的标签成了簇2、簇3。在实际计算精度时使用预测标签与重排的标签一一对比, [ 2 , 3 , 0 , 1 ] [2,3,0,1] [2,3,0,1]与 [ 0 , 1 , 3 , 2 ] [0,1,3,2] [0,1,3,2]对应位置没有相同的,所以精度为0。
可见作者的做法十分巧妙,并且结果更加合理。