
Hard Task Sampling
Trick:Hard Task 思路来源于 Meta-Tranfer-Learning,基本思路是在 Meta-Learning 的每一次 Meta-Test 的时候,会从预训练错误率比较高的 Task 中再次采样,增加那些 task 的训练次数。也就是难题多做的策略。 基本思路 对比 Adaboost 这样的思路其实和 AdaBoost 的想法是有一定的异曲同工之妙的,或者说其实就是 AdaBoost 的思路: Adaboost 参考笔记 ,从该笔记中我们可以看到,AdaBoost 的基本思路如下: Boosting 算法的工作机制是首先从训练集用初始权重训练出一个弱学习器 1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器 1 学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器 2 中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器 2.,如此重复进行,直到弱学习器数达到事先指定的数目 T,最终将这 T 个弱学习器通过集合策略进行整合,得到最终的强学习器. 和 Meta-Transfer-Learning 对比一下,我们可以发现,这个方法实际上就是讲 Transfer Learning 的与训练网络当成弱学习器 1,然后通过弱学习器 1 的训练样本权重,来增大 Hard-Task 的配比(也就是增加任务的权重)完全一致。 具体实现 实现上主要是,样本 sample 的过程,就是如何在进行参数选择后和原本的 Dataloader,结合起来。在这里我们主要参考 MTL 中的方法,进行网络的构建处理。 第一部分:sampler 构建,为了后续 Dataloader 中进行数据的采样,需要构建一个这样的 sampler,关键在于 index 的对应关系,以及最后输出的是 index 的集合。 python import torch import numpy as np # 注意的点,我们需要确定我们 batch 数目,cls 数目和每次每个 cls 选出多少个数据 per # 紧接着定义一个 sample,sample 输出的是对应原 dataset 中的数据的 index, class CatagoriesSampler(): def __init__(self, label, n_batch, n_cls, n_per): self.n_batch = n_batch self.n_cls = n_cls self.n_per = n_per label = np.array(label) # 根据不同的 label 输入情况,我们可可能需要找到每个 label 对应的样本的 index,将其整合在一起。如下(option) self.m_idx = [] for i in range(max(label)+1): idx = np.argwhere(label==i).reshape(-1) idx = torch.from_numpy(idx) self.m_idx.append(idx) def __len__(self): # 要注意一下这里数据的长度是根据我们要输出的 batch 数目决定的 return self.n_batch def __iter__(self): # 直接定义每次采样的时候的 batch 输出 for i_batch in range(self.n_batch): batch = [] classes = torch.randperm(len(self.m_idx))[:self.n_cls] for c in classes: # 随机选择出的类标签 l = self.m_idx[c] # 随机选择样本 random_pos = torch.randperm(len(l))[:self.n_per] batch.append(l[random_pos]) # stack t and reshape 的作用👇 # stack 变成 n_cls * n_per , t 转置,reshape(-1)变成行向量 batch = torch.stack(batch).t().reshape(-1) yield batch 第二部分:直接调用部分 ...