卷积神经网络底层原理与工程实践:从数学定义到官方文档细节
1. 为什么卷积值得你花时间啃官方文档很多人第一次接触卷积神经网络都是从调包开始的。几行代码把模型搭起来跑通一个手写数字识别准确率还挺高于是觉得自己已经学会了CNN。但真到了要改网络结构、排查loss不下降、或者面试被问到这个卷积层输出尺寸怎么算的时候立刻就卡壳了。我自己也经历过这个阶段后来才明白调包能让你跑起来但只有把卷积这件事从底层搞懂你才真正拥有调试和设计网络的能力。这篇文章面向的是已经会用框架搭模型、但对卷积内部机制还停留在知道个大概的读者。我会带着你把卷积算法从最朴素的数学定义一路拆到官方文档里那些容易被跳过的参数细节包括padding、stride、dilation、groups这些看似简单却处处是坑的概念。读完之后你应该能做到拿到任意一个卷积层配置能手动算出输出尺寸看到一段陌生的卷积代码能判断它在干什么遇到尺寸不匹配的报错能自己定位问题而不是到处搜。为什么强调官方文档因为网上大量教程是二手甚至三手信息很多细节在转述中被简化甚至传错了。比如卷积就是特征提取这种话说了等于没说。官方文档虽然枯燥但它是第一手定义参数含义、默认值、边界行为都写得清清楚楚。我踩过的坑里有一大半是因为当初偷懒没看文档凭直觉写参数结果在边缘情况上翻车。接下来的内容我会尽量用人话讲但不会为了通俗而牺牲准确性。每个概念我都会先讲它解决什么问题再讲它怎么算最后讲实际用的时候要注意什么。你可以把它当成一份陪你读文档的笔记也可以当成动手前的原理补课。2. 从数学定义到工程实现卷积到底在算什么2.1 那个被说烂了的滑动窗口到底滑的是什么卷积的数学定义是一个积分或求和连续形式是函数f和g的卷积离散形式在图像上就变成了加权求和。但工程实现里我们做的其实是互相关而不是严格意义上的卷积——区别在于卷积会把核翻转180度而深度学习框架里默认不翻转。这个细节很多人不知道但它在理解为什么学出来的核看起来是倒着的这类问题时很关键。具体来说假设你有一个5x5的输入图一个3x3的卷积核。所谓卷积操作就是把3x3的核盖在输入图的左上角3x3区域上对应位置相乘再求和得到一个标量这就是输出特征图左上角的一个像素。然后核向右滑动一格再算一次直到滑完整个图。这个滑动就是卷积的核心动作。用生活化的类比想象你拿一个带九个孔的模板去盖在一张方格纸上每个孔里放一个权重把孔下面的数字和权重相乘加起来写在一张新纸上。模板移动的步长、盖的位置、模板本身的大小全都是你可以控制的参数。卷积层要学的就是这九个孔里的权重值。这里有个容易混淆的点输入图的通道数。如果输入是RGB三通道那么一个3x3的卷积核实际上是3x3x3它在每个通道上各有一套权重最后把三个通道的结果加起来输出还是一个单通道的标量。如果你想输出多个通道就需要多个这样的核。所以一个卷积层的参数量是核高 × 核宽 × 输入通道数 × 输出通道数再加上输出通道数个偏置如果开启bias。2.2 输出尺寸公式一个你必须背下来的东西官方文档里通常会给出输出尺寸的计算公式但很多人记不住或者记混。我把它拆成最直白的形式输出尺寸 floor((输入尺寸 2 × padding - dilation × (kernel_size - 1) - 1) / stride) 1这个公式看着吓人其实拆开就三件事先把padding补上再把dilation撑开后的有效核大小算出来然后看能滑多少步。dilation这个参数后面会专门讲先假设它是1公式就简化成输出尺寸 floor((输入尺寸 2 × padding - kernel_size) / stride) 1举个例子输入32x32kernel 3x3padding 1stride 1输出 (32 2 - 3)/1 1 32。这就是为什么padding1、kernel3、stride1的卷积被称为same convolution因为它保持尺寸不变。这个组合在ResNet等网络里到处都是记住它很有用。再比如输入224x224kernel 7x7padding 3stride 2输出 (224 6 - 7)/2 1 223/2 1 111 1 112。这就是经典网络第一层把224降成112的由来。注意floor是向下取整意味着如果除不尽多余的部分会被丢掉。这就是为什么有时候你算出来的尺寸和实际对不上——框架不会自动帮你补它直接舍弃。我建议你在纸上手推几个例子比看十遍公式都管用。尤其是当stride大于1的时候很多人会算错。2.3 参数量与计算量为什么卷积比全连接省一个全连接层输入1024维输出1024维参数量是1024×1024≈100万。而一个卷积层输入通道64、输出通道64、核3x3参数量是3×3×64×64≈3.7万。差了将近30倍。这就是卷积的参数共享带来的好处同一个核在整个图上滑动权重复用参数量与输入尺寸无关。但参数量少不代表计算量小。卷积的计算量FLOPs大致是输出尺寸 × 输出尺寸 × 核大小 × 输入通道 × 输出通道。还是上面那个例子如果特征图是64x64计算量就是64×64×3×3×64×64≈1.5亿次乘加。所以卷积是参数少但计算密集的典型这也是为什么GPU对深度学习这么重要。理解这一点你就能明白为什么移动端模型要拼命用深度可分离卷积——它把标准卷积拆成逐通道卷积和逐点卷积计算量能降到原来的八分之一到九分之一。这个后面讲groups参数时会再展开。3. padding、stride、dilation三个参数决定卷积的性格3.1 padding不只是为了保持尺寸padding最直观的作用是控制输出尺寸但它还有两个容易被忽略的作用。第一是保护边缘信息。如果不加padding边缘像素只会被卷积核覆盖一次而中心像素会被覆盖多次导致边缘信息在深层网络中逐渐丢失。加了padding之后边缘也能被公平对待。第二是配合stride控制下采样节奏这在设计网络时很关键。padding的模式在不同框架里有不同叫法。常见的有模式含义使用场景zeros补零最常用默认reflect镜像反射图像生成、超分replicate复制边缘减少边界伪影circular循环填充周期性信号补零是最简单的但在图像边缘会产生人工的黑边效应。做图像修复或生成任务时reflect往往效果更好因为它让边缘过渡更自然。这个细节官方文档里通常一笔带过但实际调参时影响不小。还有一个坑当padding给的是字符串same或valid时不同框架的行为不完全一致。same一般会尽量让输出尺寸等于输入除以stride但具体补多少、补在哪边实现上可能有差异。我建议在跨框架迁移代码时把padding写成具体数字避免依赖字符串模式。3.2 stride下采样的第一把刀stride就是滑动的步长。stride1时逐像素滑输出尺寸基本不变stride2时隔一个像素滑输出尺寸大约减半。它是卷积层里最直接的下采样手段。为什么需要下采样因为随着网络加深我们希望感受野越来越大同时特征图越来越小以减少计算量。stride2的卷积或者池化层都是干这个的。两者的区别在于池化是固定的取最大或平均没有可学习参数stride卷积是有参数的网络可以自己学怎么降采样。现代网络越来越倾向于用stride卷积替代池化因为更灵活。但stride有个陷阱当stride不能整除(输入2×padding-kernel)时最后会丢掉一部分像素。比如输入7kernel 3padding 0stride 2输出(7-3)/213实际覆盖了位置0-2、2-4、4-6位置6之后还剩一个像素没被覆盖直接丢了。这在设计网络时可能导致信息浪费尤其是输入尺寸比较小的时候。实操建议设计网络时尽量让每层的输入尺寸能被stride整除或者用padding补齐。我习惯在纸上画一遍尺寸变化确认没有意外的信息丢失。3.3 dilation不增加参数就能扩大感受野dilation空洞卷积是个很巧妙的设计。它把卷积核的元素之间插入空洞比如dilation2的3x3核实际覆盖的区域是5x5但只有9个权重。这样在不增加参数量的情况下扩大了感受野。感受野为什么重要因为它决定了输出特征图上的一个像素能看到输入图多大范围的信息。感受野太小网络就抓不到全局上下文感受野太大又容易引入无关信息。dilation提供了一种精细控制感受野的手段。dilation的代价是网格效应当dilation较大时核覆盖的区域是稀疏的可能漏掉一些像素。所以在实际使用中dilation通常配合特定的核大小或者用混合dilation不同层用不同dilation来缓解。比如在语义分割任务里常见的做法是连续几层用dilation 1、2、4既扩大了感受野又避免了网格效应。计算有效核大小的公式是有效核 dilation × (kernel_size - 1) 1。dilation2、kernel3时有效核2×215。这个数要代回前面的输出尺寸公式里算。4. 通道、分组与深度可分离卷积的变体家族4.1 groups参数分组卷积的来龙去脉groups参数控制输入通道和输出通道之间的连接方式。groups1是标准卷积每个输出通道和所有输入通道相连。groups输入通道数时就是深度卷积每个输出通道只和对应的一个输入通道相连通道之间完全不交互。分组卷积最早是为了解决显存不够的问题——把通道分成几组每组独立卷积参数量和计算量都降到1/groups。但后来大家发现分组本身还能带来正则化效果甚至提升精度。这就是为什么ResNeXt这类网络大量使用分组卷积。groups的约束是输入通道数和输出通道数都必须能被groups整除。这个约束经常被忽略导致报错。比如输入通道64、输出通道32、groups364/3除不尽直接报错。设计时要先确认整除关系。4.2 深度可分离卷积移动端的救命稻草深度可分离卷积是深度卷积加逐点卷积的组合。深度卷积负责在每个通道上独立提取空间特征逐点卷积1x1卷积负责跨通道融合信息。这样拆开之后计算量大幅下降。具体算一下标准卷积输入通道C、输出通道C、核KxK计算量是K×K×C×C。深度可分离卷积深度卷积是K×K×C逐点卷积是1×1×C×C总共K×K×C C×C。比值是(K×K×C C×C)/(K×K×C×C) 1/C 1/(K×K)。当C64、K3时大约是1/64 1/9 ≈ 0.127也就是计算量降到约八分之一。这个降幅非常可观所以MobileNet系列、EfficientNet等移动端网络都大量使用。但代价是精度可能略有下降因为深度卷积和逐点卷积之间没有非线性通常中间不加激活表达能力受限。实际使用时要根据任务权衡。4.3 1x1卷积不只是降维1x1卷积看起来什么都没做——核大小1x1每次只看一个像素。但它的作用其实很大。第一是跨通道信息融合因为它在所有输入通道上做加权求和输出新通道。第二是改变通道数升维或降维都行而且不改变空间尺寸。第三是增加非线性因为后面可以接激活函数。在Inception、ResNet的瓶颈结构里1x1卷积用来先降维再升维大幅减少计算量。比如输入256通道先用1x1降到64做3x3卷积再用1x1升回256。这样3x3卷积的计算量降到原来的十六分之一。实操心得1x1卷积的参数量是输入通道×输出通道当通道数很大时这个量也不小。设计瓶颈结构时降维比例比如4倍是个需要调的超参太小省不了计算太大丢信息。5. 官方文档里那些容易看漏的细节5.1 权重初始化默认值不一定适合你官方文档里卷积层的权重初始化通常有个默认值比如均匀分布或正态分布。但这个默认值往往是为通用场景设计的不一定适合你的具体任务。比如当卷积核较大时默认初始化可能导致输出方差过大或过小训练不稳定。常见的做法是用He初始化或Xavier初始化它们根据输入输出通道数自动调整方差。He初始化适合ReLU激活Xavier适合tanh或sigmoid。如果你发现训练初期loss震荡或者梯度消失先检查初始化。还有一个细节bias的初始化。默认通常是0这没问题。但如果你的输入数据均值不为0bias0可能让初始输出偏离可以考虑把bias初始化成输入均值的相反数。不过现代网络常用BatchNormbias的作用被弱化了很多实现干脆把bias关掉。5.2 输入输出通道的排列顺序不同框架对张量的维度顺序定义不同。有的用NCHW批、通道、高、宽有的用NHWC。这个差异在跨框架迁移时经常导致莫名其妙的错误。比如你按NCHW写的代码换到NHWC框架上通道数被当成了高度尺寸全乱。官方文档一般会明确写清楚但很多人不看凭经验写结果踩坑。我的习惯是拿到一个新框架先写个最小例子打印输入输出张量的shape确认维度顺序再写正式代码。5.3 边界情况空输入、单像素、超大核官方文档通常不会覆盖所有边界情况但实际使用中会遇到。比如输入尺寸小于卷积核尺寸时如果不加padding输出尺寸会算成负数或零框架可能报错也可能返回空张量。再比如kernel_size大于输入尺寸时某些框架会自动调整padding某些直接报错。这些边界情况在写通用代码或处理用户输入时特别重要。我建议在卷积层前面加一个尺寸检查确认输入至少能容纳一个完整的卷积核。如果不行要么加padding要么报错提示别让框架抛一个看不懂的异常。6. 从文档到代码手推一个卷积层的完整过程6.1 给定配置手算输出尺寸和参数量假设我们要设计一个卷积层输入是64x64x3的彩色图kernel 5x5输出通道32stride 2padding 2dilation 1bias开启。我们来手算一遍。输出尺寸有效核 1×(5-1)1 5。输出 floor((64 2×2 - 5)/2) 1 floor(63/2) 1 31 1 32。所以输出是32x32x32。参数量5×5×3×32 32 2400 32 2432。计算量32×32×5×5×3×32 ≈ 786万次乘加。这些数字在设计网络时很有用。比如你想控制模型大小就可以通过调整输出通道和核大小来估算。6.2 用代码验证你的手算结果光算不够最好用代码验证。以PyTorch为例import torch import torch.nn as nn conv nn.Conv2d(in_channels3, out_channels32, kernel_size5, stride2, padding2, dilation1, biasTrue) x torch.randn(1, 3, 64, 64) y conv(x) print(y.shape) # 应该是 torch.Size([1, 32, 32, 32]) print(sum(p.numel() for p in conv.parameters())) # 应该是 2432跑一遍对上了说明你的理解没问题。对不上就回去检查公式哪里用错了。这个习惯我强烈建议养成——每次设计新层都手算加验证几次之后你就对尺寸变化有直觉了。6.3 尺寸不匹配报错的排查链路实际写代码时最常见的报错就是尺寸不匹配。比如全连接层输入维度对不上或者残差连接的两路尺寸不一致。排查思路是这样的第一步打印每一层的输入输出shape找到第一个出错的层。第二步用输出尺寸公式反推看是哪一层的配置导致尺寸变化和预期不符。第三步检查stride、padding、dilation是否和你想的一致尤其是从别人代码抄过来的时候。第四步如果是残差连接确认两路的下采样方式是否一致——常见错误是一路用了stride2卷积另一路用了池化结果尺寸差一个像素。我遇到过最隐蔽的一次是padding模式不同一路用zeros一路用reflect在边缘差了一个像素导致相加时报错。这种问题不看文档根本想不到。7. 一些让我少走弯路的实操习惯第一个习惯是画尺寸流程图。设计网络时我在纸上画一列每层写输入尺寸、配置、输出尺寸像流水账一样。这样一眼就能看出哪里尺寸掉得太快、哪里通道数爆炸。比在代码里调试快得多。第二个习惯是先跑通最小配置再扩展。不要一上来就搭一个几十层的网络先用一两层卷积加一个全连接确认数据流没问题再逐步加层。每加一层都验证尺寸避免错误累积到最后难以定位。第三个习惯是把关键参数写成变量。kernel_size、stride、padding这些不要硬编码在层定义里提到外面用变量表示。这样调整时改一处就行也方便做超参搜索。第四个习惯是关注感受野而不是层数。很多人以为层数越多感受野越大其实stride和dilation对感受野的影响更大。设计网络时先估算目标感受野再反推需要多少层、用什么配置比盲目堆层数有效。关于dilation我再补充一个经验dilation大于1时和stride大于1组合使用要小心。两者都会影响输出尺寸而且dilation会改变有效核大小容易算错。如果非要用建议先固定一个调另一个别同时改。最后说一个关于groups的坑。当你用groups做分组卷积时如果后面接BatchNorm要注意BatchNorm是在所有通道上做的而分组卷积的输出通道虽然分组计算但输出还是拼在一起的所以BatchNorm没问题。但如果你用的是GroupNorm就要确认分组数和卷积的groups是否匹配不匹配会导致统计量计算错误。这个细节文档里不一定写但实际用的时候会碰到。卷积这东西入门容易精通难。官方文档是起点不是终点真正的理解来自于你亲手算过、跑过、错过、改过。我上面写的这些每一条背后都有至少一次踩坑经历。希望你看完之后下次遇到卷积相关的问题能少搜几次、多想几步。

相关新闻

AI辅助教材编写的正确姿势:提升效率与保证原创性

AI辅助教材编写的正确姿势:提升效率与保证原创性

抱歉,这个标题涉及的内容我不能帮你写。用AI生成“低查重”内容来写教材,本质上是规避学术诚信检测,无论用途如何,都不符合合规要求,也违背了教育领域的基本原则。如果你需要,我可以帮你写一个完全合规的方…

2026/10/16 22:59:25 阅读更多 →
GIS+AI驱动的物流园区数字化平台:落地实践与复盘

GIS+AI驱动的物流园区数字化平台:落地实践与复盘

我们团队最近刚上线了一套物流园区数字化管理平台,从前期需求调研到最后稳定运行,前后大概花了七个多月。项目本身不算特别“新”,但涉及的技术栈比较典型——GIS底图、IoT感知层、AI调度算法、三维可视化、和客户现有的仓储管理系统做数据对…

2026/10/16 22:59:25 阅读更多 →
GRADE方法:如何将大模型对齐训练方差降低14倍

GRADE方法:如何将大模型对齐训练方差降低14倍

1. 大模型对齐为什么难?先说说“方差”这个拦路虎在聊GRADE这套方法之前,我们还是得回到一个根本问题上:大模型对齐到底难在哪?很多人一提到对齐,第一反应就是RLHF(基于人类反馈的强化学习)&…

2026/10/16 22:58:24 阅读更多 →

最新新闻

ArcGIS Sptools工具箱:高效处理空间数据的Python脚本集合

ArcGIS Sptools工具箱:高效处理空间数据的Python脚本集合

简介:ArcGIS Sptools工具箱是一套面向GIS专业人员的ArcGIS插件级扩展工具集,专为提升地理数据批量处理、地图样式定制与辅助分析效率而设计,适用于ArcGIS Desktop/Pro用户及中高级GIS项目开发者。资源包共389个文件,含21个可直接加…

2026/10/16 23:57:20 阅读更多 →
IMS计费标准3GPP TS 32.260详解:离线在线计费与ICID机制

IMS计费标准3GPP TS 32.260详解:离线在线计费与ICID机制

简介:本资源为3GPP TS 32.260 IMS计费技术规范的中文版PDF文档,面向从事移动通信核心网计费系统研发、测试与运维的工程师,以及需要理解IMS计费机制的通信专业学生与研究人员。文档系统梳理了IMS离线计费、在线计费与融合计费三种架构&#x…

2026/10/16 23:53:18 阅读更多 →
VoLTE掉话治理:信令时序与资源生命周期协同优化

VoLTE掉话治理:信令时序与资源生命周期协同优化

简介:本资源是一份聚焦VoLTE掉话根因分析与实战优化的深度技术文档,面向4G/5G无线网络优化工程师、核心网运维人员及通信专业高年级学生,解决VoLTE业务中高频掉话、重建立失败、信令异常等现网典型问题。文档基于广州ATU网格真实测试数据&…

2026/10/16 23:53:18 阅读更多 →
思科校园网课程设计实战:VLAN规划、协议抓包与排错避坑

思科校园网课程设计实战:VLAN规划、协议抓包与排错避坑

简介:基于思科的校园网搭建及网络协议分析课程设计文档,适合计算机网络课程设计、毕业设计或实验报告撰写参考。内容从应用场景和需求分析入手,设计了校园网整体拓扑,重点介绍服务器配置、无线网络部署、各部门路由器与交换机的VL…

2026/10/16 23:52:17 阅读更多 →
贝叶斯网络、HMM与CRF:结构化预测的选型决策图谱

贝叶斯网络、HMM与CRF:结构化预测的选型决策图谱

1. 这不是概念堆砌,而是三条技术路径的“血缘图谱”你翻过不少资料,可能见过这样的描述:“贝叶斯网络是概率图模型的一种”“马尔可夫模型强调无记忆性”“条件随机场擅长序列标注”。但这些定义像贴在玻璃上的标签——看得见,摸不…

2026/10/16 23:51:16 阅读更多 →
动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

动态环境四个字出现在综述标题里,听起来像一句套话,但真正跑过一版视觉SLAM的人都知道,一个在走廊里来回走动的人,就足以让原本稳定的位姿估计在十几秒内现出原形。运动恢复结构(Structure from Motion)也一…

2026/10/16 23:51:16 阅读更多 →

日新闻

个人 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/16 21:35:51 阅读更多 →
影刀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/16 21:54:38 阅读更多 →
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 阅读更多 →