不用Django,把机器学习预测结果展示到HTML页面的三种方案
最近我遇到一个挺常见的需求机器学习模型跑完预测结果还躺在 notebook 里可客户那边只想打开一个网页就能看到实时预测效果。我第一反应是上 Django但项目本身不大真不想为了一个展示页搭一套全家桶。于是问题就来了怎么把预测模型的数据显示到 HTML 页面上并且不使用 Django。这篇文章我打算把实际项目里最常用的几种路线都讲一遍包括 Flask 轻量接口、FastAPI 替代方案、纯前端加载模型以及上线部署时一定会遇到的坑。你可以看作一份“从模型到网页”的实战笔记适合刚接触模型部署、或者后端基础不深但想快速做展示页的朋友。如果你已经会一点 HTML 和 Python那照着我下面的步骤一个小时左右就能跑通一个自己的预测页面。1. 先想清楚模型数据到网页前要过哪几关1.1 模型输出不等于页面数据先别急着写代码。我做过的项目里大部分卡住的人都是把“模型输出”和“页面展示”混在一起了。模型训练完得到的东西可能是张量、DataFrame、数组也可能只是一个分类标签。这些数据活在 Python 进程里浏览器根本看不见。要让 HTML 页面显示它至少要做三件事把预测结果从模型环境里拿出来序列化成浏览器能识别的格式通常是 JSON通过某种网络交互方式传递到前端HTTP 接口是最常见的办法前端拿到数据之后用 JavaScript 动态更新页面上的文本、表格或图表。这三个环节只要断了一个页面要么白屏要么一直转圈。很多朋友问我“为什么接口返回正常页面还是空的”十有八九是前端渲染那一步写错了而不是后端接口的问题。1.2 三种典型的数据流模式从实际需求来看预测结果上网页大概率逃不开下面三种模式后端预测型用户在前端输入参数后端接收后调用模型计算完再返回结果。适合模型体积大、业务逻辑复杂、或者参数和结果不想被用户直接看到的情况。前端预测型模型文件被打包成浏览器能加载的格式直接在浏览器本地推理。适合模型比较小、实时性要求高、不想占用服务器资源的场景。结果展示型模型提前算好一批预测结果存成 JSON、CSV 或数据库表前端只需要拉取并展示。很多团队内部的“销量预测看板”“风险预警面板”都属于这一类。你的需求属于哪一种直接决定了选型。我遇到过很多人说“非 Django 怎么显示”聊到最后发现需求只是第二种或第三种根本不需要起后端服务用一个静态页面就搞定了。1.3 非 Django 框架意味着什么不选择 Django 不代表不用后端。我对这个问题的理解是Django 太重配置数据库、admin 后台、中间件对一个展示页来说全是负担。非 Django 的世界里轻量方案指的是这几条路线Flask最经典几行代码起一个接口生态成熟新手学习成本低。FastAPI异步支持好自带接口文档用 Pydantic 做数据校验代码量更少。纯前端完全解耦用 TensorFlow.js 在浏览器跑模型或者直接读取预计算结果文件。选哪个不完全是技术偏好问题而是看你的页面交互复杂度、模型体积、部署环境。下面三种方案我都会带着代码走一遍你照着做就能通。2. 方案一Flask Fetch HTML新手最容易上手的组合2.1 环境准备与最小目录结构如果你只是想快速把模型预测结果显示到网页上Flask 是我最推荐的第一选择。先装依赖pip install flask pandas joblibpandas 和 joblib 不一定都用得上但做数据相关展示页通常跑不掉先装好省事。项目目录我建议这样组织predict_demo/ ├── app.py ├── templates/ │ └── index.html └── static/ └── style.cssFlask 默认会去templates目录找模板静态资源放static。就算你只是做单页展示保持这个结构也有好处后面加图片、样式、JS 文件时不会乱。如果以后还想加其他页面直接往 templates 里丢 HTML 就行。2.2 加载模型并编写预测接口核心逻辑只有一个模型全局加载一次然后用一个路由接收参数返回 JSON。下面是我实测过的一段代码假设你有一个用 joblib 保存的模型文件model.pkl输入特征是x1、x2两个数值from flask import Flask, jsonify, request, render_template import joblib import numpy as np app Flask(__name__) model joblib.load(model.pkl) app.route(/) def index(): return render_template(index.html) app.route(/predict, methods[POST]) def predict(): data request.get_json() x1 float(data[x1]) x2 float(data[x2]) features np.array([[x1, x2]]) result model.predict(features)[0] return jsonify({prediction: float(result)}) if __name__ __main__: app.run(debugTrue, port5000)这里有三个细节要注意。第一模型加载一定放在路由外面。你不想每请求一次就读一次文件一个展示页可能同时被多人打开那样模型会重复读服务越来越慢。第二request.get_json()需要前端在请求头里带上Content-Type: application/json否则 Flask 拿不到 body 里的参数。这种“接口通了但参数为空”的报错最容易让人迷惑。第三预测结果如果直接丢给jsonify很可能会报类型错误。NumPy 的float32、ndarray都不能直接 JSON 序列化所以我通常用float()包一下或者调用tolist()转成列表。2.3 写一个能用的 HTML 页面与 fetch 联动templates/index.html里放输入框、按钮和结果区。先写一个最简版本!DOCTYPE html html langzh-CN head meta charsetUTF-8 title模型预测展示/title /head body h1线性回归预测/h1 div labelx1/label input typetext idx1 labelx2/label input typetext idx2 button onclickdoPredict()预测/button /div p预测结果span idresult--/span/p script async function doPredict() { const x1 document.getElementById(x1).value; const x2 document.getElementById(x2).value; const response await fetch(/predict, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({x1: x1, x2: x2}) }); const data await response.json(); document.getElementById(result).textContent data.prediction.toFixed(4); } /script /body /html这里用的是浏览器原生fetch没必要为了一个小页面再去引 axios。await response.json()会把后端返回的 JSON 转成 JavaScript 对象然后直接操作 DOM。我在使用中强烈建议给按钮加一个禁用状态防止用户连续点击导致重复请求btn.disabled true; btn.textContent 预测中...;预测结果回来后恢复按钮这样体验会好很多。2.4 把预测结果渲染成表格或图表如果预测结果不是一个数而是一组值比如未来七天的销量那渲染逻辑就不一样了。我的做法是后端返回一个包含数组的对象前端通过循环拼表格或者交给图表库画线。后端接口节选forecast model.forecast(steps7) result {date: [], sales: []} for i, d in enumerate(pd.date_range(startpd.Timestamp.now().date(), periods7)): result[date].append(str(d.date())) result[sales].append(float(forecast[i])) return jsonify(result)前端渲染成表格const data await response.json(); const table document.createElement(table); const thead table.insertRow(); thead.innerHTML th日期/thth预测值/th; for (let i 0; i data.date.length; i) { const tr table.insertRow(); tr.innerHTML td${data.date[i]}/tdtd${data.sales[i].toFixed(2)}/td; } document.getElementById(chart-area).appendChild(table);如果想画折线图用 Chart.js 最省心引入 CDN 后把数据填进配置项canvas idchart width400 height200/canvas script srchttps://cdn.jsdelivr.net/npm/chart.js/script script new Chart(document.getElementById(chart), { type: line, data: { labels: data.date, datasets: [{ label: 销量预测, data: data.sales }] } }); /script图表能直观展示趋势很适合预测类结果。我建议不要自己去画坐标轴直接用库节省时间也避免一堆边界问题。2.5 跨域与请求状态两个常见的坑开发环境里 Flask 默认只允许同源访问。如果你的前端页面和后端不在同一个端口比如前端用 webpack-dev-server 跑在 8080后端跑在 5000浏览器就会报跨域错误。解决方案是装flask-corspip install flask-cors然后在app.py里加一行from flask_cors import CORS CORS(app)这会把所有接口的跨域限制放开开发阶段够用了。正式部署时我会在反向代理层面处理而不是全开 CORS。另一个坑是模型预测耗时较长前端 Fetch 默认没有超时时间用户可能等得没耐心。我通常会在后端加缓存或者在前端显示请求状态。最简单的加载提示已经写在上面了别小看这一行实际体验提升很大。3. 方案二FastAPI 静态页面更现代也更省心3.1 FastAPI 为什么适合这个场景FastAPI 这些年越来越受欢迎它最大的好处是自动生成/docs接口文档。你写完接口后打开http://127.0.0.1:8000/docs页面上会列出所有接口、参数、响应格式还能直接点击调用测试。对于模型展示这种需要反复调参的场景尤其方便。Flask 就没有这个调试接口时还得靠 Postman 或者 curl。安装命令pip install fastapi uvicorn然后启动服务用uvicorn app:app --reload --port 8000--reload是开发模式代码改动自动重载写接口的时候很方便。3.2 接口代码与数据校验FastAPI 配上 Pydantic 之后参数校验几乎零成本。还是同一个模型我写的接口是这样from fastapi import FastAPI from fastapi.responses import JSONResponse, FileResponse from pydantic import BaseModel import joblib import numpy as np app FastAPI() model joblib.load(model.pkl) class PredictPayload(BaseModel): x1: float x2: float app.post(/predict) async def predict(payload: PredictPayload): features np.array([[payload.x1, payload.x2]]) result model.predict(features)[0] return {prediction: float(result)} app.get(/) async def index(): return FileResponse(static/index.html)注意这里定义了一个PredictPayload数据模型前端传 JSON 过来后FastAPI 会自动做类型转换。如果传了无法转成 float 的值接口直接返回 422 和字段错误信息不需要自己写校验代码。页面方面我用FileResponse直接返回 HTML 文件而不是模板渲染。原因是展示页不需要 Python 端注入变量前端自己请求接口拿数据职责更清晰。3.3 前端适配与请求地址管理前端代码和 Flask 方案几乎一样。不同点在于 FastAPI 默认端口是 8000如果你的页面不是和接口同源fetch 里就要写完整地址const response await fetch(http://127.0.0.1:8000/predict, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({ x1: 3.5, x2: 2.0 }) }); const data await response.json();我习惯把接口地址抽成一个常量const API_BASE http://127.0.0.1:8000;这样以后换了域名或加了前缀只改这一处就可以。3.4 同步与异步的注意点FastAPI 里写async def是异步函数但模型预测通常是 CPU 推理属于同步阻塞操作。如果你在async def里直接调用一个很慢的预测函数可能会阻塞事件循环。我的经验是这类接口直接用def声明普通函数反而更合适FastAPI 会把它丢到线程池处理不会卡住其他请求。比如声明成app.post(/predict) def predict(payload: PredictPayload): ...效果和async def比差异不大但代码更直白新手也不容易踩坑。以后并发量上去了再考虑换异步进程或者拆分模型服务。4. 方案三纯前端加载模型或直接使用预计算结果4.1 什么时候可以放弃后端我见过不少展示项目其实可以不起后端服务。比如模型是一个简单的 scikit-learn 二分类器文件只有几十 KB或者模型已经跑完预测结果已经存进 CSV、JSON 文件。这种情况下纯前端完全够用。但有一点要提醒浏览器出于安全限制不能直接通过fetch读取本地磁盘文件。如果你想双击 HTML 文件直接看大概率会失败。纯前端方案需要页面通过一个本地服务器打开比如在项目根目录执行python -m http.server 8080或者把页面部署到任意静态托管平台。只要 URL 是 http 或 https 协议fetch 就能正常工作。4.2 用 TensorFlow.js 在浏览器里跑推理如果你的模型是 TensorFlow 格式可以用tensorflowjs_converter转成浏览器能加载的tfjs格式pip install tensorflowjs tensorflowjs_converter --input_formattf_saved_model \ ./saved_model ./tfjs_model前端加载模型的代码很简单script srchttps://cdn.jsdelivr.net/npm/tensorflow/tfjslatest/script script let model null; async function loadModel() { model await tf.loadGraphModel(./tfjs_model/model.json); } function runInference() { const input tf.tensor2d([[x1, x2]]); const output model.predict(input); output.data().then(values { document.getElementById(result).textContent values[0]; }); } /script这个方案最大的优点是省掉后端服务器部署成本低。但模型如果超过几百 KB页面加载就会明显变慢。而且模型在浏览器里跑推理结果的逻辑完全暴露在前端不适合有保密需求的项目。4.3 用预计算结果做只读看板我的很多现实需求其实是这一种模型只需要在后台跑一次然后把预测结果存成result.json供前端展示。这样的 HTML 页面完全脱离 Python可以放进任意静态托管服务稳定又不容易挂。result.json示例[ {date: 2025-01-01, sales: 123.5}, {date: 2025-01-02, sales: 130.2}, {date: 2025-01-03, sales: 119.8} ]前端读取const response await fetch(./result.json); const rows await response.json();再配合 Chart.js 或者 ECharts 画图一个“预测看板”就完成了。这种做法我特别推荐做团队内部展示风险低、可维护性强只需要一个定时任务更新 JSON 文件即可。5. 高频问题排查与避坑指南5.1 接口返回 404路由匹配问题页面请求接口报 404 是我遇到最多的问题。常见原因有两种一是 Flask 路由装饰器写的是/predict前端请求的是/predic少了一个 t二是 FastAPI 配置了/api前缀前端请求地址没加。排查方法很简单直接用浏览器地址栏访问接口地址如果是 GET 请求会看到返回值如果是 POST 请求用 curl 模拟一次curl -X POST http://127.0.0.1:5000/predict \ -H Content-Type: application/json \ -d {x1: 1.0, x2: 2.0}先确认接口本身通了再回头检查前端路径别一上来就怀疑跨域。5.2 JSON 序列化失败数据类型的坑预测结果经常是 NumPy 的ndarray、float32、pd.DataFrame。这些都不能直接被 flask 的jsonify或 FastAPI 的 JSONResponse 序列化。我统一处理的方式是转成 Python 原生类型if hasattr(result, tolist): result result.tolist()tolist()会把 NumPy 数组转成嵌套列表。如果结果是标量就直接用float()或int()包一下。这样 JSON 化就完全没问题。5.3 模型加载慢、内存占用高模型文件很大时每次启动服务都会占用大量内存。我发现很多人的误区是不断重启服务导致模型反复加载最终把服务器搞得很卡。解决办法有几个使用懒加载第一次请求时才加载模型避免启动即占用资源把模型放到一个独立进程中和 Web 服务解耦如果只是展示固定预测结果干脆预计算好不要每次都重新跑模型。5.4 浏览器缓存导致页面数据旧页面改过了但浏览器还显示旧数据。这个很常见尤其是 HTML 和 JS 文件更新频繁的时候。我习惯在静态文件的 URL 后面加版本号script src/static/app.js?v20250118/script如果是 fetch 请求可以加时间戳强制刷新const response await fetch(/predict?t${Date.now()});开发阶段这招非常好用避免你改完代码还要手动清缓存。5.5 跨域CORS终极排查方法跨域报错时浏览器 Console 会出现类似blocked by CORS policy的提示。解决思路按优先级排序开发阶段后端开启 CORSFlask 用flask_corsFastAPI 用CORSMiddleware正式部署用 Nginx 反向代理让前端页面和后端接口同域比如/api/转发到后端端口临时调试可以通过浏览器插件暂时绕过跨域限制但只适合自己调试千万别做成“测试时能打开用户打开就白屏”的版本。6. 从项目里带走的几条实操心得6.1 先打通链路再考虑体验优化我的习惯是先用最笨的路径把“模型 - 接口 - 页面”这条链路跑通再考虑图表漂不漂亮、按钮 loading 好不好看。很多时候你卡在一个细节上其实是链路没通怎么也看不出来是后端返回错了还是前端解析错了。先把“输入参数 - 看到预测结果”这个最小闭环做出来剩下的全是加分项。6.2 把结果落成文件比每次都跑模型更稳有一次我帮人做了个销量预测展示页一开始坚持每次请求都实时跑模型结果并发一高接口就变慢老板还嫌卡。后来我改成每天定时跑一次预测结果存成 JSON 文件前端直接读取页面打开速度从三秒降到了几十毫秒服务器也轻松了。对大部分“预测模型数据显示到页面”的需求来说实时预测的诉求其实没那么强展示端优先考虑稳定性更重要。最后再分享一个小习惯无论用哪种方案我都会在后端返回的 JSON 里加一个status字段比如{status: ok, data: {...}}。这样前端可以通过status区分是正常结果还是错误信息排查问题的时候能省掉一大半时间。预测模型展示这个场景本身不复杂但越是简单的事越要把数据流整清楚。

相关新闻

open-code-review:从人治到规则治的代码审查实践指南

open-code-review:从人治到规则治的代码审查实践指南

1. 为什么“open-code-review”值得单独拿出来聊第一次听到“open-code-review”这个词,很多人会下意识觉得它只是“代码审查”的又一个新包装。但真正在团队里推过代码审查的人都知道,这件事的难点从来不在“审查”两个字,而在于“open”——…

2026/10/19 13:08:32 阅读更多 →
代码评审工具化实践:从规则引擎到流程编排的轻量集成方案

代码评审工具化实践:从规则引擎到流程编排的轻量集成方案

1. 为什么"代码评审"这件事值得单独拿出来做一套工具但凡在研发团队里待过几年的人,都会对"代码评审"这件事又爱又恨。爱的是它确实能拦住不少低级错误,恨的是它经常变成走过场——要么是评审人扫两眼就点了通过,要么是作…

2026/10/19 13:08:32 阅读更多 →
SSM+Vue客房订餐系统毕业设计完整实现与论文写作指南

SSM+Vue客房订餐系统毕业设计完整实现与论文写作指南

每年到了毕设季,我都习惯先看一眼市面上都在做哪些题目。说实话,像“ssmvue客房订餐系统”这种组合,几乎是每年都会出现的经典选题,但真正能把论文和程序都做得扎实的同学,比例并不高。这篇文章就把这个项目的完整拆解…

2026/10/19 13:08:32 阅读更多 →

最新新闻

手写代码评审辅助工具:基于静态分析与代码块评分,实现机器扫雷人做判断

手写代码评审辅助工具:基于静态分析与代码块评分,实现机器扫雷人做判断

程序员之间最容易翻脸的地方,除了代码风格,就是代码评审。 公司项目组从去年开始严格执行 MR 评审制度,本意是守住质量底线,但真正执行起来,问题特别多。一个 400 行起步的 MR,评审人往往只来得及看两三个…

2026/10/19 13:51:40 阅读更多 →
从零配置Maven环境:避开JDK版本、settings.xml与依赖下载的坑

从零配置Maven环境:避开JDK版本、settings.xml与依赖下载的坑

上周帮A同学折腾新电脑,一天之内踩遍了配置 Maven 环境的所有经典坑:mvn 命令找不到、JAVA_HOME 路径不合法、依赖下载到一半卡死、IDEA 里构建正常但命令行一跑就报错。很多教程把 Maven 配置写成"下载解压、配两个变量、完事",但…

2026/10/19 13:51:40 阅读更多 →
SAP物料编号范围设计原理与实战配置指南

SAP物料编号范围设计原理与实战配置指南

简介:本资源是一份面向SAP ABAP开发人员、后勤模块顾问及系统实施工程师的实操型配置指南,聚焦物料主数据编号范围的后台维护方法与典型问题处理。针对ERP 6.0 EHP7版本,详细讲解如何通过MMNR/SNRO事务码创建号码组、定义内外部编号段&#x…

2026/10/19 13:51:40 阅读更多 →
LeetCode反转链表:迭代法详解与指针操作避坑指南

LeetCode反转链表:迭代法详解与指针操作避坑指南

1. 反转链表到底在反转什么 链表反转是LeetCode上出镜率最高的题目之一,没有之一。我刷了这么多题,面试里被问到的链表题,十道里有六道跟反转沾边——要么是完整反转,要么是反转前K个,要么是两两交换,要么是…

2026/10/19 13:51:40 阅读更多 →
MobileNetV2端到端部署实战:猫狗分类与模型量化

MobileNetV2端到端部署实战:猫狗分类与模型量化

1. 项目背景与技术选型思路一直在做端侧视觉类项目,说实话,猫狗图像分类这种题目听起来很“教学”,可真要把它做成一套能跑的轻量级系统,反而比想象中更能暴露问题。很多人一上来就往 VGG、ResNet 这种大模型上靠,训练…

2026/10/19 13:51:40 阅读更多 →
进口阀门选型与采购实务:极端工况应用与避坑指南

进口阀门选型与采购实务:极端工况应用与避坑指南

进口阀门这些年一直是工业项目里绕不开的话题。做设备采购的、搞工艺设计的、管工厂运维的,几乎都跟它打过交道。很多人一听到“进口阀门”就想到贵、货期长、售后麻烦,但实际上它能在国内重工业场景里占据一席之地,靠的是极端工况下那份稳定…

2026/10/19 13:50:38 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/19 1:30:52 阅读更多 →

月新闻

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