TensorFlow入门:从线性回归到逻辑回归的完整实战指南
从零开始跑通 TensorFlow 的第一个模型其实是件挺考验耐心的事。我见过不少朋友兴致勃勃装了环境结果卡在“先学什么模型”这个问题上翻了一堆资料从卷积神经网络看到 Transformer最后还是回到最简单的线性回归。这个选择其实很明智TensorFlow 里的高阶 API 封装程度很高如果一上来就追热点模型很容易被复杂的张量操作和训练细节劝退。反而是从线性回归和逻辑回归入手能把“数据流图、损失函数、梯度下降、评估指标”这条主线一次理清之后再去看 CNN、RNN 就会顺畅很多。这篇内容就是沿着这条主线写的定位是给刚接触深度学习的开发者看的手把手指南。我会先讲讲为什么选 TensorFlow然后分别拆解线性回归和逻辑回归的数学原理、代码实现、训练过程最后说一说我把这两个模型跑通之后对后续学习方向的一些体会。整个过程里我会把环境配置、数据准备、训练循环这些容易被忽略的细节也一并交代清楚你可以直接照着敲代码应该能在半天内把这两个经典模型完整跑通。1. TensorFlow 到底是什么以及为什么我推荐用它入门1.1 TensorFlow 能做什么它解决的痛点是什么TensorFlow 本质上是一个数值计算框架它把复杂的数学运算组织成一张有向图图中的节点是操作op边是数据张量。你在写模型时定义的网络结构会被转换成这张计算图然后交给底层的执行引擎去调度充分利用 CPU、GPU 甚至 TPU 的计算能力。对我来说它最大的价值不是“跑得快”而是“思路清晰”——你把前向传播搭好声明好损失函数剩下的事情框架帮你安排。很多人觉得深度学习很神秘其实核心就三件事定义模型结构、定义损失函数、定义优化方法。这三个步骤 TensorFlow 都提供了高度封装的接口。框架本身是一个工具箱而线性回归和逻辑回归就是你第一次真正使用这个工具箱去解决实际问题的尝试。TensorFlow 2.x 之后默认开启了 Eager Execution动态图模式你可以像写普通 Python 一样逐行执行张量操作不用像早期版本那样先构建图再统一运行调试体验好了非常多。1.2 版本选择和环境配置的几条经验早期 TensorFlow 1.x 有tf.Session()、tf.placeholder这些概念现在 2.x 基本已经不用了。2024 年之后新入门的朋友我建议不要去看 1.x 的旧教程直接学 2.x 的 Keras API 就好。顺便说一句如果你是从 PyTorch 转过来的会发现 TensorFlow 2.x 的写法其实已经没那么别扭了。环境配置给两条建议。第一用虚拟环境隔离项目依赖不要直接装到系统 Python 里排除包冲突的隐患。第二新手阶段用 CPU 版本跑这两个模型完全够了线性回归和逻辑回归都是毫秒级到秒级的任务没必要为了跑 demo 折腾 GPU 驱动和 CUDA。直接一行pip install tensorflow即可。注意如果你的机器是 Apple Silicon 芯片推荐安装tensorflow-macos加上tensorflow-metal插件CPU 版本的训练速度也能有不错的提升。Windows 用户直接装标准版就行。2. 线性回归从原理到代码一步步拆解2.1 线性回归的数学直觉拟合一条线线性回归要解决的问题很朴素给你一堆散点让你找一条直线尽可能穿过它们。比如你想根据房子面积预测房价假设数据大致呈线性关系那模型就是一个形如y w * x b的一次函数。这里的w是权重b是偏置两个都是变量模型训练的目标就是找到一组最好的w和b让预测值跟真实值之间的差距最小。怎么衡量“差距”最常用的是均方误差MSE公式是每个样本预测值与真实值差值的平方和除以样本数。平方的目的是消除正负号抵消、同时放大大误差的影响——误差越大平方后惩罚越重。为什么用平方而不是绝对值因为平方函数是处处可导且光滑的方便后面做梯度下降。你用绝对值的话在零点处不可导优化过程容易卡住。2.2 手写核心训练循环理解底层的梯度更新过程在跳进 Keras 高层 API 之前我强烈建议你先手写一次训练循环哪怕只跑一次也好。这样才能真正理解“训练”发生了什么。import numpy as np import tensorflow as tf # 生成模拟数据y 3x 2 噪声 x_data np.random.rand(200, 1).astype(np.float32) y_data 3 * x_data 2 0.1 * np.random.randn(200, 1).astype(np.float32) # 定义可训练变量 w tf.Variable(tf.random.normal([1, 1])) b tf.Variable(tf.zeros([1])) learning_rate 0.01 for epoch in range(500): with tf.GradientTape() as tape: # 前向传播 y_pred tf.matmul(x_data, w) b # 计算损失 loss tf.reduce_mean(tf.square(y_data - y_pred)) # 反向传播自动求梯度 grads tape.gradient(loss, [w, b]) # 手动更新参数 w.assign_sub(learning_rate * grads[0]) b.assign_sub(learning_rate * grads[1]) if epoch % 100 0: print(fEpoch {epoch}, Loss: {loss.numpy():.4f}) print(f训练结果: w {w.numpy()}, b {b.numpy()})这段代码有几个地方值得细看。tf.GradientTape()是 TensorFlow 2.x 的自动求导机制它会记录在它作用域内的所有张量操作然后调用tape.gradient()就能自动计算损失对每个变量的梯度。这背后用到了链式法则但你不必手动推导框架都帮你做了。训练的本质就是“猜w和b算损失求梯度沿着梯度反方向更新参数”。assign_sub就是做w w - learning_rate * gradient这个操作它是在原变量上原地更新而不是重新创建变量这样可以保证计算图里的连接关系不变。学习率0.01是我试了试比较合适的值太大了会震荡不收敛太小了收敛慢后面讲问题排查时再展开。2.3 用 tf.keras 高层 API 实现真正的生产写法手写循环理解原理但实际项目中我更推荐用 Keras 的Sequential模型代码精简很多可读性也好。Keras 把前向传播、损失计算、梯度更新都封装好了你只需要几行声明式的代码。model tf.keras.Sequential([ tf.keras.layers.Dense(1, input_shape(1,)) ]) model.compile(optimizersgd, lossmse, metrics[mae]) history model.fit(x_data, y_data, epochs200, verbose1)Dense(1)就是全连接层它做的事情就是y w * x b跟前面手写的完全一样。input_shape(1,)告诉模型输入是一个一维特征。optimizersgd就是随机梯度下降lossmse对应均方误差metrics[mae]会额外输出平均绝对误差方便你直观理解预测偏差的量级。fit函数是整个训练过程的入口它内部帮你处理了批次切分、梯度更新、日志打印等所有细节。训练完成后可以调用模型查看参数w_trained, b_trained model.layers[0].get_weights() print(fKeras 训练结果: w {w_trained[0][0]}, b {b_trained[0]})我实测下来手写循环和 Keras 高层 API 训练出的参数基本一致误差在小数点后几位。区别在于 Keras 帮你做了更多工程化处理比如自动切分 batch、每个 epoch 的进度条、验证集评估等这些在真实项目中都是必须的。3. 逻辑回归分类问题从这里开始3.1 从回归到分类逻辑回归到底“回归”了什么逻辑回归名字里带着“回归”实际上解决的是分类问题。它的思路是在线性回归的输出外面套一层激活函数sigmoid把任意实数压缩到 0 到 1 之间输出可以解释为样本属于某个类别的概率。比如判断一封邮件是否是垃圾邮件输出是 0.8就可以说“80% 的概率是垃圾邮件”。sigmoid 函数公式是sigmoid(z) 1 / (1 exp(-z))z 是线性部分w * x b的输出。这个函数有几个好性质值域在 (0,1)单调递增且是可导的方便梯度计算。它的导数有个很漂亮的形式sigmoid(z) * (1 - sigmoid(z))这让反向传播的计算变得非常简洁这也是为什么它成为经典激活函数的原因。这里面有个关键点分类问题不能再用均方误差作为损失函数了。逻辑回归用的是二元交叉熵binary crossentropy公式是-y * log(y_pred) - (1 - y) * log(1 - y_pred)。为什么换损失函数因为 sigmoid 函数会在两端饱和如果还用均方误差梯度会变得很小模型学不动收敛极慢。交叉熵在概率输出场景下梯度更稳定优化曲面更适合梯度下降。3.2 用 tf.keras 实现二分类模型二分类问题的标准做法是最后一层用含 1 个神经元的 Dense 层激活函数用 sigmoid损失函数用 binary_crossentropy。我以“模拟某销售系统判断用户是否会产生消费”为例写一个完整的流程。import numpy as np import tensorflow as tf # 造一份二分类模拟数据 np.random.seed(42) n_samples 1000 # 两个特征访问时长和页面浏览数 X np.random.randn(n_samples, 2).astype(np.float32) # 生成标签简单的线性可分 一点噪声 y (X[:, 0] * 2 X[:, 1] * 1 0.5 0).astype(np.float32) # 切分训练集和测试集 split int(n_samples * 0.8) X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:] model tf.keras.Sequential([ tf.keras.layers.Dense(1, activationsigmoid, input_shape(2,)) ]) model.compile(optimizertf.keras.optimizers.Adam(learning_rate0.01), lossbinary_crossentropy, metrics[accuracy]) history model.fit(X_train, y_train, epochs100, batch_size32, validation_data(X_test, y_test), verbose1) # 评估测试集 loss, acc model.evaluate(X_test, y_test, verbose0) print(f测试集准确率: {acc:.4f}) # 预测 probs model.predict(X_test[:5]) print(预测概率:, probs.flatten())这里我特意用了 Adam 优化器而不是 SGD。Adam 能根据每个参数的历史梯度自动调整学习率对新手来说不用手动调学习率就能跑出不错的结果省心很多。batch_size32表示每 32 个样本做一次梯度更新训练时内存占用小、且梯度估计更稳。validation_data参数会在每个 epoch 结束后在验证集上评估模型这样你能实时看到模型在没见过数据上的表现防止过拟合。3.3 多分类问题的那些“进阶”细节如果你拿来训练的数据不是两个类别而是手写数字识别那种 10 分类逻辑回归的思想可以无缝扩展输出层神经元数量改成类别数激活函数换成 softmax损失函数换成 categorical_crossentropy。softmax 做的事情是把一组实数logits变成一组和为 1 的概率分布最大的那个就是模型预测的类别。这里有个编码细节容易踩坑categorical_crossentropy要求标签是 one-hot 编码比如 [0,1,0,0...]而sparse_categorical_crossentropy可以直接接受整数标签比如 2 就代表第 2 类。实际用的时候要对应好否则会报形状不匹配的错误。我个人习惯用sparse_categorical_crossentropy因为多数数据集加载出来是整数标签省一个编码步骤。多分类跟二分类的区别还有一个点输出层没有用 sigmoid用的是 softmax。两者本质都是把线性输出映射为概率区别在于 softmax 保证所有类别概率之和为 1且每个概率都大于 0。这种设计天然适合互斥分类场景。4. 从线性到非线性这两个模型学习价值的关键所在4.1 两个模型的本质关联以及它们之间的经典延展线性回归和逻辑回归的关系可以理解为一个连续的递进线性回归输出连续实数值用于预测逻辑回归在线性输出的基础上加非线性变换输出离散概率用于分类。它们在数学结构上高度统一区别只在损失函数和最后的激活层。掌握了这两个模型后续学神经网络的路就很顺了。教科书上经典的“单层感知机”本质上就是一个逻辑回归模型而深层神经网络就是堆叠了多个这样的层并且在每层之间加入非线性激活函数。你可以把这两个模型理解为深度学习的“原子组件”。从这两个模型里收获的建模思路——定义结构、选损失、优化求解——和后面搭 CNN、RNN 时的思路完全一致。4.2 为什么“会写代码”还不够关键是理解数据流我指导过一些朋友代码能跑通、结果也对但换一个数据集就不会改代码了。问题往往出在没搞懂数据形状流经网络的路径。在 Keras 里每层张量的形状变化比如输入是(样本数, 特征数)经过Dense(1)变成(样本数, 1)再和标签(样本数, 1)算损失。这个形状流如果不清楚改输入特征数量时必然报错。建议你可以做一个小实验定义一个很简单的模型用model.summary()打印网络结构再用model.layers[i].output观察中间张量的形状。这个习惯比背 API 更有价值因为深度学习里 80% 的报错都是形状不匹配导致的。运行一下model.summary()看看输出Model: sequential _________________________________________________________________ Layer (type) Output Shape Param # dense (Dense) (None, 1) 3 这里的None表示 batch 维度可以是任意大小。Param 是 3对应两个特征的权重加一个偏置。这个信息对排查问题很重要。5. 常见报错排查新手最容易踩的坑5.1 形状不匹配问题报错信息里最常见的就是ValueError: Shapes (None, 1) and (None, 2) are incompatible。我举个例子你的标签 y 如果是二维的(样本数, 1)而模型输出的形状在某些配置下变成了(样本数,)两者做损失计算就会报错。排查思路很简单打印x.shape和y.shape确认维度再用reshape或tf.squeeze统一形状。还有种情况是 Keras 里当你用Sequential的第一层不指定input_shape时模型会在第一次fit时推断输入形状。如果训练数据和验证数据的特征数不一致fit 过程中会直接报警。所以检查数据形状是第一步别急着改模型。5.2 损失值不下降或变成 NaN 的处理损失值一直不降最常见的原因是学习率太大或数据没做归一化。像线性回归里特征如果跨了几个数量级房价上百万、面积几十平梯度更新的方向就会扭曲。解决办法是数据标准化减均值除以标准差让特征大致落在同一个尺度上。损失变成 NaN多半是梯度爆炸了。针对逻辑回归我遇到过一种典型情况学习率设成 0.1adam 优化器也救不回来损失直接是 nan。解决方式是降低学习率或者对输入数据做归一化。还有个隐性坑是标签数据里有 NaN这种一般来自数据预处理阶段可以用np.isnan(y).any()检查一下。注意遇到 NaN先查数据再查学习率。不要一上来就怀疑模型结构线性回归和逻辑回归的结构极其简单很少是结构本身出问题。5.3 过拟合和欠拟合的快速判断训练集 loss 很低、验证集 loss 很高这是过拟合。线性回归模型一般不会过拟合因为模型容量太小。逻辑回归也很少过拟合但如果你加了过多高阶特征比如把 x 变成 x^2、x^3就会有这个问题。判断方法就一个看验证集指标是否明显差于训练集。反过来如果训练集 loss 就很高那是欠拟合说明模型容量不够或者数据分布不是线性的。这时候不要硬调参数而是考虑换非线性模型。我见过有人在线性回归上死磕调了一天学习率结果数据本身就是二次函数线性模型怎么可能拟合得好遇到这种情况直接上多项式特征或换模型才是正解。6. 跑通这两个模型之后下一步怎么走我个人觉得学深度学习最好的节奏是“一次只往前迈一步”。线性回归和逻辑回归跑通之后可以尝试这样几个自然延伸把逻辑回归的 2 分类扩展到 10 分类的多分类任务体验 softmax 和交叉熵的组合把线性回归的单一特征改成多个特征体会输入维度对模型结构和训练速度的影响再进一步把网络加深一层比如Dense(8, activationrelu)加Dense(1)你就能看到引入非线性激活函数后模型对非线性数据的拟合能力有了质的飞跃这时候你再回头看今天的两个模型就能真正看到深度学习层层递进的全貌。我在给一些初学者做指导时经常强调一件事不要急着追新模型新架构把最简单的模型吃透比看十篇热门论文有用得多。因为你会在实践中建立起“模型结构 — 损失函数 — 数据分布 — 优化过程”这个完整的思维闭环。有了这个闭环后面遇到的每个模型、每个新架构你都能快速抓住它的核心。最后再分享一个小技巧跑模型时把model.fit的返回值history保存下来用 matplotlib 画一下训练过程的 loss 曲线。我每次调试模型都会先看这个曲线它比任何日志都直观。Loss 曲线如果下降平滑说明训练状态正常如果剧烈震荡说明学习率太激进如果验证集 loss 不掉反升过拟合的信号很明显。这个习惯陪我排查了非常多的模型问题建议你也一试。

相关新闻

STM32+FreeRTOS+W5500+MQTT工业级通信栈实战

STM32+FreeRTOS+W5500+MQTT工业级通信栈实战

简介:本资源是一套基于STM32F103RET6的物联网终端完整嵌入式开发工程,面向嵌入式初学者与IoT项目开发者,解决MCU端多任务调度、以太网接入及云端MQTT通信集成难题。工程深度融合FreeRTOS实时调度、W5500硬件TCP/IP协议栈与轻量级MQTT客户端&a…

2026/10/16 13:37:12 阅读更多 →
TG记账群发机器人源码解析:消息监听、指令解析与统计汇总全链路

TG记账群发机器人源码解析:消息监听、指令解析与统计汇总全链路

简介:这是一套面向Telegram平台开发者的统计机器人源码合集,聚焦群发、账单统计与自动记账三大核心功能,适合有一定PHP与前端基础、希望快速搭建TG记账或群发工具的中高级开发者。压缩包共收录约2000个文件,以688个PHP后端脚本、3…

2026/10/16 13:37:12 阅读更多 →
VCU开发源码包实战指南:从工程骨架到CAN协议验证

VCU开发源码包实战指南:从工程骨架到CAN协议验证

简介:本资源为电动汽车整车控制器(VCU)的完整开发套件,面向嵌入式工程师、新能源汽车控制系统学习者及高校相关专业师生,解决VCU软硬件协同开发、控制策略理解与实车系统集成等核心问题。压缩包共477个文件&#xff0c…

2026/10/16 13:37:12 阅读更多 →

最新新闻

ArcGIS坡度分析避坑指南:从投影单位到DEM清洗的关键细节

ArcGIS坡度分析避坑指南:从投影单位到DEM清洗的关键细节

坡度分析这个事,说大不大说小不小。你在ArcGIS里用一把 Slope 工具,点一下运行,demo 数据立马出图,看着挺像那么回事。但如果你拿它去写报告、出专题图、甚至作为后续水文分析或地形分类的输入,问题就一串串地冒出来—…

2026/10/16 15:31:51 阅读更多 →
YOLOv5动态锚点与多尺度预测原理解析

YOLOv5动态锚点与多尺度预测原理解析

简介:本资源是一份面向Python与计算机视觉初学者的YOLOv5实战入门指南,聚焦目标检测框架的本地环境搭建与端到端应用,解决新手在CUDA/cuDNN适配、PyTorch依赖冲突、预训练模型调用及基础检测流程等常见卡点问题。文档以清晰步骤覆盖从系统要求…

2026/10/16 15:31:51 阅读更多 →
数据分析指标黑话全解析:从DAU到LTV,听懂业务增长的关键指标

数据分析指标黑话全解析:从DAU到LTV,听懂业务增长的关键指标

1. 为什么数据分析师说话像“加密通话”刚入行那会儿,我第一次参加数据周会,听到“这个项目DAU掉了,但次留还稳,ARPU也扛住了,就是GMV差了点意思”这类话,整个人是懵的。明明每个字都认识,连在一…

2026/10/16 15:31:51 阅读更多 →
ArcGIS mxd工程包管理:图层规范、数据源校验与ArcPy批处理实践

ArcGIS mxd工程包管理:图层规范、数据源校验与ArcPy批处理实践

简介:ArcGIS地图数据压缩包面向GIS开发者和地理信息学习者,汇集城市级、洲级与世界级三套多尺度地图图层,并配套Esri标准的.msd地图文档,可广泛服务于地图制作、空间分析、数据管理与二次开发等场景。包内共有24个文件&#xff0c…

2026/10/16 15:31:51 阅读更多 →
单阶段实例分割新思路:EmbedMask的嵌入耦合机制解析

单阶段实例分割新思路:EmbedMask的嵌入耦合机制解析

直接说结论:如果你觉得“单阶段实例分割”就是 YOLACT、SOLO 那一类方法的天下,那么 EmbedMask 值得你再花半小时重新理解一遍。它没有把实例分割变成一个完全检测驱动的任务,也没有回到两阶段那种“先框后分割”的串联老路,而是把…

2026/10/16 15:31:51 阅读更多 →
企业级LLM大模型落地实战:从微调对齐到生产安全

企业级LLM大模型落地实战:从微调对齐到生产安全

简介:这是一份面向AI工程师、机器学习工程师、数据科学家及科研人员的《企业级生成式人工智能LLM大模型技术、算法及案例实战》PDF电子书。内容以2024年7月线上高级实训班为骨架,系统覆盖Generative AI原理本质、工业级Prompting、Llama 2/3模型深度解密…

2026/10/16 15:30:50 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →