AI-For-Beginners 第 13 课实战任务:用自定义数据集重跑文本表示 Notebook(BoW、N-Gram 与 TF-IDF)
教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载本指南围绕 AI-For-Beginners 第 5 单元第 13 课NLP 文本表示的课程作业展开讲解如何把仓库内两套文本表示 NotebookPyTorch 版与 TensorFlow 版从 AG News 基准数据集迁移到你自己选择的数据集上重新运行并说明在改写过程中如何记录与突出个人发现、如何遵守数据集来源标注要求。读完本指南你将掌握文本分类 词袋BoW/ N-Gram / TF-IDF 向量化这一整套可迁移的动手流程并能独立完成从数据加载、向量化到分类器训练与结果解读的闭环实验。任务速览这份 Assignment 到底要求什么课程作业原文位于 作业文档其核心要求可以拆解为四步选取 Notebook使用本课附带的 PyTorch 版 Notebook 或 TensorFlow 版 Notebook任选其一即可换数据重跑用自己的数据集重新运行该 Notebook。数据可以来自 Kaggle 等公开平台但必须注明出处attribution改写以突出发现不要只是机械地跑通而是改造 Notebook 使其突出你自己的分析结论与观察尝试创新数据集鼓励选取一些出人意料、可能带来惊喜结论的数据集例如 NUFORC美国国家不明飞行物报告中心维护的 UFO 目击记录数据集——这类文本与常规新闻完全不同往往能暴露文本表示方法的真实行为。需要说明的是本作业是 课程 README 中 Challenge环节之后的正式实践任务与课前/课后测验共同构成该课的完整学习闭环。作业所依赖的全部技术内容文本分类、分词、词袋、N-Gram、TF-IDF都沉淀在课程 README 与两套 Notebook 中因此本文先梳理这条技术基线再给出换数据的改造步骤。先读懂要改造的 Notebook文本表示的技术骨架课程上下文基于 AG News 的文本分类整个第 13 课聚焦一个典型 NLP 任务——文本分类text classification。基线数据集为 AG News 新闻数据集每条样本由「类别 标题 正文」组成目标是把新闻分入 World、Sports、Business、Sci/Tech 四个类别之一。仓库内的示例样本形如类别Sci/Tech标题Ky. Company Wins Grant to Study Peptides (AP)正文AP - A company founded by a chemistry researcher at the University of Louisville won a grant to develop...文本如何变成张量从字符到 token 再到向量要让神经网络处理文本首先必须把文本表示为张量。计算机本身并不理解字母的语义——字符只是通过 ASCII/UTF-8 等编码映射为数字课程 README 给出了两类基础表示方案字符级表示character-level把每个字符当作一个数字。若语料有C个不同字符单词Hello将表示为一个 5×C的张量每个字母对应 one-hot 编码中的一列词级表示word-level先为语料中所有词建立词表vocabulary再用 one-hot 编码表示每个词。这种方式语义层次更高但词表很大时会带来高维稀疏张量问题。无论采用哪种表示第一步都是把文本切分为tokenstoken 可以是字符、单词甚至词的一部分再借助词表把 token 映射为数字最终喂给神经网络。N-Gram把上下文纳入词表单词的精确含义只能由上下文决定——neural network与fishing network含义完全不同。一种朴素做法是把词对当作独立 token句子I like to go fishing会被切分为I like、like to、to go、go fishing。代价是词表急剧膨胀且go fishing与go shopping虽是同一动词却毫无共享语义。这种词对、三词组合统称n-gramsbigram 为 2-gramtrigram 为 3-gram同样也适用于字符级表示。Bag-of-Words固定长度向量 词频做分类任务时我们需要用一个固定长度的向量表示整段文本。最简单的方式是把所有词的 one-hot 向量直接相加——得到的就是一个词频向量即Bag-of-WordsBoW。BoW 记录文本里出现了哪些词、各出现多少次这往往已能很好指示文本主题政治新闻常含president、country科研文献则多collider、discovered等词。BoW 的缺陷在于高频停用词如and、is会掩盖真正重要的词这正是下一节 TF-IDF 要解决的问题。TF-IDF按文档频率压低常见词权重TF-IDFterm frequency–inverse document frequency是 BoW 的变体不再用 0/1 或纯频数而是用浮点权重词i在文档j中的权重为$$w_{ij} tf_{ij}\times\log({N\over df_i})$$其中tf_ij是词i在文档j中出现的次数即 BoW 值N是文档总数df_i是包含词i的文档数。权重随词在文档中出现次数增多而增大同时被包含该词的文档数抵消——若某词出现在每一篇文档中df_i N则w_ij 0该词被完全忽略。无论是 BoW 还是 TF-IDF都无法表达语义与词序。正如语言学家 J. R. Firth 在 1935 年所言一个词的完整含义总是语境化的脱离语境的词义研究不足为信。课程的后续单元语言建模、词嵌入将解决这一问题——这也在提醒你作业中观察到的BoW/TF-IDF 的上限是方法本身的固有边界而非你的实现缺陷。两套 Notebook 的完整处理链路改造的基准线作业要求你重跑并改写的 Notebook其内部处理链路值得先完整梳理因为换数据时你改动的正是这条链路的输入环节。PyTorch 版链路TextRepresentationPyTorch.ipynb加载数据通过torchtext.datasets.AG_NEWS(root./data)加载数据集训练/测试集均为迭代器每条样本返回(label, text)元组classes [World, Sports, Business, Sci/Tech]。由于迭代器只能消费一次随后用list(...)固化分词torchtext.data.utils.get_tokenizer(basic_english)把文本切为 token 列表如He said: hello→[he, said, hello]建词表用collections.Counter统计 token 频率后调用torchtext.vocab.vocab(counter, min_freq1)AG News 全量词表约95,810个词Notebook 输出原话为 Vocab size if 95810。通过vocab.get_stoi()拿到 token→索引映射实现encode()函数把文本编码为索引序列BoW 向量化to_bow()对编码后的索引序列做词频累加返回长度等于vocab_size的 float32 张量。Notebook 特别提示调低词表大小再训练观察准确率如何变化——预期会有一定下降但不剧烈换取更高训练性能组织 batch把bowify函数作为collate_fn传入torch.utils.data.DataLoader其中标签统一t[0]-1AG News 标签从 1 开始转为 0 基特征用torch.stack([to_bow(...)])堆叠定义分类器单线性层torch.nn.Sequential(torch.nn.Linear(vocab_size,4), torch.nn.LogSoftmax(dim1))输入维度 词表大小输出维度 4 个类别训练循环train_epoch()用 Adam 优化器默认 lr0.01、NLLLoss损失支持epoch_size截断训练教学用只训部分数据与report_freq控制进度打印。Notebook 中在 15,000 条样本上训练一个 epoch 后得到约86.2%的训练准确率loss ≈ 0.0261。TensorFlow 版链路TextRepresentationTF.ipynb加载数据tfds.load(ag_news_subset)加载 TensorFlow Datasets 版 AG News经dataset[train]/dataset[test]取子集样本字段为label、title、description向量化使用keras.layers.experimental.preprocessing.TextVectorization(max_tokensvocab_size)先adapt(ds_train.take(500).map(extract_text))在部分数据上建立词表——Notebook 中把vocab_size限制为 50,000最终实际词表长度约5,335。Notebook 明确提醒只用子集建词表是为了提速全量adapt会小幅提升最终准确率BoW 向量化to_bow()用tf.reduce_sum(tf.one_hot(vectorizer(text), vocab_size), axis0)对 one-hot 向量求和随后用map(...).batch(batch_size)batch_size128构造训练/测试数据集定义分类器keras.Sequential([keras.layers.Dense(4, activationsoftmax, input_shape(vocab_size,))])损失为sparse_categorical_crossentropy优化器 Adam指标acc。Notebook 指出4 分类问题准确率超过 80% 已是好结果端到端单网络由于TextVectorization本身是 Keras 层可以把它并入模型输入侧keras.Input 向量化层 one-hot 求和 Dense免去map预处理训练时直接喂原始文本自动 BoW / TF-IDFTextVectorization(max_tokens..., output_modecount)可自动输出词频向量output_modetf-idf则可自动计算 TF-IDF 权重——这是该 Notebook 提供的最便捷实验开关用于对比手动 one-hot 求和与内置向量化两种实现。两版对比小结环节PyTorch 版TensorFlow 版数据源torchtext.datasets.AG_NEWStfds.load(ag_news_subset)分词/建词表get_tokenizer(basic_english)vocab(counter, min_freq1)TextVectorization(max_tokens...)adapt()BoW 计算to_bow()手动累加词频one-hot 求和或output_modecountTF-IDF用 sklearn 的TfidfVectorizer(ngram_range(1,2))演示内置output_modetf-idf分类器Linear(vocab_size,4) LogSoftmax NLLLoss AdamDense(4, softmax) sparse_categorical_crossentropy Adam关键超参min_freq、vocab_size、epoch_size、report_freq、batch_sizemax_tokens、adapt样本数、batch_size用自己的数据集替换 AG News具体操作步骤第 1 步选择并获取数据集注意出处标注Kaggle 等平台上有大量适合文本分类的公开数据集。作业特别鼓励创新选题——不一定要再选新闻可以选社会观测、历史档案、事件记录等非常规语料。使用他人数据时务必在 Notebook 中注明来源与作者题目中的used with attribution是硬性要求。第 2 步统一数据格式为 (label, text)两套 Notebook 的后续代码都依赖统一的样本协议这是替换的核心PyTorch 版要求训练/测试集是返回(label, text)元组的可迭代对象且标签按classes列表的 0 基索引组织bowify中t[0]-1的减一逻辑需与你的标签体系保持一致——若你的数据已是 0 基可去掉减一或调整 classes 排列TensorFlow 版要求样本是包含label、title、description或可映射出文本字段的结构。最省事的方式是用tf.data.Dataset.from_tensor_slices构造再复用现有的extract_text/tupelize辅助函数注意extract_text中x[title] x[description]的拼接逻辑需对应你数据的文本字段名。第 3 步替换数据加载入口PyTorch 版把train_dataset, test_dataset torchtext.datasets.AG_NEWS(root./data)替换为你的数据读取代码如 pandas/CSV 读取后构造元组列表并同步替换classes列表与torchtext.datasets.AG_NEWS相关的所有引用TensorFlow 版把tfds.load(ag_news_subset)替换为你的数据集构造代码随后dataset[train]/dataset[test]的取子集方式也需相应调整。第 4 步按数据集特点调整关键参数词表规模PyTorch 版用min_freq控制最低词频Notebook 建议观察提高min_freq后词表长度如何显著下降TensorFlow 版用max_tokens直接截断。对自定义数据集建议先打印词表长度再决定截断值N-Gram 规模bigram 会让词表爆炸——PyTorch 版在 AG News 上构建 bigram 词表得到约1,308,842个 tokenNotebook 输出 Bigram vocabulary length 1308842。TF 版同样提示 bigram 词表超过 130 万 token。除非与 embedding 降维结合否则不建议对小语料直接上高维 n-gram训练量你的数据集可能远小于 AG News约 12 万条训练样本。此时可把epoch_size调大或不设PyTorch 版默认None表示完整跑一个 epoch并增加 epoch 数report_freq决定进度打印频率小数据集可调小以观察更多中间结果。实验设计尝试出人意料的数据集作业特意举例NUFORC 的UFO 目击记录数据集可在 Kaggle 检索到使用须注明出处。这类数据与新闻语料差异巨大恰好能检验文本表示方法的泛化能力你可以围绕它设计如下观察点分类目标自定UFO 目击记录包含目击形状、时长、地点、描述等文本字段可自定义分类任务例如按目击类型/地区分组验证 BoW 是否同样有效领域词汇差异此类语料的高频词时间、地点、形状描述词与新闻完全不同可对比直接跑与清理停用词后跑两种配置下词频分布的差异方法与数据规模的交互在小语料上对比 BoW、bigram、TF-IDF 三种表示的训练准确率观察 n-gram 词表爆炸在小语料上的实际影响不确定性与边界目击描述常含自由文本噪声可借此观察低频词、拼写变体对词表构建和分类结果的影响。更一般的选题建议选择类别数不同≠4、文本长度分布不同、含明显领域词汇的数据集能让替换数据这一动作产生真正有信息量的对比结论。突出个人发现改写 Notebook 的落点Rewrite the notebook to underline your own findings要求你留下可复现、可解释的证据链建议至少包含以下四类输出训练过程记录保留/改造训练循环的进度打印呈现准确率随样本数上升的曲线数据PyTorch 版示例输出3200 条时 80.28%、6400 条时 83.72%、9600 条时 85.34%、12800 条时 85.77%最终 86.2%——换成你的数据后这一组数字本身就是最有说服力的发现词汇表分析打印你的数据集词表长度、Top-N 高频词对比限制vocab_size/max_tokens前后准确率与训练时间的变化Notebook 明确建议做这个实验方法横向对比在相同数据上分别训练 BoW、bigram若内存允许、TF-IDF 三个分类器用表格汇总各自的词表大小、训练耗时与准确率并解释差异原因结论与边界明确指出你的数据上哪种表示最有效、哪种场景下出现反直觉现象并呼应课程结论——频次类方法无法表达语义与词序若需要更强效果应走向词嵌入与语言模型见 课程 README 的后续单元导览。提交前的自检清单✅ 明确选用了 PyTorch 版还是 TensorFlow 版 Notebook✅ 用自己的数据集而非 AG News完成了从加载、向量化到训练的全流程✅ Notebook 中注明了数据集来源与作者attribution✅ 记录了训练中间结果、词表规模等观察数据而非只有最终准确率✅ 对 BoW / N-Gram / TF-IDF 至少做了部分对比并给出自己的解读✅ 尝试了一个出人意料的数据集如 NUFORC 的 UFO 目击数据并说明其带来的新观察✅ 全文与 作业原文 的四项要求逐一对应可独立复现。完成以上步骤你就完整交付了这份作业既吃透了 课程 README 中的文本表示理论也通过亲手替换数据集验证了 BoW、N-Gram 与 TF-IDF 三种经典表示在真实甚至非常规语料上的行为差异为下一课学习词嵌入Embeddings打下了可对比的实践经验基础。赞分享教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载相关推荐AI-For-Beginners 文本表示实战指南用自定义数据集重跑 BoW、N-Gram 与 TF-IDF 笔记本AI For Beginners 文本表示实战指南用自定义数据集重跑 BoW、N Gram 与 TF IDF 笔记本 本指南面向《AI For Beginne教程人工智能机器学习深度学习用自定义数据集重跑 AI-For-Beginners 文本表示 Notebook从 BoW 到 TF-IDF 的完整实战指南用自定义数据集重跑 AI For Beginners 文本表示 Notebook从 BoW 到 TF IDF 的完整实战指南 本指南对应 AI For Beg教程人工智能机器学习深度学习AI-For-Beginners 课程详解将文本表示为张量——从字符编码、N-Gram 到 BoW 与 TF-IDF 的完整实战AI For Beginners 课程详解将文本表示为张量——从字符编码、N Gram 到 BoW 与 TF IDF 的完整实战 本文是微软 AI For B教程人工智能机器学习深度学习上一篇AI-HF_Patch终极指南5步解锁AI少女游戏的完整体验下一篇AI少女游戏优化终极指南5个步骤让游戏体验提升300%创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

从会用到会优化:YOLOv5训练流程、损失函数与增强策略全解析

从会用到会优化:YOLOv5训练流程、损失函数与增强策略全解析

开篇导读: 很多人会用 YOLOv5 训练命令,但指标一掉就只会"加epoch、改lr、换增强"。结果是参数改了一堆,却说不清到底哪一步真正生效,也无法复现实验收益。这篇文章不讲"玄学调参"。我会按源码执行路径&#…

2026/10/3 13:39:45 阅读更多 →
免费 macOS 窗口管理工具 Loop 完整指南:5 分钟用径向菜单和快捷键搞定分屏暂存

免费 macOS 窗口管理工具 Loop 完整指南:5 分钟用径向菜单和快捷键搞定分屏暂存

免费 macOS 窗口管理工具 Loop 完整指南:5 分钟用径向菜单和快捷键搞定分屏暂存 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 下午两点,你屏幕上摊着 9 个窗口。想给终端腾出右…

2026/10/3 13:39:45 阅读更多 →
FaceFusion 离线部署指南:四步在内网跑通 AI 换脸

FaceFusion 离线部署指南:四步在内网跑通 AI 换脸

FaceFusion 离线部署指南:四步在内网跑通 AI 换脸 【免费下载链接】facefusion Industry leading face manipulation platform 项目地址: https://gitcode.com/GitHub_Trending/fa/facefusion FaceFusion 是一款支持换脸、人脸增强、年龄修改的 AI 面部处理平…

2026/10/3 13:39:45 阅读更多 →

最新新闻

SOEM与Qt实现EtherCAT软主站:从交叉编译到嵌入式部署实战

SOEM与Qt实现EtherCAT软主站:从交叉编译到嵌入式部署实战

QT和SOEM这套组合,说实话在工业自动化圈子里不算新鲜,但真正把这套东西从源码编译一路玩到嵌入式板子上、还要配上Qt界面做成人机交互的,网上能一篇讲透的教程并不多见。我最早接触SOEM是因为一个产线改造项目——要用EtherCAT总线带动8个伺服…

2026/10/3 14:18:46 阅读更多 →
HFSS提取最大E/H场强与频率曲线:从原理到实操的完整指南

HFSS提取最大E/H场强与频率曲线:从原理到实操的完整指南

搞射频和微波设计的同行应该都有过这种经历:仿真一个滤波器、天线或者波导结构,性能指标都调得差不多了,然后突然要回答一个问题——这玩意儿在通带里某个频点,最大场强到底到多少了?如果是做大功率器件,通…

2026/10/3 14:18:46 阅读更多 →
2026抗DDoS技术三大核心方向:边缘清洗、AI识别与业务防护闭环

2026抗DDoS技术三大核心方向:边缘清洗、AI识别与业务防护闭环

2026抗DDoS技术发展三大核心方向聊到抗DDoS这个话题,我发现每次和同行交流,大家的焦虑点其实高度一致:峰值流量年年往上涨,攻击手法月月在翻新,而预算和团队精力始终是有限的。前几年我们讨论的是“被打了怎么办”&…

2026/10/3 14:18:46 阅读更多 →
QT集成SOEM实现EtherCAT主站:从编译到运动控制实战

QT集成SOEM实现EtherCAT主站:从编译到运动控制实战

1. 为什么是QT加SOEM:一个老牌主站库的二次生命力 做嵌入式上位机开发这些年,我踩过不少协议栈的坑,最后在EtherCAT主站这个方向上,SOEM(Simple Open EtherCAT Master)是我目前最推荐用来搭配QT做上位机的一…

2026/10/3 14:18:46 阅读更多 →
zenity实战指南:给Linux shell脚本添加图形对话框

zenity实战指南:给Linux shell脚本添加图形对话框

写过 Linux 运维脚本的朋友应该都遇到过这种尴尬:脚本跑得飞起,可一旦需要用户输入路径、确认操作、选个日期,就只能干巴巴地在终端里read -p "请输入...",用户输错一个字符就得重来;要是把脚本丢给不懂命令…

2026/10/3 14:18:46 阅读更多 →
sort排序函数底层原理与实用指南:从快排到TimSort

sort排序函数底层原理与实用指南:从快排到TimSort

1. 看起来简单的sort(),到底在干什么1.1 每个程序员都会用,但未必真懂Sort()绝对是所有编程语言里“最熟悉的陌生人”。你从学编程第一节课写冒泡排序开始,到工作后用一行std::sort(arr.begin(), arr.end())或者Arrays.sort(arr)搞定一切&…

2026/10/3 14:17:45 阅读更多 →

日新闻

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南 【免费下载链接】ex-skill 前任 skill 项目地址: https://gitcode.com/gh_mirrors/exsk/ex-skill 前任.skill 是一个运行在 Claude Code 上的开源 Skill:导入微信、iMessage、短信、…

2026/10/3 0:00:27 阅读更多 →
45个经典Linux面试题:从命令到网络排障的完整考点解析

45个经典Linux面试题:从命令到网络排障的完整考点解析

刚开始带应届生的时候,我最头疼的就是他们拿着一摞Linux面试题背得滚瓜烂熟,一上机全露馅。后来自己从被面的人变成面别人的人,才慢慢摸清楚:Linux面试题考的根本不是答案本身,而是你面对一个不确定的系统问题时&#…

2026/10/3 0:01:28 阅读更多 →
SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

简介:本资源是一份面向SAP ABAP开发人员、生产计划专员及ERP实施顾问的实操型操作指南,聚焦SAP生产预留核心业务场景,系统解决物料预留创建、查询、校验与批量处理等高频问题。文档以结构化方式覆盖预留背景原理、OMC2编码规则、工厂级参数配…

2026/10/3 0:01:28 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/3 9:14:33 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/3 9:47:50 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/3 9:42:31 阅读更多 →

月新闻

我发现了一个新思路:用 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/2 10:36:31 阅读更多 →
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/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练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/3 9:42:36 阅读更多 →