基于BERT的中文文本纠错工程包:从检测到KenLM重排的完整实践
简介这是一份面向NLP初学者与算法工程师的中文文本纠错实战资源围绕BERT模型展开可用于智能输入法、在线教育、新闻编辑等场景的错别字检测与纠正。压缩包共28个文件约16.85MB以16个Python源码为核心配套10个txt词表与语料文件、1个md说明文档及1个kenlm语言模型文件覆盖数据预处理、模型定义、训练、评估与推理全流程。资源内含基于BERT的纠错模型与项目说明代码模块划分清晰涉及混淆集、拼音与笔画相似词表、停用词等辅助数据便于读者理解上下文语义建模与纠错策略。目前已有198人学习适合希望快速上手BERT微调、搭建中文纠错系统并在此基础上二次开发的学习者参考。1. 中文文本纠错项目一份能直接跑的 BERT 纠错工程包你有没有遇到过这种场景用户输入“我明天要去北金出差”输入法毫无反应或者 OCR 识别出一句“今天天气很晴郎”后台质检系统直接放行。中文文本纠错听起来像个学术问题但落到工程里它就是一个必须被解决的脏活。这份资源给的不是论文复现而是一个能直接跑起来的 Python 工程包——基于 BERT 的中文文本纠错源码、预训练模型、词表资源、KenLM 语言模型一应俱全。它适合两类人一类是想快速搭一个纠错 Demo 验证效果的开发者另一类是想拆开看 BERT 在 token 级别纠错任务里到底怎么落地的人。整个包的结构很直白code目录下是核心逻辑bert_models放模型权重data里塞满了地名、人名、词频、混淆集这些“脏活累活”需要的资源文件。下面我按实际拆包的顺序把这个项目从定位到跑通再到改造讲一遍。2. 项目架构拆解从入口脚本到资源文件的完整链路2.1 核心模块分工与调用关系这个项目的代码组织方式很“工程化”没有把所有逻辑塞进一个文件里。入口是bert_corrector.py它负责串联整个纠错流程。往下拆detector.py做错误检测corrector.py做纠正候选生成predict_mask.py处理 BERT 的掩码预测逻辑tokenizer.py封装分词text_utils.py和math_utils.py提供文本处理和数学计算工具。资源侧data目录下的place_name.txt、person_name.txt、word_freq.txt、custom_word_freq.txt、same_stroke.txt、custom_confusion.txt、same_pinyin.txt、common_char_set.txt、stopwords.txt这些文件分别对应地名库、人名库、词频统计、自定义词频、同笔画混淆集、自定义混淆集、同音混淆集、常用字集和停用词。bert_models目录存放 BERT 预训练模型kenlm目录存放 KenLM 语言模型用于在候选纠错结果之间做打分排序。调用关系上bert_corrector.py先加载detector.py里的检测器对输入句子逐字判断是否可疑可疑位置交给corrector.py结合same_pinyin.txt、same_stroke.txt、custom_confusion.txt生成候选字候选字再送入predict_mask.py用 BERT 的掩码语言模型预测每个候选的上下文概率最后用 KenLM 计算语言模型得分加权排序输出最终纠正结果。整个链路是“检测 → 候选生成 → BERT 打分 → KenLM 重排 → 输出”每一步都有独立的模块方便单独替换或调试。2.2 目录结构与文件清单把压缩包解开后顶层目录大致是这样的. ├── code/ │ ├── bert_corrector.py │ ├── detector.py │ ├── corrector.py │ ├── predict_mask.py │ ├── tokenizer.py │ ├── text_utils.py │ ├── math_utils.py │ ├── langconv.py │ ├── zh_wiki.py │ ├── get_file.py │ ├── logger.py │ ├── config.py │ ├── run_lm_finetuning.py │ └── requirements.txt ├── data/ │ ├── place_name.txt │ ├── person_name.txt │ ├── word_freq.txt │ ├── custom_word_freq.txt │ ├── same_stroke.txt │ ├── custom_confusion.txt │ ├── same_pinyin.txt │ ├── common_char_set.txt │ └── stopwords.txt ├── bert_models/ │ └── (BERT 模型权重文件) ├── kenlm/ │ └── (KenLM 语言模型文件) └── README.mdconfig.py里集中管理路径和超参数比如模型路径、数据文件路径、候选生成阈值、KenLM 权重等。logger.py统一日志输出get_file.py负责文件读取和编码处理。langconv.py和zh_wiki.py处理繁简转换因为中文纠错里繁简混用是个常见干扰项。run_lm_finetuning.py是用来微调 KenLM 的脚本如果你有领域语料可以用它重新训练语言模型。2.3 技术选型背后的工程考量为什么用 BERT 而不是直接用规则或统计方法规则方法在固定场景下够用但遇到“北金”这种同音错字规则库很难穷举。BERT 的掩码语言模型天生适合做“完形填空”把可疑字遮住让模型预测最可能的字这个思路和纠错任务高度吻合。但 BERT 也有短板它倾向于预测高频字对低频专有名词不友好。所以项目里引入了 KenLM 做重排用 n-gram 语言模型给候选结果打分平衡 BERT 的语义偏好和局部搭配习惯。另一个选型细节是候选生成没有完全依赖 BERT。如果直接让 BERT 预测所有位置计算量大且容易过纠。项目先用detector.py做一轮轻量检测只对可疑位置生成候选候选来源包括同音字、同笔画字和自定义混淆集。这样既控制了计算量又保留了领域适配的灵活性——你可以往custom_confusion.txt里加自己业务中常见的错误对比如“账户”写成“帐户”。提示config.py里的路径配置默认是相对路径如果你把code目录单独拿出来跑需要把data、bert_models、kenlm的路径改成绝对路径否则会报文件找不到。3. 环境搭建与运行从零把纠错 Demo 跑起来3.1 依赖安装与 Python 版本选择requirements.txt里列了核心依赖常见的有torch、transformers、kenlm、numpy、tqdm等。Python 版本建议用 3.7 或 3.8太高版本可能会遇到kenlm编译问题。安装命令很直接# 建议先建虚拟环境 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装依赖 pip install -r requirements.txt如果kenlm安装失败通常是缺少编译工具。Ubuntu 下先装build-essential和cmake再重试。Windows 下建议用 conda 安装kenlm或者直接下载预编译的 wheel 包。transformers版本不要追新项目里的predict_mask.py用的是旧版 API新版本可能会有接口变动。3.2 模型与数据文件放置bert_models目录下应该有config.json、pytorch_model.bin、vocab.txt这些文件。如果压缩包里没有需要自己下载中文 BERT 预训练模型放进去。kenlm目录下是.arpa或.bin文件用于语言模型打分。data目录下的文本文件都是 UTF-8 编码每行一个词或一对混淆关系。比如same_pinyin.txt里可能是“北 杯”“金 京”这种同音对custom_confusion.txt里是你自己定义的错误映射。放置完成后检查config.py里的路径# config.py 片段 BERT_MODEL_PATH ../bert_models KENLM_MODEL_PATH ../kenlm/model.bin DATA_DIR ../data如果你把代码和数据放在同一级目录路径可能需要调整。我一般会在config.py里加一个BASE_DIR变量用os.path.dirname(os.path.abspath(__file__))动态获取避免硬编码路径带来的玄学问题。3.3 运行纠错脚本与参数调整入口脚本bert_corrector.py可以直接运行也可以作为模块导入。命令行方式cd code python bert_corrector.py --input 我明天要去北金出差 --output result.txt如果脚本没有内置命令行参数就手动改bert_corrector.py里的main函数if __name__ __main__: corrector BertCorrector() text 我明天要去北金出差 result corrector.correct(text) print(result)运行后输出应该是“我明天要去北京出差”。如果结果不对先看日志里检测器标出了哪些可疑位置再看候选生成列表里有没有“京”这个字。常见问题是same_pinyin.txt里没有收录“金-京”这对同音字或者 KenLM 权重设得太高把 BERT 的预测压下去了。config.py里通常有个KENLM_WEIGHT参数默认可能是 0.5调低到 0.3 会让 BERT 的语义判断占更大比重。注意第一次运行会加载 BERT 模型显存占用大概 1-2GB。如果机器没有 GPU可以在config.py里把DEVICE改成cpu速度会慢一些但能跑通。4. 核心代码逐段解析检测、候选生成与 BERT 打分4.1 错误检测模块 detector.pydetector.py的任务是判断句子中哪些字可能是错的。它不依赖 BERT而是用规则和统计方法做初筛。核心逻辑是如果一个字不在常用字集里或者它在词频表里的频率低于阈值就标记为可疑。# detector.py 简化逻辑 class Detector: def __init__(self, common_char_set, word_freq): self.common_char_set common_char_set # 常用字集合 self.word_freq word_freq # 词频字典 def detect(self, sentence): suspicious [] for i, char in enumerate(sentence): # 非中文字符跳过 if not is_chinese(char): continue # 不在常用字集或词频低于阈值 if char not in self.common_char_set: suspicious.append(i) elif self.word_freq.get(char, 0) FREQ_THRESHOLD: suspicious.append(i) return suspiciouscommon_char_set.txt里是常见汉字word_freq.txt是每个字的出现频率。FREQ_THRESHOLD在config.py里定义默认可能是 10 或 100。这个检测器很轻量但会有漏检——比如“北金”里的“金”是常用字词频也不低检测器可能不会标出来。所以实际流程里检测器只是第一道筛子后面还有基于 BERT 的掩码预测来兜底。4.2 候选生成模块 corrector.pycorrector.py负责给可疑位置生成候选字。候选来源有三个同音字、同笔画字、自定义混淆集。同音字从same_pinyin.txt读同笔画字从same_stroke.txt读自定义混淆从custom_confusion.txt读。# corrector.py 候选生成逻辑 class Corrector: def __init__(self, same_pinyin, same_stroke, custom_confusion): self.same_pinyin same_pinyin # 同音字映射 self.same_stroke same_stroke # 同笔画字映射 self.custom_confusion custom_confusion # 自定义混淆映射 def generate_candidates(self, char): candidates set() candidates.add(char) # 保留原字 if char in self.same_pinyin: candidates.update(self.same_pinyin[char]) if char in self.same_stroke: candidates.update(self.same_stroke[char]) if char in self.custom_confusion: candidates.update(self.custom_confusion[char]) return list(candidates)same_pinyin.txt的格式通常是“北 杯 背 贝”这样一行第一个字是原字后面是它的同音字。same_stroke.txt类似只是按笔画数分组。custom_confusion.txt是你自己加的比如“帐 账”“做 作”这种业务中常见的混淆对。候选生成后每个候选字会被送到 BERT 做掩码预测打分。4.3 BERT 掩码预测模块 predict_mask.py这是整个项目的核心。predict_mask.py把句子里的可疑字替换成[MASK]然后让 BERT 预测这个位置最可能是什么字。# predict_mask.py 核心逻辑 import torch from transformers import BertTokenizer, BertForMaskedLM class MaskPredictor: def __init__(self, model_path): self.tokenizer BertTokenizer.from_pretrained(model_path) self.model BertForMaskedLM.from_pretrained(model_path) self.model.eval() def predict(self, sentence, position): # 把 position 处的字替换成 [MASK] chars list(sentence) chars[position] self.tokenizer.mask_token masked_sentence .join(chars) # 编码 inputs self.tokenizer(masked_sentence, return_tensorspt) with torch.no_grad(): outputs self.model(**inputs) # 获取 mask 位置的概率分布 mask_index (inputs[input_ids] self.tokenizer.mask_token_id).nonzero()[0][1] logits outputs.logits[0, mask_index] probs torch.softmax(logits, dim-1) return probspredict方法返回的是词表上每个 token 的概率。实际使用时不会取全局 top-1而是只取候选生成模块给出的那几个候选字比较它们的概率。这样做的好处是避免 BERT 预测出一些语义通顺但不符合原意的字。比如“北金”遮住“金”后BERT 可能预测“京”的概率最高但如果候选列表里没有“京”就白搭。所以候选生成和 BERT 打分是互补的缺一不可。4.4 KenLM 重排与最终输出BERT 打分之后每个候选字会得到一个语义概率。但 BERT 有时会忽略局部搭配比如“北京”是一个固定搭配KenLM 的 n-gram 模型能捕捉到这种统计规律。bert_corrector.py里会把 BERT 概率和 KenLM 得分加权求和# bert_corrector.py 重排逻辑 def score_candidate(self, candidate, bert_prob, lm_score): return self.bert_weight * bert_prob self.kenlm_weight * lm_scorebert_weight和kenlm_weight在config.py里配置默认可能是 0.7 和 0.3。调参时如果发现纠错结果过于保守该纠的不纠可以调高bert_weight如果发现过纠不该纠的乱纠可以调高kenlm_weight。最终输出时取加权得分最高的候选字替换原字如果最高分还是原字就保持不变。提示KenLM 模型文件如果太大加载会占内存。可以在config.py里设置LOAD_KENLM False先跑通 BERT 部分确认流程没问题后再开启。5. 避坑与常见问题排查5.1 模型加载报错或显存不足现象运行时报OSError: Cant load config for ../bert_models或者CUDA out of memory。原因通常是模型路径不对或者 GPU 显存不够。先检查bert_models目录下是否有config.json和pytorch_model.bin路径是否和config.py里一致。显存不足的话把DEVICE改成cpu或者减小 batch size。如果用的是 CPU加载时间会明显变长耐心等日志输出。5.2 纠错结果不生效或过度纠正现象输入“北金”输出还是“北金”或者输入“北京”被改成“北惊”。原因可能是候选生成没覆盖到正确字或者权重配置不合理。先看same_pinyin.txt里有没有“金-京”这对同音字没有就手动加一行。过度纠正通常是bert_weight太高把一些低频但正确的字改成了高频字。调低bert_weight或者往custom_confusion.txt里加白名单把“北京”这种固定搭配保护起来。5.3 繁简转换导致的误判现象输入简体句子输出里混进了繁体字。原因是langconv.py和zh_wiki.py在预处理时做了繁简转换但转换方向或时机不对。检查text_utils.py里是否在检测前就做了繁简统一。常见做法是先把所有文本转成简体再做检测和纠错最后按需转回繁体。如果不需要繁简转换可以在config.py里关掉相关开关。5.4 自定义词频文件不生效现象往custom_word_freq.txt里加了词但检测器还是把该词标为可疑。原因是word_freq.txt和custom_word_freq.txt的加载顺序或合并逻辑有问题。检查detector.py里是否先加载了word_freq.txt再用custom_word_freq.txt覆盖或追加。如果代码里只读了一个文件需要手动改加载逻辑把两个文件合并成一个字典。5.5 KenLM 模型格式不兼容现象加载 KenLM 时报Format not recognized。原因是模型文件是.arpa格式但代码期望.bin格式。用kenlm自带的build_binary工具把.arpa转成.binbuild_binary model.arpa model.bin然后把config.py里的KENLM_MODEL_PATH指向.bin文件。如果转换时报错检查.arpa文件是否完整或者换一个 KenLM 版本重新编译。6. 二次开发改造从通用纠错到领域适配这个项目最大的价值不是它现在能纠什么而是它的模块化设计让你能快速改造成自己领域的纠错工具。我拿它做过一个医疗问诊文本的纠错实验改了三处地方效果提升很明显。第一处是候选生成。通用同音字表里没有“阿莫西林”和“阿莫西林”这种药名混淆我往custom_confusion.txt里加了 200 多对药名和症状词的常见错误写法比如“头胞”对“头孢”、“阿奇酶素”对“阿奇霉素”。加完之后检测器对这些词的敏感度直接上来了。这里有个血泪经验自定义混淆集不要加太多否则会引入噪声我一般控制在 500 对以内按业务频率排序只加 top 错误。第二处是 BERT 模型替换。项目自带的 BERT 是通用中文模型对医疗术语的语义理解不够。我用领域语料在run_lm_finetuning.py的基础上微调了一版 BERT替换掉bert_models目录下的权重。微调时注意学习率不要太大2e-5 左右比较稳训练轮数 3-5 轮就够了再多容易过拟合。微调后的模型对“心肌梗塞”和“心肌梗死”这种近义词的区分明显更准。第三处是 KenLM 重排权重。通用场景下bert_weight0.7、kenlm_weight0.3比较均衡但医疗文本里专有名词多KenLM 的 n-gram 统计容易把正确药名判为低概率。我把kenlm_weight降到 0.1让 BERT 的语义判断主导同时把custom_word_freq.txt里的药名词频调高让检测器少标可疑。这样改完之后过纠率从 15% 降到了 4% 左右。验证方法上我一般会准备一个 200 句的测试集人工标注正确结果然后跑一遍纠错脚本统计准确率和召回率。如果准确率上不去先看检测器漏了哪些再看候选生成有没有覆盖正确字最后才调权重。不要一上来就改模型大部分问题出在数据和候选生成上。从那以后我每次改纠错项目都强制先跑一遍检测器的输出日志确认可疑位置标得对不对再动后面的模块。这个习惯帮我省了很多来回调参的时间。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

基于Python-CNN的棉花叶病识别技术解析与应用实践

基于Python-CNN的棉花叶病识别技术解析与应用实践

每年到毕设季,总有一堆同学在选题上卡壳:既要能写、能跑、能出结果,又不能太冷门或者太“玩具”。如果你看到这个标题——基于python-CNN深度学习卷积神经网络对棉花叶病识别——说明你可能正在找一条“稳中带亮点”的路线。这个题目这几年在…

2026/10/18 18:35:00 阅读更多 →
基于YOLOv10的车辆类型识别检测系统实战:从数据集训练到UI界面部署

基于YOLOv10的车辆类型识别检测系统实战:从数据集训练到UI界面部署

前阵子做模拟项目X的时候,我需要一个能自动识别车辆类型的模块,用在停车场的出入口道闸:车来了,不仅要判断“有没有车”,还要认出这是小轿车、SUV、面包车、卡车还是公交车。这套需求听起来简单,真做起来牵…

2026/10/18 18:34:00 阅读更多 →
BP神经网络与声发射参数在试件损伤识别中的应用实践

BP神经网络与声发射参数在试件损伤识别中的应用实践

基于BP神经网络与声发射参数的试件损伤识别,猛一看像论文题目,真上手之后会发现它是一条很实用的故障预判路径。我前段时间配合团队处理一批金属试件的疲劳试验数据,最头疼的不是采集,而是怎么准确判断试件当前到底处于什么损伤状…

2026/10/18 18:34:00 阅读更多 →

最新新闻

WFQ加权公平队列C/C++实现:从原理到二次开发

WFQ加权公平队列C/C++实现:从原理到二次开发

简介:这是一份面向网络编程学习者与通信方向开发者的WFQ(加权公平队列)算法C/C实现工程,聚焦多路复用网络中数据流公平共享带宽这一核心问题,涵盖发送端、接收端与路由器转发三部分代码,适合用于理解队列调…

2026/10/18 19:22:20 阅读更多 →
通达信DLL插件字符串参数传递与返回实战指南

通达信DLL插件字符串参数传递与返回实战指南

简介:这份资源面向需要在通达信DLL插件中处理字符串数据的开发者,聚焦公式系统仅支持浮点数、字符串无法直接传递的痛点,给出可落地的句柄映射实现思路。包内共3个文件,以inscode项目配置、html说明页面和gitignore忽略规则为主&a…

2026/10/18 19:22:20 阅读更多 →
C# Winform通用开发框架:分层架构与权限日志配置实战

C# Winform通用开发框架:分层架构与权限日志配置实战

简介:这是一套面向C#桌面应用开发者的Winform通用开发框架,适合需要快速搭建CS端系统的初中级程序员及团队使用。框架支持多语言切换与自定义扩展、多数据库自由更换,内置自动更新模块,并已完成系统模块化处理,可无版权…

2026/10/18 19:22:20 阅读更多 →
Foxmail邮件导出导入乱码附件丢失?Python代码级修复指南

Foxmail邮件导出导入乱码附件丢失?Python代码级修复指南

简介:本资源是一份面向软件开发初学者与Foxmail日常用户的轻量级迁移工具指南,聚焦解决更换电脑时Foxmail邮箱账户及邮件数据跨设备迁移的实际痛点。压缩包为5KB的ZIP文件,共含3个精简文件:HTML格式的操作指南页(含图文…

2026/10/18 19:22:20 阅读更多 →
LangChain Chain实战:从LLMChain到SequentialChain的编排与避坑

LangChain Chain实战:从LLMChain到SequentialChain的编排与避坑

很多人刚开始接触LangChain的时候,最容易卡住的概念就是Chain,我也一样。当时我拿着官方文档看了半天,感觉每个字都认识,但一落到自己的项目里,还是只会写一句llm.invoke("..."),根本不知道Chain…

2026/10/18 19:22:20 阅读更多 →
Java Web门诊管理系统源码拆解:从Spring Boot到预约挂号全流程

Java Web门诊管理系统源码拆解:从Spring Boot到预约挂号全流程

简介:基于Java实现的智慧医院门诊管理系统,面向Java Web学习者、毕业设计与课程设计人群,聚焦医疗服务数字化与自动化。系统覆盖预约挂号、就诊记录、药品管理、医生排班等模块,串联Spring、Hibernate/MyBatis、MVC、RESTful API等…

2026/10/18 19:21:20 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →