惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog
V
Vulnerabilities – Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
Latest news
Latest news
博客园 - 三生石上(FineUI控件)
美团技术团队
aimingoo的专栏
aimingoo的专栏
Google Online Security Blog
Google Online Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threatpost
Y
Y Combinator Blog
T
Tailwind CSS Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
小众软件
小众软件
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Tenable Blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
D
Docker
Cyberwarzone
Cyberwarzone
量子位
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog
雷峰网
雷峰网
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
The Hacker News
The Hacker News
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Full Disclosure
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
T
The Exploit Database - CXSecurity.com
Engineering at Meta
Engineering at Meta
O
OpenAI News
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
IT之家
IT之家
S
Secure Thoughts
MongoDB | Blog
MongoDB | Blog
L
Lohrmann on Cybersecurity
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News

博客园 - VipSoft

MinerU - 将非结构化文档(PDF、图片、Office 文件等)转换为机器可读的 Markdown 和 JSON LangChain 入门 服务端部署-FastAPI LangChain 入门 LangSmith LangChain 入门 实战 - 食谱推荐 LangChain 入门 Memory 会话记忆 LangChain 入门 Tools 工具 LangChain 入门 Tools 工具 LangChain 入门 Prompts 提示词 LangChain 入门 Message 消息 LangChain 入门 Model 的初始化和调用 LangChain 入门 Agent 的基本运行机制 AI 0基础学习,名词解析 LangChain 和 LangGraph AI大模型知识体系 Dify — Workflow - 数据可视化 Dify — 连接MySQL配置 Dify — Chatflow - 数据库智能查询 Dify — Chatflow - 文档知识库 Dify — Agent 智能体 高安全券码、注册码生成 Dify — 文本生成应用 Dify — 聊天助手 -- 知识库 Windows 下 Docker 安装 Dify Ollama — 命令 Ollama — 为什么能够运行不同的模型 Ollama — 接口 Qwen — 自定义模型文件 Ollama Qwen — 安装测试 Ollama Windows 安装 & 指定安装目录 跟着AI学AI - 诊断结论信息抽取 - 批量处理脚本 跟着AI学AI - 诊断结论信息抽取 - 模型压缩与部署 跟着AI学AI - 诊断结论信息抽取 - 模型评估与调试 轻型民用无人驾驶航空器安全操控理论考试培训材料 FreeRedis Helper Windbg w3wp.DMP 内存分析 跟着AI学AI - 诊断结论信息抽取 - 数据增强 QQ 录屏软件 Java - 加权随机算法 - 示例 Java - 加权随机算法--Demo Java LoadBalanceUtil 负载均衡、轮询加权 SpringBoot 集成 IP2Region 获取IP地域信息 Windows 服务器和虚拟主机,创建.开头的文件夹 .well-known 跟着AI学AI - 诊断结论信息抽取 - 数据格式转换BERT训练格式 跟着AI学AI - 诊断结论信息抽取 - LabelStudio 标注 -- 结论标注 跟着AI学AI - 诊断结论信息抽取 - 学习路径 跟着AI学AI - UV 安装 数据标注工具 Label-Studio `VIRTUAL_ENV=venv` does not match the project environment 跟着AI学AI - 学习路径 - 命名实体识别(NER)和信息抽取(IE) 跟着AI学AI - 需要购买显卡吗? C# 无BOM的UTF-8编码 Vue ref reactive Vue - el-table 嵌套表 Spring `@Scheduled` 中这些参数的区别、组合和应用场景 Python 找出同步日志中的重复数据 Python - UV PyCharm 不能识别 .venv 的环境
跟着AI学AI - 诊断结论信息抽取 - 模型训练
VipSoft · 2026-05-11 · via 博客园 - VipSoft

数据增强和自动标注只是准备数据的手段,最终目的是用这些数据训练出好用的模型。

seqeval 是一个专门用于评估序列标注任务(如命名实体识别 NER)的 Python 库。它支持多种标签格式(如 BIO、IOBES 等),并提供了计算准确率(Accuracy)、查准率(Precision)、召回率(Recall)和 F1 分数等指标的便捷方法。seqeval 适用于命名实体识别、词性标注和语义角色标注等任务。

# 设置镜像源的环境变量
(vippython) PS D:\OpenSource\Python\VipPython> $env:HF_ENDPOINT = "https://hf-mirror.com"
# 安装依赖
(vippython) PS D:\OpenSource\Python\VipPython> uv pip install seqeval
(vippython) PS D:\OpenSource\Python\VipPython> uv pip install accelerate>=0.26.0
# 切换下目录,否则会报文件不存在
(vippython) PS D:\OpenSource\Python\VipPython> cd D:\OpenSource\Python\VipPython\information_extraction
(vippython) PS D:\OpenSource\Python\VipPython\information_extraction> uv run .\information_extraction\train_ner_model.py

train_ner_model.py

# train_ner_model.py
import json
import torch
from transformers import (
    AutoTokenizer,
    AutoModelForTokenClassification,
    TrainingArguments,
    Trainer,
    DataCollatorForTokenClassification
)
from torch.utils.data import Dataset
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
import os


class NERDataset(Dataset):
    def __init__(self, data, label2id):
        self.data = data
        self.label2id = label2id

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        item = self.data[idx]
        return {
            'input_ids': torch.tensor(item['input_ids']),
            'attention_mask': torch.tensor(item['attention_mask']),
            'labels': torch.tensor(item['labels'])
        }


def compute_metrics(pred):
    """计算评估指标"""
    predictions, labels = pred
    predictions = np.argmax(predictions, axis=2)

    # 移除忽略的索引
    true_predictions = [
        [p for (p, l) in zip(pred_row, label_row) if l != -100]
        for pred_row, label_row in zip(predictions, labels)
    ]
    true_labels = [
        [l for l in label_row if l != -100]
        for label_row in labels
    ]

    # 计算指标
    from seqeval.metrics import classification_report as seq_report
    from seqeval.metrics import accuracy_score, f1_score, precision_score, recall_score

    # 将ID转换为标签名
    id2label = {v: k for k, v in label2id.items()}

    predictions_labels = [[id2label[p] for p in pred] for pred in true_predictions]
    references_labels = [[id2label[l] for l in ref] for ref in true_labels]

    return {
        'f1': f1_score(references_labels, predictions_labels),
        'precision': precision_score(references_labels, predictions_labels),
        'recall': recall_score(references_labels, predictions_labels),
        'accuracy': accuracy_score(references_labels, predictions_labels)
    }


def train_model(train_file, valid_file, label2id, output_dir='./ner_model'):
    """训练NER模型"""
    print("=" * 60)
    print("开始训练NER模型")
    print("=" * 60)

    # 1. 加载数据
    print("加载训练数据...")
    with open(train_file, 'r', encoding='utf-8') as f:
        train_data = json.load(f)

    with open(valid_file, 'r', encoding='utf-8') as f:
        valid_data = json.load(f)

    print(f"训练集: {len(train_data)} 条")
    print(f"验证集: {len(valid_data)} 条")

    # 2. 创建数据集
    train_dataset = NERDataset(train_data, label2id)
    valid_dataset = NERDataset(valid_data, label2id)

    # 3. 加载模型
    tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")
    model = AutoModelForTokenClassification.from_pretrained(
        "bert-base-chinese",
        num_labels=len(label2id),
        id2label={str(k): v for k, v in id2label.items()},
        label2id=label2id
    )

    # 4. 训练参数
    training_args = TrainingArguments(
        output_dir=output_dir,
        num_train_epochs=10,  # 训练轮数
        per_device_train_batch_size=16,  # 批次大小
        per_device_eval_batch_size=16,
        learning_rate=2e-5,  # 学习率
        weight_decay=0.01,  # 权重衰减
        warmup_ratio=0.1,  # 预热比例
        logging_dir='./logs',
        logging_steps=50,
        eval_strategy="epoch",  # 每个epoch评估一次
        save_strategy="epoch",  # 每个epoch保存一次
        load_best_model_at_end=True,  # 结束时加载最佳模型
        metric_for_best_model="f1",
        greater_is_better=True,
        save_total_limit=3,  # 只保留最后3个模型
        fp16=False,  # 没有GPU设为False
        report_to="none",  # 不报告到wandb等
    )

    # 5. 数据整理器
    data_collator = DataCollatorForTokenClassification(tokenizer)

    # 6. 创建训练器
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=valid_dataset,
        tokenizer=tokenizer,
        data_collator=data_collator,
        compute_metrics=compute_metrics
    )

    # 7. 开始训练
    print("\n开始训练...")
    trainer.train()

    # 8. 保存模型
    print(f"\n保存模型到: {output_dir}")
    trainer.save_model()
    tokenizer.save_pretrained(output_dir)

    # 9. 保存标签映射
    with open(os.path.join(output_dir, 'label2id.json'), 'w', encoding='utf-8') as f:
        json.dump(label2id, f, indent=2, ensure_ascii=False)

    with open(os.path.join(output_dir, 'id2label.json'), 'w', encoding='utf-8') as f:
        json.dump(id2label, f, indent=2, ensure_ascii=False)

    print("训练完成!")
    return trainer


if __name__ == "__main__":
    # 加载标签映射
    with open('data/out/labels_info.json', 'r', encoding='utf-8') as f:
        labels_info = json.load(f)
    label2id = labels_info['label2id']
    id2label = {int(k): v for k, v in labels_info['id2label'].items()}

    # 训练模型
    train_model(
        train_file='data/out/bert_training_data_ecg_augmented.json',  # 增强后的数据
        valid_file='data/out/bert_training_data.json',  # 原始数据作为验证集
        label2id=label2id,
        output_dir='./ecg_ner_model'
    )

image