作为学习D-CBRS的笔记,方便理解与复习。
D-CBRS是一种回放方法中,用于记忆缓冲区样本采样的方法,我之前整理过的水库采样(Reservoir Sampling,点此跳转)也是用来解决这个的,而且看全称也能知道,这个方法是水库采样的一种改进。
它有一个前身叫做CBRS,所以接下来的文章内容,我会依次对CBRS和D-CBRS进行介绍。
这里给出两篇论文的链接:
- Online Continual Learning from Imbalanced Data
这是2020年ICML上的文章 - D-CBRS: Accounting For Intra-Class Diversity in Continual Learning
这是2022年IEEE上的文章
一.CBRS
CBRS(Class-Balancing Reservoir Sampling)作为水库采样的改进,保证了存储时各类别的平衡。
在CBRS中,有如下几个定义:
- 记忆库已满:给定大小为 m 的记忆库,当所有 m 个存储单元都被占用时,称记忆库已满;
- 最大类别:当某个类别在记忆库中包含的样本数多于或等于其他所有类别时,称该类别为最大类别,若多个类别样本数相同且均为最多,则这些类别均为最大类别;
- 满类别:若某个类别当前是或曾经是最大类别,则称该类别为 "满类别",所有类别初始都不是"满类别",一旦某个类别成为满类别,它将始终保持这一状态。
与水库采样类似,在记忆库未满时,所有输入数据流的样本都被存储到记忆库中,当记忆库已满时,对于后续的数据流样本 ( x i , y i ) (x_i,y_i) (xi,yi) 将进行以下检查操作:
- 检查 y i y_i yi 是否属于满类别。
- 如果不属于 ,那么随机选取记忆库中最大类别的一个样本,用该样本 ( x i , y i ) (x_i,y_i) (xi,yi) 替换。
- 如果属于 ,那么该接收样本以概率 m c / n c m_c/n_c mc/nc 替换同类别的一个随机存储样本,其中 m c m_c mc 是当前记忆库中类别 c c c 的样本数, n c n_c nc 是迄今为止遇到的数据流中类别 c c c 的样本总数,也就是在最大样本上进行水库采样。
其算法的伪代码如下所示:
python
#输入:stream: {(x_i, y_i)}_{i=1}^n
for i = 1 to n do
if memory is not filled then
存储 (x_i, y_i)
else
c ← y_i # 当前样本的类别
if c 不是满类别 then
找到记忆库中所有属于"最大类别"的样本
从中随机选一个样本
用 (x_i, y_i) 覆盖选中的样本
else
m_c ← 记忆库中类别 c 的当前存储样本数
n_c ← 流中已遇到的类别 c 的总样本数
采样 u ∼ Uniform(0, 1)
if u ≤ m_c / n_c then
从记忆库中随机选一个类别 c 的样本
用 (x_i, y_i) 替换它
else
忽略样本 (x_i, y_i)
end if
end if
end if
end for
二.D-CBRS
D-CBRS是CBRS的一个改进方法,因为在CBRS中,假设每个样本的价值相同,但是实际情况中,同一个类的每个样本可能拥有不同的价值,比如分类为"偶数",那么样本里就包括"0""2""4"等等,当仅用CBRS的思想,就可能让这个类中,样本大部分是某个特定偶数,或者其它类中不平衡的情况,为了解决这个问题,D-CBRS相对于前文的CBRS额外加入了k-means的算法,用于单个类中样本的聚类。
其伪代码如下图所示:
python
# 输入:数据流 stream = {(x_i, y_i)}_{i=1}^n
for i in 1 to n do
if memory is not filled then
存储 (x_i, y_i)
else
c = y_i # 当前样本类别
if c 不是 full class then
从任意一个 full class 的最大簇中随机选择一个样本
用 (x_i, y_i) 替换该样本
else
对类别 c 执行聚类
从类别 c 的最大簇中随机选择一个样本 (x_p, y_p)
if x_i 属于最大簇 then
m_c = 当前内存中类别 c 最大簇的样本数
n_c = 已观察到的类别 c 最大簇的总样本数
u = Uniform(0, 1)
if u ≤ m_c / n_c then
用 (x_i, y_i) 替换 (x_p, y_p)
else
保持 (x_p, y_p) 不变
end if
else
用 (x_i, y_i) 替换 (x_p, y_p)
end if
end if
end if
end for
在这个方法中,k是一个预先设定的超参数,并且相对于CBRS引入了额外k聚类算法的计算,所以当记忆库过大时,该方法的计算时间可能过长。
三、总结
CBRS和D-CBRS都是为持续学习(Continual Learning)中的记忆回放而设计的缓冲区采样策略。它们的目标都是在有限的内存中保持类别平衡 ,同时尊重数据流分布。
1.CBRS
- 核心思想 :在标准Reservoir Sampling基础上加入类别平衡机制。
- 关键操作 :
- 维护"满类别"(full class)状态,一旦某个类别的样本数达到最大,则永远视为满类别。
- 当新样本到来且缓冲区已满时:
- 若其类别不是满类别:从当前最大类别中随机替换一个样本。
- 若其类别是满类别 :以概率 m c n c \frac{m_c}{n_c} ncmc 替换同类中的一个随机样本(即对该类内部做水库采样)。
- 优点 :
- 保持类别间样本数大致平衡。
- 对每个类别内部仍保持流数据的随机代表性。
- 局限 :
- 假设同类样本价值相同,忽略类内多样性。
- 可能因为类内分布不平衡导致记忆样本冗余或缺乏代表性。
2.D-CBRS
- 核心改进 :在CBRS基础上引入类内多样性保持机制。
- 关键操作 :
- 对每个类别的样本进行k-means聚类,将类内样本划分为多个簇。
- 当新样本到来且缓冲区已满时:
- 若其类别不是满类别 :从任意满类别的最大簇中随机替换一个样本(鼓励跨类别、跨簇的平衡)。
- 若其类别是满类别 :
- 如果新样本属于该类的最大簇 :以概率 m c n c \frac{m_c}{n_c} ncmc 替换该簇中的一个样本(簇内水库采样)。
- 否则:直接替换最大簇中的一个样本(鼓励类内簇间平衡)。
- 优点 :
- 不仅保持类别平衡,还通过聚类保持类内样本的多样性。
- 更适合真实场景中类内分布不均的任务(如长尾数据)。
- 代价 :
- 需要额外运行k-means聚类,计算开销随记忆库增大而增加。
- 引入超参数k(簇数),需根据任务调整。
3.对比表格
| 特性 | CBRS | D-CBRS |
|---|---|---|
| 目标 | 类别平衡 | 类别平衡 + 类内多样性 |
| 类内处理 | 均匀采样 | 聚类后按簇平衡采样 |
| 计算复杂度 | O(1) 替换操作 | O(k·记忆库大小) 聚类开销 |
| 超参数 | 无 | 聚类数 k |
| 适用场景 | 类别平衡即可的任务 | 类内分布不均匀、需要多样性的任务 |
4.选择建议
- 如果任务中各类别内部样本分布相对均匀,且计算资源有限,CBRS 是更轻量且有效的选择。
- 如果任务中同类样本差异大(如不同姿态、光照、背景等),且需要记忆库尽可能覆盖多样模式,则D-CBRS 更能提升模型鲁棒性。
通过这两种方法,可以根据实际任务需求在类别平衡 与样本多样性之间取得合适的权衡,从而提升持续学习中的记忆回放效果。