深度学习数据标注完成后,需要构建dataset并送入dataloader整合好以后送入模型去学习,而数据在进入dataloader后会有一个采样器sampler进行数据的index的筛选,本文主要记录常见的几种sampler:
- mmdetection中的Groupsampler
- 数据不均衡–Imbalanced Dataset Sampler
- 数据不均衡–Weighted Random Sampler
- Random Sampler
- Sequential Sampler
- Subset Random Sampler
1、sampler
sampler是torch中的基础函数,只有定义没有实现,是实现其他不同采样器需要继承的基类,该基类只有一个初始化函数、一个迭代器__iter__函数以及一个统计数据长度的__len__函数,在实现其他采样器的时候,必须要实现的是iter函数以及len函数,其中iter不断的返回数据的index,以获取相应的样本。
class Sampler(Generic[T_co]):
def __init__(self, data_source: Optional[Sized]) -> None:
pass
def __iter__(self) -> Iterator[T_co]:
raise NotImplementedError
def __len__(self) -> int:
pass
2、Groupsampler
mmdetection实现很多数据预处理方式,并最终在collate将不同size的图片通过pad统一到相同大小。减少pad面积,可以节约算力,因此商汤实现了自己采样器Groupsampler,将未处理的图片根据ratio(长和宽的比例)分为两组,ratio大于1的分为一组,ratio小于1的分为另一组。要求每次dataloader迭代一次,返回的batch都为同一组!这样相似ratio图片的输入可以有效减少pad面积。
其实现的源码如下:
class GroupSampler(Sampler):
def __init__(self, dataset, samples_per_gpu=1):
assert hasattr(dataset, 'flag')
self.dataset = dataset
self.samples_per_gpu = samples_per_gpu
self.flag = dataset.flag.astype(np.int64)
# flag标志由dataset在初始化时确定,详见customdataset
# flag只有两个取值,根据ratio是否大于1,分为两组
self.group_sizes = np.bincount(self.flag) # 对每组的数量进行计数,详见bincount的使用方法
self.num_samples = 0 # 作为__len__的返回值
for i, size in enumerate(self.group_sizes):
self.num_samples += int(np.ceil(size / self.samples_per_gpu)) * self.samples_per_gpu
# group_size不一定能确保被samples_per_gpu整除,因此需要向上取整
# 比如分组0的数量是100个,分组1的数量是200个,samples_per_gpu为3
# 那么num_samples = 102+201 = 303
def __iter__(self): # 返回迭代器,每次迭代返回一个整数索引
indices = []
for i, size in enumerate(self.group_sizes):
if size == 0:
continue
indice = np.where(self.flag == i)[0] # 获得同组的图片下标
assert len(indice) == size
np.random.shuffle(indice) # 打乱
num_extra = int(np.ceil(size / self.samples_per_gpu)) * self.samples_per_gpu - len(indice)
indice = np.concatenate([indice, np.random.choice(indice, num_extra)])
indices.append(indice)
# 还是以"分组0的数量是100个,分组1的数量是200个,samples_per_gpu为3"举例,num_samples = 102+201 = 303
# 102大于100,201大于200,所以我们需要还额外增加下标
# 最后得到303个下标,其中前102个是分组0,后201个是分组1,确保每samples_per_gpu都是同一ratio
indices = np.concatenate(indices)
indices = [
indices[i

最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



