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

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
K
Kaspersky official blog
A
Arctic Wolf
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
N
News | PayPal Newsroom
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
W
WeLiveSecurity
Know Your Adversary
Know Your Adversary
博客园 - Franky
T
Tenable Blog
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Help Net Security
Help Net Security
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
J
Java Code Geeks
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
NISL@THU
NISL@THU
O
OpenAI News
The Cloudflare Blog
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
V
V2EX
罗磊的独立博客
美团技术团队
博客园 - 三生石上(FineUI控件)
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏

博客园 - 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