AI 辅助的数据标注与主动学习:从人工标注到智能采样
AI 辅助的数据标注与主动学习:从人工标注到智能采样

一、数据标注的"人力黑洞":标注成本决定模型上限
深度学习模型的性能上限由训练数据的质量和数量决定。但高质量标注数据的获取成本极高:医学影像标注需要专业医生,法律文本标注需要律师,每条标注的成本从几元到数百元不等。一个包含 10 万条标注数据的中型项目,标注成本可能达到数十万元。
更隐蔽的问题是标注质量的不一致:不同标注者对同一数据的判断可能不同,同一标注者在不同时间的标准也可能漂移。AI 辅助的数据标注方案,通过模型预标注和主动学习,将人工标注从"全量标注"压缩为"关键样本标注 + 模型辅助审核"。
二、AI 辅助标注的架构设计
AI 辅助标注分为三个阶段:预标注(模型自动生成初始标签)、主动学习(选择最有价值的样本交由人工标注)、人工审核(确认或修正模型标签)。
flowchart TD
A[未标注数据池] --> B[模型预标注]
B --> C[不确定性评分]
C --> D{不确定性排序}
D -->|高不确定性| E[人工标注队列]
D -->|低不确定性| F[自动接受]
E --> G[人工标注/修正]
G --> H[加入训练集]
F --> H
H --> I[重新训练模型]
I --> B
subgraph 主动学习循环
B --> C --> D --> E --> G --> H --> I --> B
end
主动学习的核心思想是:不是所有样本对模型提升的贡献相同。模型最不确定的样本(决策边界附近的样本)信息量最大,标注这些样本可以最有效地提升模型性能。
三、工程化实现
3.1 不确定性采样策略
# active_learning.py
import numpy as np
from dataclasses import dataclass
@dataclass
class SampleScore:
index: int
uncertainty: float
prediction: int
confidence: float
class ActiveLearningSelector:
def __init__(self, strategy: str = 'entropy'):
self.strategy = strategy
def select_samples(
self,
probabilities: np.ndarray,
n_samples: int = 100,
) -> list[SampleScore]:
"""基于模型输出概率选择最不确定的样本"""
scores = self._compute_uncertainty(probabilities)
# 按不确定性降序排序,选择最不确定的样本
ranked = sorted(scores, key=lambda s: s.uncertainty, reverse=True)
return ranked[:n_samples]
def _compute_uncertainty(
self, probabilities: np.ndarray
) -> list[SampleScore]:
"""计算每个样本的不确定性分数"""
scores = []
for i, probs in enumerate(probabilities):
if self.strategy == 'entropy':
# 熵采样:信息熵越高越不确定
uncertainty = -np.sum(
probs * np.log(probs + 1e-10)
)
elif self.strategy == 'margin':
# 边缘采样:最高和次高概率的差越小越不确定
sorted_probs = np.sort(probs)[::-1]
uncertainty = 1 - (sorted_probs[0] - sorted_probs[1])
elif self.strategy == 'least_confident':
# 最不自信采样:最高概率越低越不确定
uncertainty = 1 - np.max(probs)
else:
raise ValueError(f"未知策略:{self.strategy}")
scores.append(SampleScore(
index=i,
uncertainty=float(uncertainty),
prediction=int(np.argmax(probs)),
confidence=float(np.max(probs)),
))
return scores
3.2 预标注与人工审核流程
# annotation_pipeline.py
class AnnotationPipeline:
def __init__(self, model, selector: ActiveLearningSelector):
self.model = model
self.selector = selector
def pre_annotate(
self,
unlabeled_data: list,
auto_accept_threshold: float = 0.95,
) -> dict:
"""对未标注数据进行预标注"""
# 模型推理
probabilities = self.model.predict_proba(unlabeled_data)
# 计算不确定性
scores = self.selector._compute_uncertainty(probabilities)
auto_accepted = []
needs_review = []
for score in scores:
item = {
'index': score.index,
'data': unlabeled_data[score.index],
'predicted_label': score.prediction,
'confidence': score.confidence,
'uncertainty': score.uncertainty,
}
if score.confidence >= auto_accept_threshold:
# 高置信度:自动接受,但仍需抽检
item['status'] = 'auto_accepted'
auto_accepted.append(item)
else:
# 低置信度:需要人工审核
item['status'] = 'needs_review'
needs_review.append(item)
return {
'auto_accepted': auto_accepted,
'needs_review': needs_review,
'auto_accept_rate': len(auto_accepted) / len(unlabeled_data),
}
def active_learning_round(
self,
unlabeled_data: list,
n_samples: int = 100,
) -> list[dict]:
"""主动学习:选择最有价值的样本进行标注"""
probabilities = self.model.predict_proba(unlabeled_data)
selected = self.selector.select_samples(probabilities, n_samples)
return [
{
'index': s.index,
'data': unlabeled_data[s.index],
'predicted_label': s.prediction,
'confidence': s.confidence,
'priority': 'high' if s.uncertainty > 0.8 else 'medium',
}
for s in selected
]
3.3 标注质量一致性检查
# quality_check.py
class AnnotationQualityChecker:
def check_inter_annotator_agreement(
self,
annotations: dict[str, list[int]],
) -> dict:
"""检查标注者间一致性(Cohen's Kappa)"""
annotators = list(annotations.keys())
if len(annotators) < 2:
return {'error': '至少需要 2 个标注者'}
a1 = np.array(annotations[annotators[0]])
a2 = np.array(annotations[annotators[1]])
# 计算 Cohen's Kappa
n_classes = max(a1.max(), a2.max()) + 1
confusion = np.zeros((n_classes, n_classes))
for i in range(len(a1)):
confusion[a1[i]][a2[i]] += 1
total = confusion.sum()
po = np.trace(confusion) / total # 观察一致率
pe = sum(
(confusion[i, :].sum() / total) *
(confusion[:, i].sum() / total)
for i in range(n_classes)
) # 期望一致率
kappa = (po - pe) / (1 - pe) if (1 - pe) > 0 else 0
return {
'kappa': round(kappa, 3),
'agreement_rate': round(po, 3),
'quality': (
'优秀' if kappa > 0.8
else '良好' if kappa > 0.6
else '需改进' if kappa > 0.4
else '不可接受'
),
}
四、AI 辅助标注的 Trade-offs
预标注的偏见传播:模型预标注会将模型的偏见传播给标注者。标注者倾向于接受模型的建议,即使模型是错的。建议在标注界面中隐藏模型预测,或以"建议"而非"默认值"的方式呈现。
主动学习的采样偏差:不确定性采样倾向于选择决策边界附近的样本,可能忽略边界外的罕见类别。建议混合使用不确定性采样和随机采样(如 80% 不确定性 + 20% 随机),确保类别覆盖。
自动接受的误报风险:高置信度不等于正确。模型可能对某些类别始终高置信但系统性地错误。建议对自动接受的样本进行 5%-10% 的抽检,确保自动接受的质量。
标注者疲劳:长时间标注会导致标注质量下降。建议将标注任务拆分为 30 分钟的短批次,每批次后休息,并定期插入已知答案的"金标准"样本检测标注者注意力。
五、总结
AI 辅助的数据标注将"全量人工"推进到"模型预标注 + 主动学习 + 人工审核",在保证标注质量的同时大幅降低人力成本。落地路线上,建议先用模型预标注降低标注工作量,再引入主动学习聚焦关键样本,最后建立质量检查机制确保一致性。关键原则:预标注是辅助而非替代,主动学习比随机采样更高效,质量检查是标注项目的生命线。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)