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

cover

一、数据标注的"人力黑洞":标注成本决定模型上限

深度学习模型的性能上限由训练数据的质量和数量决定。但高质量标注数据的获取成本极高:医学影像标注需要专业医生,法律文本标注需要律师,每条标注的成本从几元到数百元不等。一个包含 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 辅助的数据标注将"全量人工"推进到"模型预标注 + 主动学习 + 人工审核",在保证标注质量的同时大幅降低人力成本。落地路线上,建议先用模型预标注降低标注工作量,再引入主动学习聚焦关键样本,最后建立质量检查机制确保一致性。关键原则:预标注是辅助而非替代,主动学习比随机采样更高效,质量检查是标注项目的生命线。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐