AI零样本学习:训练与推理笔记

我分析了几个失败的例子,发现:

  1. 类别定义模糊:有些文献涉及多个领域,模型不知道优先选哪个
  2. 摘要缺乏约束:模型不知道哪些信息是"关键"的
  3. 任务顺序:应该先分类再摘要,因为摘要重点取决于所属领域

我调整了策略,把任务拆分,每步给更明确的指示。

为什么写这个

最近在做一个新项目,需要对一批医疗文献进行分类和摘要。听起来很简单吧?但问题来了:

  • 没有任何标注数据
  • 领域很专,通用模型效果差
  • 预算有限,雇不起医学专家标注
  • 项目时间紧,等不起传统的数据收集流程

这时候有人提了句"用零样本学习吧",我一开始还以为是啥黑科技。折腾了一圈才发现,其实就是用Prompt工程的思路,让大模型"举一反三"。

这篇文章记录我踩过的坑和最终能用的方案,给同样遇到类似问题的人参考。

先说清楚啥是零样本学习

传统机器学习是"教孩子认字",先给孩子看一堆"苹果"的图片,告诉孩子这是苹果,然后孩子看到类似的就能认出来。

零样本学习更像是"给读书人看说明书":你从来没见过某种水果,但有人告诉你"这种水果是红色的,圆的,皮可以剥开,里面是白色的,吃起来甜甜的",你下次见到的时候大概率能猜出来是苹果。

在AI领域,零样本学习就是模型在没有见过特定任务示例的情况下,仅通过任务描述就能完成任务。这主要依赖两个基础:

  1. 大模型的预训练知识:模型在海量文本上训练过,各种概念和模式都见过
  2. 清晰的指令设计:用自然语言把任务要求说清楚

零样本学习 vs 传统学习

左边的传统学习像"教孩子认字",需要大量标注数据;右边的零样本学习像"给读书人看说明书",靠模型已有的知识和清晰的任务描述来举一反三。

需求分析

回到我的项目,具体需求是:

  • 输入:医学文献的标题和摘要
  • 输出:分类标签(比如"心血管疾病"、“糖尿病研究"等)+ 关键结论摘要
  • 约束:没有训练数据,只有少量领域术语字典

这个问题看起来很适合零样本学习:

  • 文本是标准格式,模型理解能力强
  • 任务描述清晰:分类+摘要
  • 可以利用模型的通用医学知识

但真正做的时候发现事情没那么简单。

第一次尝试:直接上Prompt

我先写了个最简单的Prompt:

请对以下医学文献进行分类和摘要:

标题:{title}
摘要:{abstract}

要求:
1. 从以下类别中选择最合适的:心血管疾病、糖尿病研究、肿瘤学、神经科学、其他
2. 提取关键结论,用100字以内总结

结果不太行:

  • 分类准确率只有60%左右
  • 摘要不聚焦,经常包含无关信息
  • 处理速度慢,每篇文献要3-5秒

问题在哪呢?我分析了几个失败的例子,发现:

  1. 类别定义模糊:有些文献涉及多个领域,模型不知道优先选哪个
  2. 摘要缺乏约束:模型不知道哪些信息是"关键"的
  3. 任务顺序:应该先分类再摘要,因为摘要重点取决于所属领域

第二次尝试:分步优化

我调整了策略,把任务拆分,每步给更明确的指示。

2.1 先分类,再摘要

## 第一步:文献分类

文献标题:{title}
文献摘要:{abstract}

请从以下类别中选择最合适的一个:
- 心血管疾病:与心脏、血管系统相关的研究
- 糖尿病研究:与糖尿病、血糖控制相关的研究
- 肿瘤学:与癌症、肿瘤相关的研究
- 神经科学:与神经系统、脑科学相关的研究
- 其他:以上未涵盖的医学领域

要求:
- 如果文献涉及多个领域,选择最主要的领域
- 只输出类别名称,不要解释

## 第二步:领域摘要

分类结果:{category}

基于"{category}"领域,提取文献的核心结论:
- 重点关注该领域的治疗进展、新发现或重要结论
- 忽略通用方法描述
- 使用80-120字总结

摘要:

这样改动后,分类准确率提升到了75%,摘要也更聚焦了。

2.2 添加示例引导

零样本学习的精髓是"零样本”,但实际上给一两个示例能显著提升效果。这叫"Few-shot",但为了保持零样本的纯粹性,我只在Prompt里放通用的结构示例:

示例输出格式:

类别:心血管疾病
摘要:研究发现ACE抑制剂能降低30%的心力衰竭再住院风险,建议作为标准治疗方案。

这下模型更清楚输出格式了。

关键踩坑点

3.1 指令长度 vs 理解深度

一开始我把所有规则都写进去,Prompt长达2000字,结果效果反而变差了。后来发现:

  • 模型注意力有限,太长的指令会"稀释"关键信息
  • 应该用"层级式"指令:核心任务简单说,细节约束分点列

最后我把核心指令压缩到300字以内,准确率反而提升了。

3.2 领域术语对齐

有些医学专业术语,模型理解可能和实际用法有偏差。比如"DM"在医学上可以是"糖尿病"(Diabetes Mellitus),但在其他语境可能是"数据挖掘"。

解决方法是在Prompt里加个术语表:

注意:以下术语在本任务中的含义:
- DM = 糖尿病(Diabetes Mellitus)
- CAD = 冠心病(Coronary Artery Disease)
...

3.3 输出稳定性

同一个输入,多次调用模型可能会得到不同结果。这对分类任务尤其致命。

我采用了两种策略:

  1. 温度参数:把temperature设为0.2,降低随机性
  2. 多数投票:调用3次,选出现次数最多的结果

这样稳定性好了很多,但速度会慢一点,需要权衡。

3.4 错误处理

模型偶尔会"抽风",输出格式不对或者内容明显错误。必须加验证逻辑:

def validate_output(result):
    # 检查类别是否在预定义列表中
    if result['category'] not in VALID_CATEGORIES:
        result['category'] = '其他'

    # 检查摘要长度
    summary = result['summary']
    if len(summary) < 50 or len(summary) > 200:
        # 重新生成摘要
        result['summary'] = regenerate_summary(result)

    return result

最终方案

经过反复迭代,最终的工作流程是这样的:

graph LR A[输入文献] --> B[预处理] B --> C[零样本分类] C --> D{类别有效?} D -->|否| E[标记为'其他'] D -->|是| F[领域摘要生成] F --> G{摘要长度OK?} G -->|否| H[重新生成] G -->|是| I[输出结果] E --> I H --> F

关键代码片段:

def classify_and_summarize(title, abstract, max_retries=2):
    """零样本文献分类与摘要"""

    # 预处理
    text = preprocess_text(title, abstract)

    # 第一次尝试
    result = call_llm(
        prompt=build_prompt(text),
        temperature=0.2
    )

    # 验证
    result = validate_output(result)

    # 失败重试
    if not is_valid(result) and max_retries > 0:
        return classify_and_summarize(title, abstract, max_retries-1)

    return result

def build_prompt(text):
    """构建优化后的Prompt"""

    prompt = f"""
## 文献分类

{text}

请从以下类别中选择最合适的一个:
- 心血管疾病:与心脏、血管系统相关的研究
- 糖尿病研究:与糖尿病、血糖控制相关的研究
- 肿瘤学:与癌症、肿瘤相关的研究
- 神经科学:与神经系统、脑科学相关的研究
- 其他:以上未涵盖的医学领域

要求:
- 只输出类别名称,不要解释
- 如果涉及多个领域,选择最主要的

类别:

## 领域摘要

基于所选领域,提取核心结论:
- 重点关注该领域的治疗进展、新发现或重要结论
- 使用80-120字总结

摘要:
"""

    return prompt

效果与总结

最终效果:

指标初始版本优化版本
分类准确率60%82%
摘要相关性65%85%
处理速度3-5秒/篇2-3秒/篇
输出稳定性70%95%

零样本学习优化效果对比

从图表看,分类准确率提升了22个百分点,摘要相关性提升了20个百分点,输出稳定性更是从70%提升到95%。虽然还是无法和有监督学习比,但对于没有标注数据的场景来说,这个结果已经足够用了。

如果没有标注数据无法精确评估,但抽样人工检查,结果还算满意。

这趟折腾的感悟

零样本不是万能的

零样本学习适合"任务明确 + 模型知识覆盖"的场景:

  • ✅ 文本分类、摘要、问答等NLP任务
  • ✅ 通用领域或常见专业领域
  • ✅ 对准确率要求不是特别高的场景

不适合:

  • ❌ 模型训练数据中没有覆盖的领域
  • ❌ 需要高度精确的任务
  • ❌ 数据格式非常规的任务

Prompt工程是核心

零样本学习的本质是Prompt工程。好的Prompt要:

  1. 任务清晰:一句话说清楚要做什么
  2. 约束明确:什么能做、什么不能做
  3. 格式规范:输出格式要有具体要求
  4. 示例引导:用少量示例明确期望

工程化很重要

零样本学习不是调完Prompt就完了,还需要:

  • 输入预处理:清洗、标准化
  • 输出验证:检查格式、内容合理性
  • 错误处理:重试机制、降级策略
  • 性能优化:缓存、批处理

后续优化方向

如果还要继续优化,我会考虑:

  1. 领域自适应:用少量标注数据微调模型
  2. 多模型集成:结合不同模型的结果
  3. 反馈闭环:人工标注结果,持续改进Prompt
  4. 性能监控:跟踪准确率、速度等指标

但就目前而言,零样本学习已经解决了我的问题,在有限的时间和预算内达到了可用效果。

最后

零样本学习听起来高大上,其实就是用更聪明的Prompt让模型更好地干活。关键不是找什么神奇算法,而是理解任务、理解模型,然后耐心地迭代优化。

希望这篇文章能帮你少踩点坑。如果有什么问题或者更好的方法,欢迎交流。

版权声明: 本文首发于 指尖魔法屋-AI零样本学习:训练与推理笔记https://blog.thinkmoon.cn/post/304-ai-zero-shot-learning-training-inference-practice/) 转载或引用必须申明原指尖魔法屋来源及源地址!