01
引言
在监督式深度学习中,最大的问题之一就是标注训练数据的稀缺性。如果您想在现实世界中训练自己的深度学习模型,通常需要标注大量数据。然而,数据标注的过程通常是繁琐且成本高昂的。这时,主动学习就派上用场了。
并非所有的训练数据样本对训练过程都具有同等的价值,通过仅选择最有价值的训练样本,主动学习试图最小化所需的标注训练数据量。
下图说明了主动学习背后的动机。
因此,我们可以用更少的标注数据达到相同的性能,从而节省时间和成本。闲话少说,我们直接开始吧!
02
主动学习( active learning)试图通过标注尽可能少的样本来获得尽可能高的性能。当主动学习策略应用于现代深度学习模型时,有时也称为深度主动学习(deep active learning)。
03
查询策略是主动学习的核心组成部分,它决定了未标注样本池中哪些样本需要交由专家进行标注。主动学习中常用的查询选择标准主要有两类:信息量(informativeness)和代表性(representativeness)。
第一种查询策略:信息量
该策略的核心思想是选择最具信息量的数据点,通常意味着选择深度学习模型对输出类别概率最不确定的样本。
具体实现方式有多种,以下介绍三种典型方法:
最低置信度法
该方法通过遍历所有类别概率P(y|x),根据上述公式选择最高概率类别y*,从而计算每个输入样本x的置信度得分。
当最高类别概率P(y*|x)较低时,将产生较高的置信度得分LC(x)。置信度得分LC(x)越高,表明样本x的信息量越大。
最大熵
最大熵采样方法通过根据下述公式对所有类别进行求和来计算每个输入样本 x 的熵。
直观地说,熵是衡量不确定性的指标。当存在一个非常可能的类别时,熵较低。而当多个类别具有同等可能性时,熵较高。
信息熵 H(x) 越高,我们的样本 x 的信息量就越大。
基于间隔的不确定性
第三种选择是,通过根据下述公式比较最高类别概率 y* 与次高类别概率 y** 来计算(不)确定性间隔。
如果模型预测不确定时,这个差值会较小。因此,间隔 M(x) 越大,我们的样本 x 就越有信息量。
举个栗子
让我们通过一个包含两张图片的示例来直观理解上述三个公式。
上图展示了两张猫的图片,但第二只猫戴着眼镜,因此一个猫狗分类器可能会有些困惑。给定两个类别的概率,所有这三种查询策略都会选择第二张图片作为更有信息量的图片。
04
第二种查询策略的核心思想是:选取最能代表整个训练数据集的样本。这意味着我们需要避免选择彼此过于相似的样本。
我们可以通过特征空间中样本之间的距离来衡量相似度。同样地,这里也有多种实现方法可选,下面我们重点介绍其中两种典型方法:
K-means聚类
K-means 是一种成熟的算法,可用于将数据聚类为 k 个群组,二维特征空间和 k = 3 个群组的示例见下图。
然后,基于 k-means 的查询策略将从每个群组中选择一定数量的样本。
核心集选择
该方法旨在选取最能代表整个数据集的核心样本集合。其核心目标是:当我们基于这k个样本训练深度学习模型时,模型在核心集上的表现能够尽可能接近其在全体数据上的表现。
该方法的理论基础来源于k-中心点问题。k-中心点算法通过选择k个中心点,使得任一数据点到其最近中心点的最大距离最小化(具体示例见下图)。
05
混合查询策略通过结合信息量与代表性来实现样本选择。当然,具体实现方式多种多样,下列参考文献中列举了若干前沿研究成果。
地址:https://arxiv.org/abs/2009.00236
其中,"多样化小批量主动学习"(Diverse mini-batch Active Learning,简称DBAL)是一种非常直观的算法,其核心思想如下:
不确定性筛选阶段
使用基于间隔不确定性度量方法,对未标注训练样本池进行筛选,仅保留不确定性最高的k*beta个样本。加权聚类阶段
采用加权K均值算法将剩余样本划分为k个簇。其中权重由不确定性度量值决定,这种机制会使聚类中心更偏向高不确定性样本区域。
代表样本选取阶段
从每个簇中选取距离聚类中心最近的样本作为最终选择。
06
下面我们将使用Python和预训练的ResNet18深度学习模型(针对图像数据)来实现混合查询策略DBAL。
首先导入必要的程序库(本示例使用Python3.9):
#!/usr/bin/python3import osimport torchimport numpy as npfrom torchvision import transformsfrom torchvision.models import resnet18, ResNet18_Weightsfrom PIL import Imagefrom sklearn.cluster import KMeans
接下来我们定义DBAL类,该类将初始化所有必要参数并加载预训练的ResNet18模型(resnet)用于获取类别概率。同时,我们还会加载第二个ResNet18模型(resnet_features),通过移除其最后的全连接层来构建一个特征提取器,该提取器可输出512维的特征向量。
class DBAL:""" active learning query strategy based on DBAL"""def __init__(self, k: int=20, beta: int=10, image_size: int=224, use_weighted_kmeans: bool=True):self.k = int(k) # number of queried samplesself.beta = beta # pre-filter factorself.image_size = image_size # ImageNet is 224 x 224self.use_weighted_kmeans = use_weighted_kmeans# load a pre-trained deep learning modelself.resnet = resnet18(weights=ResNet18_Weights.DEFAULT)self.resnet.eval() # set to evaluation mode# load a pre-trained model as feature extractorself.resnet_features = resnet18(weights=ResNet18_Weights.DEFAULT)self.resnet_features.fc = Identity() # remove last fully connected layerself.resnet_features.eval()# perform image preprocessingself.transform = transforms.Compose([transforms.Resize(self.image_size),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])
接下来我们定义一个实例方法 query,该方法接收包含未标注图像池的数据集路径作为输入,并返回需要标注的k张图像列表。
基于间隔的不确定性分数会存储在列表 margins 中,而特征映射 X 将用于后续聚类分析。
def query(self, image_path: str) -> list[str]:"""run DBAL active learning strategy. returns list of selected images in image_path"""files = os.listdir(image_path)margins = []X = np.zeros((len(files), 512), dtype=np.float32)for i, file in enumerate(files):# iterate through the unlabeled pool of dataimg = Image.open(os.path.join(image_path, file))img = self.transform(img)img = torch.unsqueeze(img, 0)predictions = self.resnet(img) # model outputfeatures = self.resnet_features(img) # feature vectorX[i,:] = features.detach().numpy() # feature matrixprobabilities = torch.nn.functional.softmax(predictions, dim=1)[0] # convert predictions to class probabilitiesP = sorted(probabilities.tolist()) # a sorted list of class probabilitiesmargins.append(1 - (P[-1] - P[-2]))
随后,我们通过仅保留不确定性最高(margin值最大)的k*beta个样本,将未标注训练样本池缩减至更小的规模。这种预筛选处理能有效降低后续聚类复杂度。
# Pre-filter to top beta*k informative examplesindices = np.argsort(margins)keep_idx =for i in range(-1, -self.k*self.beta-1, -1):keep_idx.append(indices[i])X = X[keep_idx, :]margins =files =
DBAL算法采用加权k均值聚类方法,其权重由不确定性分数列表margins确定,所有样本特征均存储在特征矩阵X中。
# cluster beta*k examples to k clusters with weighted K-meanskmeans = KMeans(n_clusters=self.k, random_state=0, n_init=1,tol=1e-4, verbose=1).fit(X, sample_weight=margins)distances = kmeans.transform(X)# select k different examples closest to the cluster centersimages = []for column in range(self.k):idx = np.argmin(distances[:, column]) # find closest sample to the current clusterim = Image.open(os.path.join(image_path, files[idx]))im.filename = str(files[idx])images.append(im)return images
最后,可以通过以下命令运行代码:
images = DBAL(N=200, k=10, beta=10,use_weighted_kmeans=True).query(image_path="./Dataset/")
07
例如,我使用预训练的ResNet18深度学习模型,在Oxford-IIIT宠物数据集上运行了DBAL算法,参数为k=20和beta=10。
在这些参数下,数据集首先被预筛选到200张图像,然后从这200张中选择了20个样本进行由专家进行标注。被选中的样本如下图所示。
根据公式计算出的边际值M(x)在这些样本中范围为0.99到0.97,表明模型对于这些样本都非常不确定。此外,这些被选中的样本似乎涵盖了数据集中不同品种的猫和狗,具有多样性。
08
本文涵盖了主动学习理论和实践的基础知识。总而言之,主动学习通过选择最重要的样本来尽量减少所需的标注训练数据量。
为了衡量训练样本的重要性,主动学习查询策略通常依赖于信息量、代表性或两者的结合。
代码实现部分展示了如何使用基于间隔的不确定性和加权 k-均值聚类来实现主动学习查询策略。
点击上方小卡片关注我
添加个人微信,进专属粉丝群!
部分内容来自互联网,仅供学习交流,侵权请联系删除!

