Annotate Text Data Transformers Via Active Learning
使用 Cleanlab 进行主动学习标注文本数据
作者: Aravind Putrevu
在本 Notebook 中,我重点介绍了如何使用主动学习来改进一个经过微调的 Hugging Face Transformer 文本分类模型,同时保持从人工标注者收集的标签总数较低。当资源限制使得无法为整个数据集获取标签时,主动学习通过选择数据标注者应该投入精力标注的样本,旨在节省时间和成本。
什么是主动学习?
主动学习帮助优先选择需要标注的数据,以最大化基于标注数据训练的监督学习模型的性能。这个过程通常是迭代进行的——在每一轮中,主动学习告诉我们应该为哪些示例收集额外的注释,以在有限的标注预算下最大限度地提高当前模型的性能。ActiveLab 是一种特别有用的主动学习算法,尤其在来自人工标注者的标签存在噪声,并且我们应该为以前标注过的示例(其标签看起来可疑)收集更多注释,而不是为尚未标注的示例收集注释时。收集这些新注释以扩充我们的训练数据集后,我们会重新训练模型并评估其测试准确率。
在本 Notebook 中,我考虑了一个二分类文本分类任务:预测特定短语是礼貌的还是不礼貌的。
与随机选择相比,使用 ActiveLab 进行主动学习在为 Transformer 模型收集额外注释时效果要好得多。无论总的标注预算是多少,它始终能产生更好的模型,错误率约减少 50%。
接下来的部分将介绍如何使用开源代码来实现这些结果。
设置环境
收集并组织数据
这里我们下载我们需要的 Notebook 数据。
文本礼貌性分类
我们使用的是 斯坦福礼貌语料库 作为数据集。
该数据集被结构化为一个二分类文本分类任务,目标是分类每个短语是礼貌的还是不礼貌的。人工标注者会被提供一个选定的文本短语,并对其礼貌性进行标注:(不礼貌为 0,礼貌为 1)。
我们在标注数据上训练一个 Transformer 分类器,并在一组保留的测试样本上衡量模型的准确性。由于这些测试样本的标签来自五个标注者的共识,我对其真实标签有较高的信心。
至于训练数据,我们有以下内容:
X_labeled_full:我们的初始训练集,包含 100 个文本示例,并且每个示例有 2 个标注。X_unlabeled:一个包含 1900 个未标注文本示例的大型数据集,供我们考虑让标注者进行标注。extra_annotations:当请求某个示例的标注时,我们可以从中提取的附加标注池。
可视化数据
<ipython-input-6-d9c8ad254414>:5: DeprecationWarning: Sampling from a set deprecated
since Python 3.9 and will be removed in a subsequent version.
{k:extra_annotations[k] for k in random.sample(extra_annotations.keys(), 5)}
{'4235a537': {'a6': 0.0, 'a12': 0.0, 'a98': 0.0, 'a99': 0.0, 'a119': 0.0},
, '3d961d64': {'a68': 0.0, 'a70': 0.0, 'a79': 0.0, 'a99': 0.0, 'a199': 1.0},
, '4a5e75dc': {'a60': 1.0, 'a102': 1.0, 'a130': 1.0, 'a148': 1.0, 'a174': 1.0},
, '369a8b74': {'a65': 1.0, 'a68': 1.0, 'a71': 1.0, 'a157': 0.0, 'a161': 0.0},
, '356a4a74': {'a61': 0.0, 'a70': 1.0, 'a139': 0.0, 'a145': 1.0, 'a198': 1.0}} 查看一些来自测试集的示例
Impolite examples:
Polite examples:
不礼貌的示例:
| 文本 | |
|---|---|
| 120 | 和浪费我们的时间一样。我只能重复一句话:你为什么不通过添加你心爱的马其顿的内容来做一些建设性的工作? |
| 150 | 与其告诉我我关闭某些 afd 是多么错误,也许你应该把时间花在处理当前的 afd 积压上 |
| 326 | 根据 CFD,这本应已经转移到 |
礼貌的示例:
| 文本 | |
|---|---|
| 498 | 你好,我提出了取消保护 tamazepam 页面 |
| 132 | 由于某些编辑,页面的对齐方式发生了变化。你能帮忙吗? |
| 131 | 我很高兴你对整体外观感到满意。在我标注所有街道之前,文字大小、字体样式等都可以吗? |
辅助方法
以下部分包含了本 Notebook 所需的所有辅助方法。
get_idx_to_label 旨在用于主动学习场景,特别是在处理标注和未标注数据的混合时。它的主要目标是根据主动学习分数确定应选择哪些示例(来自标注数据集和未标注数据集)进行额外标注。
get_idx_to_label_random 旨在主动学习的上下文中使用,其中数据点的选择是随机进行的,而不是基于模型的不确定性或学习分数。这种方法可以作为基准,与更复杂的主动学习策略进行比较,或者用于在不确定如何为示例打分的场景中。
以下是一些实用方法,帮助我们计算标准差、选择之前标注过该示例的特定标注者,以及一些用于文本示例标记化的令牌化函数。
get_trainer 函数旨在为文本分类任务设置训练环境,使用的是 DistilBERT,这是一种轻量级且速度更快的 BERT 模型的蒸馏版。
get_pred_probs 函数通过交叉验证对给定数据集执行样本外预测概率计算,并额外处理未标注数据。
get_annotator 函数根据一组标准确定最合适的标注者,从特定示例中收集新的标注。而 get_annotation 函数则专注于从选择的标注者处收集给定示例的实际标注,同时还会将已收集的标注从池中删除,以防止其再次被选择。
运行以下代码单元以隐藏下一个模型训练块的 HTML 输出。
使用的方法
对于每一轮主动学习,我们:
- 计算基于迄今为止收集的所有标注的 ActiveLab 共识标签,应用于每个训练示例。
- 使用这些共识标签,在当前训练集上训练我们的 Transformer 分类模型。
- 在测试集上评估模型的测试准确率(该测试集具有高质量的真实标签)。
- 通过交叉验证,获取模型对整个训练集和未标注集的样本外预测类别概率。
- 获取训练集和未标注集上每个示例的 ActiveLab 主动学习分数。这些分数估算了为每个示例收集另一个标注的潜在信息量。
- 选择一组主动学习分数最低的示例子集(n = batch_size)。
- 为每个选定的 n 个示例收集一个额外的标注。
- 将新的标注(以及如果选择的非标注示例)添加到训练集中,用于下一轮迭代。
接下来,我将比较通过主动学习标注的数据与通过随机选择标注的数据训练的模型。对于每一轮随机选择,我使用多数投票共识而非 ActiveLab 共识(步骤 1),然后仅随机选择n个示例来收集额外标签,而不是使用 ActiveLab 分数(步骤 6)。
关于 ActiveLab 共识标签和主动学习分数的更多直觉解释将在本笔记本的后续部分中分享。
模型训练与评估
我首先对测试集和训练集进行标记化处理,然后初始化一个预训练的 DistilBert Transformer 模型。通过 300 次训练步骤对 DistilBert 进行微调,在我的数据上取得了准确率与训练时间之间的良好平衡。该分类器输出预测类别概率,我在评估其准确性之前,将概率转换为类别预测。
使用主动学习分数决定下一个标注内容
在每轮主动学习中,我们通过 3 折交叉验证拟合当前训练集上的 Transformer 模型。这使我们能够获得训练集上每个示例的样本外预测类别概率,同时我们还可以使用训练好的 Transformer 获取未标注池中每个示例的样本外预测类别概率。所有这些都在 get_pred_probs 辅助方法中实现。样本外预测的使用帮助我们避免了由于潜在过拟合导致的偏差。
一旦得到这些概率预测,我将它们传入开源 cleanlab 包中的 get_active_learning_scores 方法,该方法实现了 ActiveLab 算法。此方法为我们提供了所有标注数据和未标注数据的分数。较低的分数表示收集一个额外标签对当前模型来说最具信息性(这些分数在标注数据和未标注数据之间是直接可比较的)。
我将得分最低的示例形成一个批次,作为需要收集标注的示例(通过 get_idx_to_label 方法)。在每轮中,我始终收集相同数量的标注(无论是在主动学习还是随机选择方法下)。对于这个应用,我将每个示例的最大标注次数限制为 5 次(避免重复标注同一个示例)。
添加新的标注
combined_example_ids 是我们希望收集标注的文本示例的 ID。对于每一个示例,我们使用 get_annotation 辅助方法从标注者那里收集新的标注。在此过程中,我们优先选择那些已经标注过其他示例的标注者。如果给定示例的标注者在训练集中不存在,我们将随机选择一个标注者。在这种情况下,我们会在训练集中添加一列,表示新的标注者。最后,我们将新收集的标注添加到训练集中。如果对应的示例之前没有标注过,我们还会将其添加到训练集中,并从未标注数据集中移除。
我们现在已经完成了一轮新的标注收集,并基于更新后的训练集重新训练 Transformer 模型。我们将通过多轮的迭代重复此过程,不断扩展训练数据集并提升模型性能。
结果
在进行 25 轮主动学习(每轮标注一批数据并重新训练 Transformer 模型)后,每轮收集 25 个标注。我重复了整个过程,下一次使用随机选择来决定每轮标注哪些示例——作为基准比较。在标注额外数据之前,两种方法都从相同的初始训练集(包含 100 个示例)开始(因此在第一轮中,Transformer 的准确率大致相同)。由于训练 Transformer 模型时固有的随机性,我对这个过程进行了五次运行(每种数据标注策略),并报告了五次重复运行中测试准确率的标准差(阴影区域)和均值(实线)。
我们可以看到,选择下一步标注哪些数据对模型性能有着显著的影响。使用 ActiveLab 的主动学习在每一轮中都显著优于随机选择。例如,在第 4 轮,总共有 275 个标注的训练集时,通过主动学习我们获得了 91% 的准确率,而在没有智能选择标注示例的情况下,准确率仅为 76%。总体来说,使用主动学习构建的数据集上训练的 Transformer 模型,其误差率大约是传统方法的 50%,无论总的标注预算是多少!
在进行文本分类数据标注时,你应考虑使用主动学习,并配合重新标注选项,以更好地应对标注者的不完美性。