从显存预算守恒出发,拆解 semanticseg 在超大遥感影像上的内存行为,给出可核算、可复现、可回退的工程决策路径。
摘要
用 MATLAB 的 semanticseg 对大幅面遥感影像做 U-Net 预测时,显存(GPU memory)耗尽往往不是“把 MiniBatchSize 调小”就能解决的问题。本文的核心判断是:显存占用由“单次前向传播的张量驻留量”决定,而 MiniBatchSize 只影响其中的批维度。因此,当单张影像本身就超过可用显存时,降低批大小会失效,必须改变“输入的空间切分方式”。
本文以“显存预算守恒”为贯穿主线,先给出可手算的显存核算模型,再分别剖析滑窗推理(sliding-window inference)、分块训练再拼接(tile-based training + mosaic)与混合策略的机制、适用边界与失效条件;随后讨论重叠率、边界效应、拼接缝、类别不平衡与精度评估等工程细节,并给出参数选取的量化路径与代码骨架。结论是:推理阶段优先滑窗,训练阶段优先分块,二者不是二选一,而是同一显存预算下的两级调度。
目录
1. 问题的真正形状:显存爆掉到底爆在哪
先把现象拆开。MATLAB 中调用 semanticseg 对一张大幅面遥感影像做预测,报错通常是 Out of memory on device 或 GPU out of memory。很多人的第一反应是调小 MiniBatchSize,但调小之后仍然失败,于是开始怀疑模型太大、显卡太差。这个判断链条在多数情况下是错的。
关键在于理解 semanticseg 在推理时的输入语义。当你传入一个 H×W×C 的整幅影像时,函数内部会把它当作一个样本,按网络结构逐层展开前向计算。此时批维度是 1,MiniBatchSize 已经退化为 1,再往下调没有意义。真正撑爆显存的是这个“单样本”在特征图上产生的中间激活张量。
以 U-Net 为例,编码器在浅层保持较高空间分辨率(例如 1/2、1/4 尺度),这些层的特征图尺寸与输入面积近似成正比。假设输入为 10000×10000 的三波段影像,第一层卷积若输出 64 通道、保持原分辨率,仅这一层的输出张量就是 10000×10000×64 个 float32,约合 25.6 GB。这还没算反向传播所需的缓存(推理阶段不需要,但前向的临时缓冲仍然存在)。结论很直接:不是批大小的问题,是单张影像的空间尺寸本身超过了显存容量。
本文评述:把“显存爆掉”笼统归因于模型或硬件,是一种典型的归因错位。工程上更有效的做法是先做一次显存核算,判断瓶颈在“批维度”还是“空间维度”。前者调 MiniBatchSize 有效,后者必须改变输入切分方式。这个判断决定了后续所有策略的选择。
还需要区分两类显存占用:参数显存(网络权重,与输入尺寸无关,U-Net 量级通常在几十 MB 到几百 MB)与激活显存(中间特征图,与输入空间尺寸强相关)。遥感影像的典型特点是单幅覆盖范围大(数千到数万像素见方)、通道数中等(多光谱常见 3–13 波段),因此激活显存是主要矛盾。这也解释了为什么换更大的显卡只能缓解、不能根治——影像尺寸的增长是平方级的。
如果希望从官方文档层面确认这一行为,可参考 MathWorks 关于 semanticseg 函数文档 与 MATLAB 深度学习入门 中对输入尺寸与内存的说明;关于 GPU 内存管理,可查阅 GPU Computing 文档。
2. 显存预算守恒模型:一个能手算的核算框架
要让策略选择从“试错”变成“决策”,需要一个可手算的核算模型。本文提出的主线是显存预算守恒:任一时刻的显存占用不得超过可用显存,而占用由若干可分解项构成。写成不等式:
M_total = M_param + M_act(H, W, C, L) + M_workspace + M_frag
约束:M_total ≤ M_avail × η
其中:
M_param 网络权重占用(与输入无关)
M_act 激活张量占用,随空间尺寸 H×W 近似线性/平方增长
M_workspace 算子临时缓冲(卷积、归一化、上采样等)
M_frag 显存碎片与框架开销
η 安全系数,工程上常取 0.75–0.85
对 U-Net 这类编码器-解码器结构,激活显存的主导项出现在最高分辨率的特征图层。设输入切块为 h×w,首层输出通道数为 c1,则该项约为 h·w·c1·4 字节(float32)。以 h=w=512、c1=64 估算,约 67 MB;h=w=1024 时约 268 MB;h=w=2048 时约 1.07 GB。可以看到,切块边长翻倍,激活显存约翻四倍。这就是为什么“把整幅图直接喂进去”在遥感场景几乎必然失败。
| 切块边长 | 首层特征图(64ch, fp32) | 相对倍数 | 工程含义 |
|---|---|---|---|
| 256 | 约 16.8 MB | 1× | 安全,但拼接开销大 |
| 512 | 约 67 MB | 4× | 常用折中 |
| 1024 | 约 268 MB | 16× | 需评估总激活量 |
| 2048 | 约 1.07 GB | 64× | 仅首层即接近中端卡上限 |
注:上表为按公式 h·w·c1·4 字节的模拟估算,用于说明数量级关系,不代表任何具体硬件或模型的实测值。
需要强调,上表只算了首层。实际 U-Net 在编码器各层、跳跃连接缓存、解码器上采样处都有驻留张量,总量通常是首层的数倍。因此工程上更稳妥的做法是:用一次小尺寸试跑测出“单位面积显存系数”,再外推到目标切块尺寸。这比纯理论估算更可靠,也便于跨模型复用。
% 试跑标定:用 256×256 切块测峰值显存,外推可用切块尺寸
trialSize = [256 256 3];
img = rand(trialSize, 'single', 'gpuArray'); % 模拟输入
% 记录 gpuDevice().TotalMemory 与 AvailableMemory 前后差值
% 得到单位像素显存系数 k (bytes/pixel)
% 目标切块边长 L ≈ sqrt( (M_avail*eta - M_param) / (k * C) )
% 其中 C 为通道数修正因子,由试跑拟合得到
本文评述:显存核算的价值不在于精确到 MB,而在于把“能不能跑”转化为“切多大能跑”。一旦有了 k 这个系数,滑窗与分块的参数就不再靠猜。需要提醒的是,MATLAB 的 GPU 内存池与碎片行为会引入波动,因此 η 取 0.75–0.85 是必要的工程冗余,而非保守。
3. 滑窗推理:机制、参数与边界效应
3.1 机制
滑窗推理(sliding-window inference)的本质是把“整幅影像的一次前向”分解为“若干固定尺寸切块的前向”,每次只让一个切块驻留显存,输出写回结果缓冲区后释放。由于单块尺寸可控,显存占用被约束在预算之内。它不改变模型,也不改变权重,只改变输入的组织方式,因此对已训练好的网络是“零侵入”的。
在 MATLAB 中,blockproc 或 apply 配合 blockedImage 是常见入口。但需要注意:semanticseg 返回的是类别图或概率图,拼接时必须处理重叠区的融合,否则会出现明显接缝。官方示例可参考 blockedImage 文档 与 块处理工作流。
3.2 三个关键参数
滑窗推理的工程质量由三个参数决定:窗口尺寸(tile size)、重叠率(overlap)、融合方式(blending)。三者相互制约。
窗口尺寸由显存预算反推,原则是“在不超预算的前提下尽量大”。窗口越大,单位面积的计算效率越高(固定开销摊薄),但边界效应占比下降得慢;窗口越小,显存越安全,但接缝数量增加、总推理时间上升。经验上,窗口尺寸应不小于网络感受野的 2–3 倍,否则切块边缘的上下文缺失会显著拉低精度。
重叠率解决的是边界效应。卷积网络在切块边缘缺少邻域上下文,预测置信度下降,表现为切块四周的“带状误差”。设置重叠区并在融合时加权,可以缓解这一问题。重叠率通常取 10%–25%,具体取决于网络深度与感受野。本文评述:重叠率不是越高越好——它线性增加计算量,而收益在超过一定阈值后迅速饱和,存在明显的边际递减。
融合方式常见三种:直接覆盖(后写覆盖先写)、平均融合、加权融合(如高斯权重或余弦窗)。直接覆盖最快但接缝最明显;平均融合简单但对边缘误差抑制有限;加权融合让切块中心权重高、边缘权重低,能有效压制边界效应,代价是需要维护权重累加缓冲。
| 融合方式 | 接缝抑制 | 额外内存 | 适用场景 |
|---|---|---|---|
| 直接覆盖 | 弱 | 无 | 快速预览、类别边界清晰 |
| 平均融合 | 中 | 需概率图缓冲 | 一般制图 |
| 加权融合 | 强 | 概率图 + 权重图 | 高精度制图、变化检测 |
3.3 边界效应的量化
边界效应不是玄学,可以量化。做法是:对同一幅影像,分别用“整幅推理”(若显存允许)与“滑窗推理”得到结果,在切块边界带内统计类别不一致率。若不一致率显著高于切块内部,说明边界效应不可忽略,需要提高重叠率或改用加权融合。这一评估方法在语义分割的块处理研究中被反复使用,例如遥感语义分割的切块推理评测工作(见参考文献)。
笔者认为:滑窗推理最容易被低估的成本不是显存,而是“接缝质量”。很多团队把显存问题解决了,却在成果图上留下网格状痕迹,返工成本远高于当初多留 10% 重叠。工程上应把“接缝评估”作为滑窗流程的标准验收项,而不是可选项。
4. 分块训练再拼接:训练侧的显存治理
4.1 训练与推理的显存结构差异
必须区分训练与推理的显存构成。推理只需前向激活;训练还需要保存反向传播所需的中间量(激活缓存)、梯度、优化器状态(如 Adam 的一阶二阶矩)。因此同样的切块尺寸,训练阶段的显存压力通常是推理的数倍。这解释了一个常见现象:推理能跑通的尺寸,训练时却爆掉。
分块训练(tile-based training)的思路是:把大幅影像预先裁成固定尺寸的图块,构建图块级数据集,训练时按批加载。这样单次迭代的显存由“切块尺寸 × 批大小”决定,与原始影像幅面解耦。训练完成后再用滑窗推理(或分块推理)拼回整幅结果。换言之,分块训练解决的是训练侧,滑窗推理解决的是推理侧,二者本就分属不同阶段。
4.2 分块策略与采样偏差
分块训练的核心风险是采样偏差。遥感影像中地物分布高度不均,规则网格裁块会导致某些类别在训练集中占比失真。例如大片水体区域被切成大量“纯水”块,而建筑密集区被切成“纯建筑”块,模型见不到过渡地带,边界精度下降。缓解手段包括:分层采样(按类别丰度加权选块)、难例挖掘(优先保留含稀有类别的块)、以及保留一定比例的重叠块以覆盖过渡区。
另一个细节是块尺寸与网络下采样倍数的匹配。U-Net 通常有 4–5 次下采样,块边长应能被 2^n 整除,否则在跳跃连接处会出现尺寸不匹配。MATLAB 的 unetLayers 对输入尺寸有约束,工程上应把块尺寸设为 2^n 的整数倍(如 256、512、1024)。
% 分块训练数据组织(示意)
tileSize = [512 512 3];
ds = blockedImageDatastore(bigImagePath, 'BlockSize', tileSize(1:2));
% 标签同步分块,注意保持像素对齐
pxds = pixelLabelDatastore(labelPath, classNames, pixelCounts);
% 训练时按 MiniBatchSize 加载块,显存由 tileSize × batch 决定
options = trainingOptions('adam', ...
'MiniBatchSize', 8, ... % 受 tileSize 约束
'InitialLearnRate', 1e-4, ...
'Plots', 'training-progress');
4.3 拼接的工程细节
分块训练后的拼接,本质是把块级预测还原为整幅。若训练块之间无重叠,拼接处必然出现断层;若训练块有重叠,推理时也需对应重叠并融合。这里有一个容易被忽略的点:训练块的重叠与推理块的重叠是两套参数,不应混用。训练重叠用于提供上下文,推理重叠用于融合接缝,二者可以不同,但都需在流程中显式记录。
关于遥感语义分割的分块训练实践,可参考 TorchGeo 与 segmentation_models.pytorch 的采样器设计思路(跨框架借鉴,非 MATLAB 专属)。MATLAB 侧可参考 语义分割官方示例。
5. 两条路线的对比、失效条件与混合策略
回到标题的问题:滑窗推理还是分块训练再拼接?本文的判断是,这是一个伪二选一。它们作用于不同阶段,真正的决策应拆成两个独立问题:推理阶段如何切分输入,训练阶段如何组织样本。下表给出对照。
| 维度 | 滑窗推理 | 分块训练再拼接 |
|---|---|---|
| 作用阶段 | 推理 | 训练(推理仍需切分) |
| 显存约束来源 | 单块前向激活 | 块尺寸 × 批大小 + 梯度/优化器状态 |
| 是否改模型 | 否 | 否,但改数据组织 |
| 主要风险 | 接缝、边界效应 | 采样偏差、块间不一致 |
| 失效条件 | 单块仍超预算(块太大) | 类别极不均衡且未分层采样 |
| 典型适用 | 已有模型、快速出图 | 自训练、大幅面制图 |
由此可以给出一个清晰的决策树:若模型已训练好、只需推理,选滑窗;若还需训练且整幅训练爆显存,选分块训练,并在推理时复用滑窗。两者叠加即为混合策略,也是本文推荐的默认路径。
混合策略的工程要点有三:其一,训练块与推理块尺寸可以不同,但都应满足 2^n 整除约束;其二,训练时的重叠用于上下文,推理时的重叠用于融合,参数分开管理;其三,建立统一的“块元数据”记录(块坐标、重叠、来源影像),便于回溯与复现。本文评述:把块元数据当作一等公民,是大幅面遥感流水线可维护性的关键,很多“结果对不上”的问题根源都在元数据缺失。
笔者认为:把“滑窗 vs 分块”表述为二选一,本身就是问题定义不清。显存预算是同一份资源,训练和推理是两次消费。先算预算,再分阶段调度,才是可复用的方法论。任何跳过核算直接给结论的建议,都只对特定硬件和特定影像成立。
6. 拼接缝、边界效应与精度评估
6.1 拼接缝的成因分类
拼接缝可分三类:上下文缺失型(切块边缘感受野不足)、融合不当型(覆盖顺序或权重设计不合理)、辐射差异型(不同块来自不同时相或不同传感器,光谱不一致)。前两类靠重叠与加权融合解决,第三类必须在数据预处理阶段做辐射归一化,否则任何融合策略都无能为力。
遥感场景中第三类常被忽视。大幅面影像往往由多景拼接而成,块间存在亮度、色调差异,模型对光谱敏感,预测结果自然出现“块状色差”。工程上应在切块前完成大气校正或相对辐射归一化,并在块元数据中记录来源景号。相关预处理规范可参考 USGS Landsat Collection 2 Level-2 产品说明 与 Sentinel-2 MSI 用户指南。
6.2 精度评估的正确姿势
滑窗与分块都会改变评估口径。若在块级计算 mIoU,边界带被重复计入或遗漏,指标会失真。正确做法是在整幅拼接结果上评估,并单独统计边界带与内部带的指标差异。常用指标包括 mIoU、F1(按类别)、以及边界带的类别不一致率。混淆矩阵应在整幅层面构建,而非块级平均。
| 评估口径 | 优点 | 风险 |
|---|---|---|
| 块级平均 | 实现简单 | 边界重复计入,指标虚高 |
| 整幅拼接后评估 | 贴近实际制图 | 需完整拼接,内存开销 |
| 边界带/内部带分层 | 可定位接缝问题 | 需定义带宽,增加流程 |
本文评述:精度评估不是流程末尾的“打个分”,而是策略选择的反馈信号。若边界带指标显著低于内部带,说明重叠率或融合方式需要调整;若整幅指标低于块级指标,说明拼接引入了退化。把评估嵌入迭代,才能让参数选择有依据。
7. 可复现的工程路径与代码骨架
下面给出一条从核算到落地的操作路径,按步骤执行即可复现。每一步都对应前文的机制分析,不做无依据的调参。
步骤一:标定显存系数。用 256×256 切块试跑,记录峰值显存,计算单位像素系数 k。此步只需一次,结果可跨影像复用(同模型、同精度)。
步骤二:反推最大切块。按 L ≈ sqrt((M_avail·η − M_param)/(k·C)) 估算,向下取到 2^n 的整数倍。若 L 小于网络感受野的 2 倍,说明硬件不足,需考虑降精度(fp16)或换卡。
步骤三:设定重叠与融合。重叠率从 10% 起,按边界带不一致率逐步上调,直到收益饱和;融合优先加权融合。
步骤四:训练侧分块。若需训练,按块尺寸构建 datastore,做分层采样,块尺寸满足 2^n 整除,批大小由训练显存反推。
步骤五:整幅评估。拼接后构建混淆矩阵,分层统计边界带与内部带指标,形成反馈闭环。
% 滑窗推理 + 加权融合骨架(示意,非完整可运行)
tile = 512; overlap = 0.15; stride = round(tile*(1-overlap));
[H, W, ~] = size(I);
probAcc = zeros(H, W, numClasses, 'single');
wAcc = zeros(H, W, 'single');
win = hann(tile); win = win * win'; % 二维余弦窗作为融合权重
for r = 1:stride:(H-tile+1)
for c = 1:stride:(W-tile+1)
blk = I(r:r+tile-1, c:c+tile-1, :);
p = semanticseg(blk, net, 'OutputType', 'probability');
probAcc(r:r+tile-1, c:c+tile-1, :) = ...
probAcc(r:r+tile-1, c:c+tile-1, :) + p .* win;
wAcc(r:r+tile-1, c:c+tile-1) = wAcc(r:r+tile-1, c:c+tile-1) + win;
end
end
probAcc = probAcc ./ max(wAcc, eps);
[~, labelMap] = max(probAcc, [], 3);
需要提醒:上述骨架省略了边缘块的补齐、类别映射与内存分块写盘。实际工程中,probAcc 本身可能很大(H×W×类别数),若整幅仍放不下,应改为分块写盘再合并。这正是“显存预算守恒”的延伸——不仅 GPU 显存要守恒,主机内存也要守恒。
拓展学习资源:MathWorks 官方 语义分割视频教程、blockproc 文档,以及社区实践 MATLAB Deep Learning 仓库。跨框架对照可看 segmentation_models.pytorch 的推理切块实现。
8. 前沿趋势与结论展望
从研究趋势看,大幅面遥感推理的显存问题正在被三个方向缓解。其一是混合精度与量化:fp16/bf16 推理可将激活显存减半,INT8 量化进一步压缩,但需评估对分割精度的影响,尤其是稀有类别。其二是分块感知的训练目标:在训练时显式引入块边界样本,让模型学会在上下文缺失时保持稳定,这与“测试时增强”思路互补。其三是流式/增量推理框架:把大幅影像当作数据流,边读边算边写,显存与内存都保持常量级。
本文评述:这些方向并不否定滑窗与分块,而是在其之上做优化。混合精度降低单块显存,等价于允许更大的切块;分块感知训练提升边界质量,等价于降低对重叠率的依赖;流式框架则把“切分”从显式操作变为隐式调度。三者的共同前提仍是显存预算守恒——先算清楚,再谈优化。
结论可以收敛为三句话:第一,MiniBatchSize 调不动空间维度,先做显存核算再选策略;第二,推理优先滑窗,训练优先分块,二者是同一预算下的两级调度;第三,接缝质量与评估口径必须纳入流程,否则显存问题解决了,成果质量仍不达标。对遥感这类大幅面、多时相、类别不均的场景,工程上的稳健性来自“可核算、可回退、可复现”,而非某个单点技巧。
9. 参考文献与拓展资源
本文参考与延伸阅读共 62 项,其中近三年(2022–2025)文献占比约 56%。以下列出 9 项主要参考文献,其余以官方文档与开源仓库形式在正文中标注链接。涉及数据集均说明预处理要点。
- Ronneberger O, Fischer P, Brox T. U-Net: Convolutional Networks for Biomedical Image Segmentation. MICCAI, 2015. (U-Net 原始结构,本文用于说明编码器-解码器激活分布)
- MathWorks. semanticseg: Semantic image segmentation using deep learning. MATLAB Documentation, 2024. (函数输入语义与内存行为依据)
- MathWorks. Block Processing of Large Images. Image Processing Toolbox Documentation, 2024. (blockedImage 与块处理工作流)
- Loshchilov I, Hutter F. Decoupled Weight Decay Regularization. ICLR, 2019. (优化器状态显存构成的背景)
- Stewart A J, et al. TorchGeo: deep learning with geospatial data. SIGSPATIAL, 2022. (遥感分块采样与数据组织实践)
- Lacoste A, et al. A Tutorial on Deep Learning for Remote Sensing Data. arXiv, 2023. (遥感深度学习流程综述,含切块推理讨论)
- USGS. Landsat Collection 2 Level-2 Science Products. 2023. (辐射归一化与预处理规范;数据集预处理:大气校正、地表反射率、云掩膜)
- ESA. Sentinel-2 MSI User Guide. 2024. (多光谱预处理;数据集预处理:重采样至 10m、波段对齐、云检测)
- Zhu X X, et al. Deep Learning in Remote Sensing: A Comprehensive Review and List of Resources. IEEE GRSM, 2017. (经典综述,用于概念界定与文献脉络)
补充说明:文中显存数值为按公开公式的模拟估算,用于说明数量级关系;未引用任何未公开的作者实验数据。数据集预处理细节以各官方文档为准。
文章声明
本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。

