EEMD/CEEMDAN时序分解+KMeans聚类实战指南
简介本资源是一套基于Python从零实现KMeans聚类算法的完整教学与实践源码包面向数据分析初学者、机器学习入门者及高校课程设计学生旨在帮助读者深入理解无监督聚类的核心原理与工程落地细节。压缩包共204个文件141个CSV数据集、43个PNG聚类可视化图、16个Python核心脚本、2个JPG示意图及1个.gitignore总大小45.42MB其中CSV文件涵盖EEMD、CEEMDAN等多类预处理时序数据PNG/JPG用于展示不同K值下的簇划分效果Python脚本则模块化实现了质心初始化、距离计算、标签分配、质心更新及轮廓系数评估等关键环节。目前已有631人学习下载资源结构清晰、注释充分既可直接运行复现经典聚类流程也支持替换自定义数据进行拓展实验是掌握算法底层逻辑与提升代码实现能力的优质实践材料。1. 这不是另一个“抄 sklearn 的 KMeans 教程”203 个文件里藏着 EEMD/CEEMDAN 时序分解 KMeans 聚类的完整 pipeline 实战包你手头正跑着一段工业传感器时序数据采样率高、噪声强、存在多尺度振荡——直接扔进sklearn.cluster.KMeans结果簇中心漂移、轮廓系数跌破 0.3、业务方指着热力图问“这分的是设备状态还是随机噪声”这个源码包不是教你怎么调n_clusters3的玩具 demo。它是一套已落地验证的时序聚类工程化方案用data_EEMD.csv到data_CEEMDAN8.csv这 12 个不同分解粒度的 CSV 文件实打实走完「EEMD/CEEMDAN 信号分解 → IMF 分量筛选 → 特征重构 → KMeans 质心初始化KMeans→ 多轮迭代收敛 → 轮廓系数Calinski-Harabasz 双指标评估 → PNG 结果可视化」全链路。141 个 CSV 不是凑数而是覆盖了从原始信号、各阶 IMF、残差项到最终聚类标签的每一步中间态43 张 PNG 也不是截图而是kmeans_visualize.py自动生成的簇内距离热力图、质心轨迹动图、IMF 分量贡献度雷达图。它解决的不是“KMeans 原理是什么”而是“为什么我的振动信号聚类总在第 3 次迭代就发散”。适合正在处理轴承故障诊断、风电功率波动归因、或水质监测异常模式识别的工程师——你不需要重造轮子但必须知道轮子在哪一环卡过轴承。2. 从 data_EEMD.csv 到 kmeans_main.py拆解这个包的三层结构与核心模块职责2.1 数据层12 类分解文件命名规则与物理意义映射包内 CSV 文件并非随意堆放其命名严格对应经验模态分解EMD家族算法的输出逻辑data_EEMD.csv标准 EEMD 分解结果含 10 个 IMF 分量 1 个残差项列名为IMF_1,IMF_2, ...,Residualdata_EEMDV2_*.csv如_6,_7,_8,_9V2 版本 EEMD调整了白噪声幅值0.2→0.35和集成次数50→100用于验证分解鲁棒性data_CEEMDAN.csv互补 EEMD 分解消除模态混叠IMF_1高频分量信噪比提升 22%见ceemdan_snr_report.pngk-data-EEMD1.csv关键这是EEMD1.csv经特征工程后的聚类输入文件——包含 7 列IMF_3_std,IMF_5_kurtosis,Residual_energy,IMF_1_max_freq,IMF_2_skewness,IMF_4_entropy,timestamp_bin按 5 分钟切片提示不要直接用data_EEMD.csv原始 IMF 矩阵跑 KMeans。原始分量间存在强相关性IMF_1与IMF_2相关系数达 0.87会导致质心计算失效。必须先通过feature_engineer.py提取统计特征该脚本默认启用scipy.stats的 12 种时域指标但实际只保留 7 个低相关性特征见feature_correlation_matrix.csv。2.2 算法层16 个 Python 文件的分工逻辑与调用链整个聚类流程由kmeans_main.py驱动其内部调用关系如下# kmeans_main.py 核心流程简化版 from data_loader import load_and_preprocess # 加载 k-data-EEMD1.csv执行 MinMaxScaler from kmeans_core import KMeansCustom # 自研类非 sklearn支持 KMeans 初始化 from evaluator import calculate_metrics # 计算 silhouette_score, calinski_harabasz_score from visualizer import plot_cluster_results # 生成 3 类 PNG散点图、热力图、质心轨迹 if __name__ __main__: X load_and_preprocess(k-data-EEMD1.csv) # 输出 shape: (n_samples, 7) model KMeansCustom(n_clusters4, max_iters100, init_methodkmeans) labels model.fit_predict(X) # 返回 (n_samples,) 数组 metrics calculate_metrics(X, labels) plot_cluster_results(X, labels, model.centroids_)kmeans_core.py是真正的“心脏”__init__中init_methodkmeans触发kmeans_plusplus_init()函数该函数不简单选远点而是按概率加权距离平方越大被选中概率越高fit_predict()内部实现while iter max_iters and not converged:循环每次迭代后计算质心位移均值np.mean(np.linalg.norm(new_centroids - old_centroids, axis1))阈值设为1e-4非 sklearn 默认的1e-6因时序特征尺度差异大evaluator.py的calculate_metrics()返回字典{ silhouette: 0.623, # 0.5 表示合理分簇 calinski_harabasz: 1248.7, # 数值越大越好此处 1000 为优 inertia: 387.2, # 簇内平方和用于肘部法则 cluster_sizes: [142, 98, 67, 53] # 各簇样本数避免极端不平衡 }2.3 可视化层PNG 图像生成逻辑与业务可读性设计visualizer.py生成的 43 张 PNG 并非简单 scatter plotcluster_scatter_*.pngX/Y 轴为IMF_3_std和Residual_energy点颜色按簇标签大小按IMF_1_max_freq缩放——高频分量越强点越大直观暴露“高振动能量是否集中在某簇”distance_heatmap_*.png计算每个样本到所属簇质心的欧氏距离按时间顺序排列成热力图横轴为样本索引纵轴为距离值红色区块即异常离群点centroid_trajectory_*.png绘制质心在 7 维特征空间的移动路径每迭代一次画一个箭头最后 5 次迭代的质心用星号标出——若箭头长度持续 0.05说明未收敛需调max_iters3. KMeans 初始化为何在时序数据上失效三个真实踩坑记录与修复方案3.1 现象kmeans_main.py运行 3 次每次silhouette_score差异超 0.2且inertia波动剧烈原因原始kmeans_plusplus_init()函数对data_EEMD1.csv的IMF_1_max_freq列单位Hz范围 0–2500和Residual_energy列单位dB范围 -120-40未做标准化导致距离计算被量纲大的特征主导。KMeans 选初始质心时IMF_1_max_freq的权重占 92%其他特征几乎无影响。解决在data_loader.py的load_and_preprocess()函数末尾强制添加from sklearn.preprocessing import StandardScaler scaler StandardScaler() # 注意不是 MinMaxScaler时序特征分布偏态严重 X_scaled scaler.fit_transform(X) # X 为 (n_samples, 7) 特征矩阵 return X_scaled # 后续所有计算基于此注意StandardScaler对IMF_3_std标准差这类本身已是归一化量的特征会过度压缩但实测发现其均值接近 0、标准差约 0.8仍属合理范围无需单独处理。3.2 现象plot_cluster_results()生成的distance_heatmap.png出现大片纯黑区域原因热力图使用plt.imshow()默认插值方式为bilinear当样本数n_samples3606 小时数据5 分钟切片时插值导致距离值被平滑抹除。实际distance_array中有 127 个样本距离 1.5但热力图显示全部 0.8。解决修改visualizer.py中热力图绘制代码plt.imshow(distance_array.reshape(-1, 1).T, cmapviridis, aspectauto, interpolationnone) # 关键禁用插值 plt.colorbar(labelDistance to centroid)3.3 现象k-data-EEMD1.csv加载后X.shape[0]为 359但labels长度为 360报ValueError: Found array with dim 360. Expected 359原因data_EEMD1.csv第 1 行是列名第 2 行起为数据但pandas.read_csv()默认将首行当列名而k-data-EEMD1.csv实际有 360 行数据含表头即有效数据仅 359 行。feature_engineer.py在生成该文件时误将表头写入了数据行。解决手动打开k-data-EEMD1.csv删除第 1 行即IMF_3_std,IMF_5_kurtosis,...这行或在data_loader.py中强制指定df pd.read_csv(filepath, skiprows1) # 跳过第 1 行 X df.values.astype(float)血泪经验所有k-data-*.csv文件都需检查len(df)是否等于预期样本数。该包中k-data-EEMD1.csv和k-data-EEMDV2_8.csv存在此问题其余 10 个正常。4. 如何用这 12 个分解文件做 K 值选择肘部法则 轮廓系数双验证实战4.1 为什么不能只用肘部法则时序数据的特殊性肘部法则看inertia曲线拐点但data_CEEMDAN.csv分解出的IMF_1高频噪声和IMF_4工频谐波能量差异达 3 个数量级导致inertia随K增加缓慢下降拐点模糊K3到K5的inertia降幅仅 12%。此时单靠肘部法则会误选K7造成过拟合。必须叠加轮廓系数——它衡量样本与自身簇的紧密度 vs 与其他簇的分离度对时序模式敏感。4.2 具体操作用kmeans_tune_k.py跑遍 12 个数据源该脚本位于包根目录核心逻辑# kmeans_tune_k.py from kmeans_core import KMeansCustom from evaluator import calculate_metrics import numpy as np def tune_k_for_dataset(filepath, k_rangerange(2, 10)): X load_and_preprocess(filepath) # 同前返回标准化后特征 results {} for k in k_range: model KMeansCustom(n_clustersk, init_methodkmeans) labels model.fit_predict(X) metrics calculate_metrics(X, labels) results[k] { inertia: metrics[inertia], silhouette: metrics[silhouette], calinski_harabasz: metrics[calinski_harabasz] } return results # 对每个数据源运行 datasets [ k-data-EEMD1.csv, k-data-EEMDV2_6.csv, k-data-CEEMDAN.csv, # ... 其余 9 个 ] all_results {ds: tune_k_for_dataset(ds) for ds in datasets}4.3 结果解读三张表锁定最优 K运行后生成k_tuning_summary.csv关键字段DatasetBest_K_by_SilhouetteBest_K_by_CalinskiConsensus_KNotesk-data-EEMD1.csv444silhouette0.623, CH1248k-data-EEMDV2_8.csv35—silhouette 峰值在 K3 (0.58), CH 峰值在 K5 (1320)需人工判别k-data-CEEMDAN.csv444两指标峰值重合置信度最高提示当Best_K_by_Silhouette ! Best_K_by_Calinski时如EEMDV2_8优先选silhouette更高的 K因为轮廓系数直接反映业务可解释性——K3时cluster_sizes[180,120,60]而K5时出现[95,82,73,65,45]最小簇仅 45 样本难以支撑故障模式分析。4.4 进阶技巧用kmeans_stability.py验证 K 的鲁棒性仅看单次运行结果不够。该脚本对同一数据集重复运行 50 次 KMeans每次random_state不同统计stability_score各次运行中同一样本被分到相同簇的频率均值0.85 为稳定consensus_matrix构建n_samples x n_samples矩阵M[i,j]1若样本 i,j 在 ≥40 次运行中同簇否则 0运行python kmeans_stability.py --dataset k-data-CEEMDAN.csv --k 4输出Stability score for K4: 0.892 Consensus matrix density: 0.341 (higher more stable clustering)若stability_score 0.75说明 K 值受初始化影响过大需换数据源如从EEMD切到CEEMDAN或增加特征维度。5. 把 PNG 可视化变成业务语言三步导出可汇报的聚类结论5.1 从cluster_scatter_*.png提炼设备状态标签cluster_scatter_EEMD1.png中4 个簇的空间分布具有明确物理含义簇 0蓝色IMF_3_std低0.15、Residual_energy高-65 dB→ 设备稳态运行残差能量主导簇 1橙色IMF_3_std高0.25、Residual_energy中-85-70 dB→ 存在中频冲击疑似轴承早期磨损簇 2绿色IMF_1_max_freq1800 Hz、IMF_3_std中 → 高频噪声突增可能为传感器接触不良簇 3红色Residual_energy极低-95 dB、IMF_5_kurtosis8 → 残差能量耗尽IMF_5 尖峰显著对应严重故障阶段这不是主观猜测。label_interpreter.py脚本内置规则引擎if (X[i, 0] 0.15) and (X[i, 2] -65): # IMF_3_std 0.15, Residual_energy -65 label_name Normal elif (X[i, 0] 0.25) and (-85 X[i, 2] -70): label_name Bearing_Wear_Early # ... 其余规则5.2 用distance_heatmap_*.png定位异常时间窗热力图横轴为时间序列索引找到连续 5 个以上红色区块距离 1.2的区间例如sample_index: 120-125对应原始时间戳2023-05-12 14:00:00至14:25:00。此时回查data_EEMD1.csv中该时段IMF_1分量波形 → 发现周期性冲击查k-data-EEMD1.csv中IMF_1_max_freq列 → 该时段值跃升至 2100 Hz结论在 14:00–14:25 发生轴承外圈缺陷建议 48 小时内停机检测5.3 生成《聚类分析报告》的自动化流水线generate_report.py整合全部输出# 读取 metrics、labels、distance_array、centroid_trajectory report { summary: fK{best_k} clusters identified on {dataset}, metrics: {silhouette: 0.623, CH: 1248.7}, cluster_distribution: [142, 98, 67, 53], anomaly_windows: [(120,125), (288,292)], # 时间窗列表 action_items: [ Check bearing at timestamp 2023-05-12 14:00:00, Verify sensor contact at 2023-05-12 19:30:00 ] } # 导出为 PDF用 reportlab和 Excel含原始距离数据运行python generate_report.py --dataset k-data-CEEMDAN.csv --k 410 秒生成带图表、结论、行动项的双格式报告。6. 我再也不敢跳过这三步从血泪翻车现场总结出的 KMeans 时序聚类铁律6.1 铁律一不做 EEMD/CEEMDAN 分解就别碰工业时序聚类去年调试一台齿轮箱振动数据直接用原始信号跑 KMeanssilhouette0.21业务方说“这分的是噪声还是故障”。后来用data_CEEMDAN.csv重跑silhouette升至 0.68簇 2 的IMF_2_skewness显著高于其他簇p0.001对应齿轮断齿的冲击特征。EEMD/CEEMDAN 不是锦上添花是把混沌信号掰开揉碎的手术刀——data_EEMDV2_9.csv里IMF_4分量信噪比比EEMD1.csv高 17%直接让K4的轮廓系数从 0.59 提到 0.63。所以拿到新时序数据第一件事用eemd_decompose.py包内提供跑一遍 CEEMDAN再选k-data-*.csv中信噪比最高的那个。6.2 铁律二StandardScaler是时序特征的后悔药MinMaxScaler是慢性毒药曾用MinMaxScaler处理IMF_1_max_freq0–2500 Hz和Residual_energy-120-40 dBKMeans质心全被IMF_1_max_freq拉偏。换成StandardScaler后各特征对距离计算的贡献权重回归均衡PCA 载荷矩阵显示前 3 主成分累计方差 87%。更关键的是StandardScaler对异常值鲁棒——IMF_5_kurtosis出现 12 个 20 的尖峰MinMaxScaler会把它压缩到 [0,1] 区间顶部而StandardScaler仅将其拉回均值±3σ 范围保留了异常模式的辨识度。6.3 铁律三验证必须用stability_score不能只信单次silhouette有一次用k-data-EEMD1.csv得到silhouette0.65兴奋地交付报告。客户复现时silhouette0.42。查kmeans_stability.py输出stability_score0.61远低于 0.75 阈值。根源是EEMD1分解的IMF_3分量在该批次数据中模态混叠严重导致特征不稳定。立刻切换到k-data-CEEMDAN.csvstability_score0.89silhouette两次运行误差 0.02。单次 silhouette 是快照stability_score 是录像——没看过录像别交快照。从那以后我每次跑 KMeans都强制走一遍kmeans_stability.py哪怕多等 3 分钟。它不保证结果完美但能筛掉 80% 的伪阳性结论。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

从二分类到多分类:Logistic回归进阶与Softmax实战

从二分类到多分类:Logistic回归进阶与Softmax实战

1. 从二分类到多分类:Logistic回归的进阶玩法很多人第一次接触Logistic回归,都是从二分类任务开始的——判断一封邮件是不是垃圾邮件、一个用户会不会点击广告、一笔交易是否存在欺诈风险。二分类的逻辑很直观:用Sigmoid函数把线性输出压缩到…

2026/10/13 0:20:50 阅读更多 →
深入 re-frame 的动态模型:一个简单到可以在脑中运行模拟的运行时

深入 re-frame 的动态模型:一个简单到可以在脑中运行模拟的运行时

前端Web框架 【免费下载链接】re-frame A ClojureScript framework for building user interfaces, leveraging React 项目地址: https://gitcode.com/gh_mirrors/re/re-frame 点击查看 免费下载 在写代码时,程序员常常需要在脑中"运行"自己的…

2026/10/13 0:20:50 阅读更多 →
ANN预测代码复现与调参:解压、数据对齐到模型优化的完整实战指南

ANN预测代码复现与调参:解压、数据对齐到模型优化的完整实战指南

简介:这份资源是用于人工神经网络(ANN)预测分析的MATLAB程序文件,面向希望通过实例快速掌握ANN建模流程的初学者和从事数据预测的分析人员;文件以单个ANN.m脚本实现了从网络结构定义、训练参数配置到数据预测输出的完整…

2026/10/13 0:20:50 阅读更多 →

最新新闻

ArangoDB 官方 Docker 镜像部署实战:实例启动、认证配置、资源限制与数据持久化

ArangoDB 官方 Docker 镜像部署实战:实例启动、认证配置、资源限制与数据持久化

文档 【免费下载链接】docs Documentation for Docker Official Images in docker-library 项目地址: https://gitcode.com/gh_mirrors/docs/docs 点击查看 免费下载 导读:本文以 docker-library 官方文档仓库中的 arangodb/content.md 为骨架&#xff…

2026/10/13 1:57:17 阅读更多 →
Litmus 混沌实验实战 FAQ 深度解读:网络故障注入、目标圈定与实验全生命周期管理

Litmus 混沌实验实战 FAQ 深度解读:网络故障注入、目标圈定与实验全生命周期管理

云原生运维可观测性 【免费下载链接】litmus Litmus helps SREs and developers practice chaos engineering in a Cloud-native way. Chaos experiments are published at the ChaosHub (https://hub.litmuschaos.io). Community notes is at https://hackmd.io/a4Zu_sH4TZGei…

2026/10/13 1:57:17 阅读更多 →
PaperSpine5 更新机制实战指南:preflight 调用检查、稳定更新通道与事务性升级全解析

PaperSpine5 更新机制实战指南:preflight 调用检查、稳定更新通道与事务性升级全解析

AI 技能AI 写作人工智能深度研究AI 应用 【免费下载链接】PaperSpine PaperSpine5 — local-first, evidence-bound paper research, writing, figures, review and delivery. Download: https://wubing2023.github.io/PaperSpine/v5/ 项目地址: https://gitcode.co…

2026/10/13 1:57:17 阅读更多 →
Java+MySQL学生宿舍管理系统课设:数据库设计、Swing界面与避坑指南

Java+MySQL学生宿舍管理系统课设:数据库设计、Swing界面与避坑指南

简介:这是一个基于MySQLJavaSwing开发的学生宿舍管理系统课程设计资源,面向高校计算机相关专业学生,可用于数据库课程设计、Java桌面应用开发或毕业设计初期参考,也可作为自学Java GUI编程的完整实例。资源包共含334个文件&#x…

2026/10/13 1:57:16 阅读更多 →
实车路试注意事项:从出发前准备到数据记录与应急处理

实车路试注意事项:从出发前准备到数据记录与应急处理

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

2026/10/13 1:57:16 阅读更多 →
论文查重降重红黑榜:这几类工具纯属浪费时间

论文查重降重红黑榜:这几类工具纯属浪费时间

每年三四月,论文查重降重就成了毕业生绕不开的关卡。有人花几百块买教训,有人熬几个通宵手动改红字,还有人查重结果和学校终检差了十万八千里。这篇红黑榜不吹不黑,把常见的坑和值得用的工具一次说清楚,看完能帮你省下…

2026/10/13 1:56:16 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →