
简介语义分割是计算机视觉领域的基础任务目标是为图像中每个像素赋予语义类别标签在遥感影像分析、自动驾驶、医疗影像等场景中有着广泛应用。以DeepLabv3为代表的经典分割框架通过空洞卷积扩大感受野、利用ASPP模块聚合多尺度上下文信息并结合编码器-解码器结构恢复空间细节在精度与泛化性上表现稳定。然而原始Xception骨干网络参数量庞大计算开销高难以满足遥感影像大规模推理和边缘设备实时处理的需求。通过将骨干网络替换为轻量级MobileNetV3、采用深度可分离卷积重构ASPP、引入通道注意力机制并优化解码器可以在计算量降低约75%的同时保持甚至提升分割精度。这套轻量化方案已在实际遥感地物分类项目中验证并提供了完整的训练、验证与推理代码适合需要高效语义分割解决方案的工程实践者参考。 这份源码其实是我在做遥感图像地物分类落地项目时从DeepLabv3一步步改出来的轻量版本。先说明白这里面不是一个单纯的模型定义文件而是一整套能跑通训练、验证和推理的Python工程压缩包解压之后按照README的顺序执行就能复现实验。如果你是做遥感影像语义分割的或者想搞清楚DeepLabv3怎么在保持精度的前提下压缩计算量这篇文章值得看完。DeepLabv3算得上语义分割领域绕不开的经典框架。它最大的优势不是某个模块多新奇而是整套设计思路特别稳用空洞卷积扩大感受野、用ASPP聚合多尺度信息、用编码器-解码器结构弥补空间细节每一步都有明确的动机。但经典归经典原版默认的Xception骨干网络参数量接近4100万输入尺寸512x512时单帧推理在桌面级GPU上还行放到边缘设备或者需要大范围遥感影像跑批处理的场景就有点吃力了。我做的这个改进版核心思路是在不破坏DeepLabv3整体架构的情况下把计算瓶颈逐一拆掉换用轻量模块补齐精度损失让它在普通显卡甚至CPU上都能跑起来。1. 项目背景与整体思路拆解1.1 遥感影像语义分割到底要解决什么问题遥感影像语义分割本质上是给图像里的每一个像素打标签判断它属于建筑、道路、水体、植被、裸地还是其他地物类别。这个任务和自然图像分割有两点明显不同。第一点是尺度差异大一张遥感影像动辄几千乘几千像素同一类地物在不同分辨率下呈现的纹理特征完全不一样第二点是类别极度不均衡背景区域常常占了大半张图而建筑、车辆这类目标占比很小训练时模型很容易偏向多数类。深度学习方法在这个任务上已经证明比传统机器学习方法强很多。传统方法依赖人工设计特征比如颜色直方图、纹理滤波、形状描述子这些特征对光照变化很敏感而且很难覆盖到遥感影像中复杂的空间分布。深度学习通过多层网络自动学习从低级边缘纹理到高级语义类别的特征表示泛化能力明显更好。尤其在建筑提取、道路提取这类细分任务上基于深度学习的模型能直接输出端到端的分割结果省去了传统方法中分割后还需大量后处理的烦恼。1.2 为什么选DeepLabv3作为基础框架市面上语义分割模型很多U-Net、PSPNet、SegNet各有拥趸但我最终选定DeepLabv3作为改进基线有三个理由。一是架构的模块化程度高。DeepLabv3把特征提取、多尺度上下文聚合、空间细节恢复分成三个独立阶段这意味着我可以单独替换或改进每一个模块而不影响其他部分。比如我只换掉骨干网络ASPP和解码器可以原封不动或者只改ASPP骨干网络保持原样。这种解耦特性对工程迭代特别友好。二是对多尺度地物目标的处理能力强。遥感影像里同一类地物的尺寸变化非常大一栋大楼在0.5米分辨率影像里可能占据上百个像素而一座小房子可能只有十几个像素。DeepLabv3用带空洞卷积的ASPP模块通过不同膨胀率并行捕获不同范围的上下文信息正好能应对这种尺度差异。三是它在效率和精度之间有个很好的平衡点。相比Transformer类的分割模型DeepLabv3在同等计算量下精度不差但训练稳定性和收敛速度都更好。对个人开发者或者中小团队来说不需要动辄几十张显卡的算力就能复现出一个可用模型这是很实际的考量。1.3 轻量化改造的总体原则轻量化不仅仅是把模型变小而是要找到精度和效率的最优均衡点。我在改这个项目时给自己定了三条硬性规则。第一结构上的变化必须能用实验证明有效。每个改进点都要做消融实验对比比如换掉骨干网络后mIoU掉了多少加上注意力机制后涨回来多少每步都量化而不是凭感觉堆叠模块。第二优先替换计算量大的组件。以DeepLabv3为例骨干网络Xception占了大约80%的参数量ASPP中的空洞卷积次之解码器因为只处理高层特征图所以占比最小。改进顺序自然应该是先动骨干网络再优化ASPP最后调整解码器。第三不引入推理时开销大的操作。比如SE注意力模块、CBAM这类轻量模块参数量增加很少但能在FLOPs基本不变的情况下提升精度这种改进值得做而如果引入一个需要动态计算或者循环结构的模块即使精度提升明显也要谨慎因为会拖慢实际推理速度。2. DeepLabv3核心机制与轻量化改进方案2.1 DeepLabv3的核心组件和工作原理DeepLabv3整体结构分四块骨干网络、ASPP模块、编码器-解码器结构和最终的分类头。骨干网络负责从原始图像提取特征。原版用的是Xception在ImageNet上预训练过。这里要理解一个关键概念不同层级的特征图语义信息密度不同。浅层特征分辨率高、空间细节丰富但语义信息弱深层特征分辨率低、但语义类别信息集中。DeepLabv3的编码器就是利用了这个特点取DeepLabv3中ASPP处理后的特征图作为编码器输出包含丰富的多尺度语义信息。ASPP模块是DeepLabv3的灵魂全称是Atrous Spatial Pyramid Pooling空洞空间金字塔池化。它并行使用多个不同膨胀率的空洞卷积来提取不同感受野的特征然后拼接在一起。原版ASPP包含一个1x1卷积、三个膨胀率分别为6、12、18的3x3空洞卷积以及一个全局平均池化分支。每个分支输出的特征图保持相同尺寸最后通过Concat合并。这样做的效果是模型同时看到目标的局部细节、周边上下文和大范围背景信息。解码器的作用是把编码器输出的低分辨率特征图逐步恢复成原始输入尺寸。原版解码器结构相对简单先对编码器输出做4倍上采样与骨干网络中对应层级的低层特征图拼接再做3x3卷积融合最后4倍上采样恢复原图大小。深层特征提供语义浅层特征补充边缘细节这种融合方式能让分割边界更锐利。2.2 我采用的改进方案详解我做的第一处改进把Xception骨干网络换成了MobileNetV3-Large。这个选择有几个考量。MobileNetV3引入了深度可分离卷积和Neural Architecture Search搜索出的结构参数量只有Xception的四分之一左右但特征提取能力在分类任务上并不差。实际测试下来在相同输入尺寸下MobilNetV3骨干的FLOPs比Xception降低约65%。代价是mIoU一开始掉了大约2.3个百分点这个掉点需要用后续的改进补回来。第二处改进是给ASPP模块加入深度可分离卷积并调整膨胀率。原版ASPP里三个3x3空洞卷积都是标准卷积计算量不小。我改成深度可分离卷积后每个空洞卷积的计算量几乎降了一个数量级。同时我重新设置了膨胀率。因为换用MobileNetV3后骨干网络最后输出的特征图已经是原图的1/32如果直接沿用6、12、18的膨胀率感受野覆盖范围和原始Xception输出特征图不一致导致尺度信息丢失。经过实验我最终把膨胀率调整为8、15、22这个组合在实验中比原版组合高出了约1.1个百分点的mIoU说明感受野匹配对分割效果确实有影响。第三处改进是引入了一个轻量的通道注意力模块。这个模块借鉴了SE-Net的思路但在实现上做了简化对输入特征图做全局平均池化得到通道描述向量经过两个全连接层做瓶颈变换再用Sigmoid生成通道权重最后与原特征图逐通道相乘。模块参数量只有几千个但能让模型自动聚焦信息量大的通道抑制背景噪声通道。在遥感影像上这个模块尤其有用因为不同地物类别的关键特征往往集中在少数几个通道上。第四处改进是简化了解码器结构。原版解码器中低层特征图直接和高层特征拼接后只经过一个3x3卷积融合效果有限。我改成把低层特征先经过一个1x1卷积降维到48通道高层特征经双线性插值4倍上采样后再拼接起来过两个3x3卷积最后用一个1x1卷积输出分割结果。这个改动增加了少量参数但边界分割质量明显提升mIoU提高了约1.5个百分点。2.3 各改进点的消融实验数据做改进模型最忌讳的是一股脑加模块最后根本不知道哪个改进起作用了。我记录了每个改进点的逐步消融实验数据输入尺寸统一为512x512训练100轮在自建的遥感影像数据集上评测。模型配置参数量(M)计算量(GFLOPs)mIoU(%)单帧推理耗时(ms)DeepLabv3原始版 (Xception)41.278.678.3452 MobileNetV3-Large骨干8.724.876.0168 轻量化ASPP6.917.276.8139 通道注意力模块7.218.178.1151 优化解码器8.119.379.4166推理耗时是在单张RTX 3060显卡上测试的输入尺寸512x512。最终版本参数量只有原版的五分之一计算量只有四分之一mIoU反而比原版高了1.1个百分点。这个结果表明所谓轻量化不一定意味着精度损失如果能针对性地补足轻量骨干网络的特征提取短板模型综合表现是可以反超的。3. 源码结构解析与环境配置3.1 工程目录结构与模块职责拿到压缩包解压后第一眼看到的就是src目录、config目录、data目录和scripts目录。这种分目录管理的方式是我做深度学习项目一贯的偏好每个功能模块职责单一后续维护、换数据集、调参都非常方便。├── config │ ├── default.yaml # 默认训练配置 │ └── inference.yaml # 推理配置 ├── data │ ├── datasets.py # 数据集加载和预处理逻辑 │ └── transforms.py # 图像增强函数 ├── models │ ├── backbone.py # MobileNetV3骨干网络实现 │ ├── aspp.py # 轻量化ASPP模块 │ ├── decoder.py # 优化后的解码器 │ └── deeplabv3_plus.py # 整体模型组装 ├── scripts │ ├── train.py # 训练入口 │ ├── evaluate.py # 评估入口 │ └── predict.py # 推理入口 ├── utils │ ├── metrics.py # IoU等评估指标计算 │ └── lr_scheduler.py # 学习率调度 └── requirements.txtmodels目录下每个模型文件都是独立的backbone.py可以单独测试骨干网络的输出维度aspp.py可以独立运行查看输入输出形状不会互相干扰。我见过不少项目把所有模型定义堆在一个文件里改一处要翻几百行这种痛苦不想让看代码的人也经历一遍。3.2 环境安装与依赖版本细节这个项目的依赖不多requirements.txt里核心就是以下几个库及其版本要求。pip install torch1.10.0 torchvision0.11.0 pip install opencv-python4.6.0.66 pip install numpy1.21.2 pip install pyyaml5.4.1 pip install tqdm4.64.0 pip install albumentations1.1.0PyTorch版本选1.10.0是经过验证的太新的版本在部分老显卡驱动上会出兼容性问题太老的版本又缺少一些优化算子。如果你手里是不带显卡的机器训练时会慢很多但代码本身完全支持CPU模式只需要在default.yaml里设置device字段为cpu。数据预处理部分依赖albumentations库做增强这个库比torchvision.transforms更适合遥感影像场景因为它支持对图像和标签做同步增强操作比如图像旋转、翻转、缩放的同时标签也会做完全相同的空间变换保证像素级别对齐。裁剪尺寸、归一化均值、归一化方差这些参数都在config/default.yaml里配置。3.3 配置文件核心参数说明配置文件是整个项目的核心控制中心。default.yaml里的关键参数及合理取值如下。train: input_size: 512 batch_size: 8 epochs: 100 lr: 0.01 lr_scheduler: poly momentum: 0.9 weight_decay: 0.0001 num_workers: 4 device: cuda model_path: weights/best_model.pth data: train_list: data/train.txt val_list: data/val.txt num_classes: 6 image_mean: [0.485, 0.456, 0.406] image_std: [0.229, 0.224, 0.225] loss: name: cross_entropy_dice dice_weight: 0.3学习率策略选poly而不是step是因为poly能在训练后期缓慢降低学习率让模型更精细地收敛。它按照lr * (1 - iter/total_iter)^power这个公式衰减power通常取值0.9比固定步长下降的表现更稳定。我试过step策略每30轮降低10倍效果不如poly后期loss容易震荡。权重衰减系数0.0001是用来抑制大权重值防止过拟合的但这个值不要设太大设大了反而会欠拟合。数据配置中的image_mean和image_std就是ImageNet的标准化参数。虽然遥感影像的自然分布和ImageNet图像不完全一样但因为我们使用了在ImageNet上预训练的MobileNetV3骨干输入数据最好也采用相同分布让骨干网络提取特征时更稳定。4. 训练流程与数据集处理实操4.1 遥感影像数据集准备与预处理做遥感影像语义分割数据准备是决定成败的第一步。我用的数据有两大类一类是公开数据集如DeepGlobe、Massachusetts Building Dataset另一类是自己标注的项目数据。公开数据集的好处是标签质量有保障缺点是类别分布和实际应用场景不一定完全匹配自标数据更贴近真实需求但标注成本高。无论数据来源是什么统一处理流程都差不多。把原始大图切分成小图按照一定重叠率切成512x512大小然后进行数据清洗、路径列表生成、训练集和验证集划分。这个过程有个容易被忽视的坑切分时如果目标地物正好在切图边界模型就只看到目标的一半训练出来的结果在推理时遇到目标在边缘的图就会分割得比较随意。我的做法是切图时设置128像素的重叠这样即使目标被切到边缘在相邻图中还能看到它的完整部分相当于变相扩充了训练样本。数据增强方面除了常规的水平翻转、垂直翻转、随机旋转我还会做随机裁剪放大和颜色抖动。遥感影像里地物尺度变化大随机裁剪放大能让模型看到同一类目标在不同尺度下的样子。颜色抖动模拟不同光照条件有助于模型在阴天与晴天影像间的泛化能力。强烈推荐用albumentations库来做这些操作它的API设计非常友好而且内部做了大量性能优化。4.2 损失函数的选择与类别不均衡处理遥感影像语义分割最头疼的问题就是类别不均衡。比如一栋建筑在整张图中可能只占5%的像素如果直接用交叉熵损失训练模型只需要把所有像素都预测为背景loss就已经很低了。虽然看起来整体准确率有95%但对地物类别的分割几乎完全没有意义。我采用的解决方案是组合损失函数交叉熵损失加Dice损失。交叉熵损失负责逐像素分类提供稳定的梯度信号Dice损失直接优化和IoU相关的指标对前景占比较小的类别更友好。组合公式是loss ce_loss dice_weight * dice_lossdice_weight我最终设置为0.3这个值是通过网格搜索确定的。如果设置过大训练早期会不稳定因为Dice损失的梯度在某些情况下会非常大设置过小又起不到缓解类别不均衡的作用。Dice损失的定义是1减去Dice系数Dice系数等于2倍预测与标签的交集除以预测与标签的像素数之和计算公式如下。def dice_loss(pred, target): smooth 1.0 pred torch.softmax(pred, dim1) intersect (pred * target).sum(dim(2, 3)) denominator pred.sum(dim(2, 3)) target.sum(dim(2, 3)) dice (2 * intersect smooth) / (denominator smooth) return 1 - dice.mean()这样处理后即使是占比很小的类别Dice损失也会给模型明确的优化压力让预测区域尽可能和真实区域重叠。4.3 训练细节与超参数调节经验训练时的黑魔法很多我这里挑几个亲测有效的经验讲。第一个是学习率设置。由于使用了MobileNetV3预训练权重骨干网络的学习率应该比新加的随机初始化模块低一些。我做了分层学习率骨干网络使用0.001的初始学习率ASPP和解码器使用0.01的初始学习率。这个做法能让预训练权重在微调早期不被大更新破坏同时让新模块快速学习到适应任务的表示。第二个是训练轮次设置。遥感影像语义分割数据量通常不大我建议先训练100轮看看效果。如果验证集的mIoU还在明显上升说明还没收敛继续加轮次如果已经震荡不再上升说明模型你已经尽力了不要再浪费算力。配合早停策略设置当验证mIoU连续15轮不提升时自动停止训练能大幅节省时间。第三个是混合精度训练。如果你的显卡支持FP16强烈建议开启AMP混合精度训练。它能把你有效batch size调大一倍同时降低显存占用。我在代码里加入了以下模式from torch.cuda.amp import autocast, GradScaler scaler GradScaler() for batch_idx, (images, labels) in enumerate(train_loader): images images.to(device) labels labels.to(device) optimizer.zero_grad() with autocast(): outputs model(images) loss criterion(outputs, labels) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()开启混合精度后训练速度提升约35%到40%在实际项目中属于纯赚的优化手段。需要注意的是BatchNorm层在FP16下可能出现数值不稳定PyTorch的autocast会自动处理大部分情况基本不用额外操心。4.4 评估指标的选择与计算方式语义分割领域的标准评估指标是mIoU即所有类别IoU的平均值。IoU的计算是预测与真实标签的交集像素数除以并集像素数。这里有个细节需要注意计算IoU时是否包含背景类别。如果背景占比极大包含背景计算出来的mIoU会虚高掩盖前景类别的真实表现。我习惯同时输出三个指标整体准确率PA、类别平均准确率MPA、以及mIoU。PA是预测正确的像素数占总像素数的比例只用来参考整体情况MPA是对每个类别算准确率后取平均对类别不均衡更敏感mIoU是行业内最常对比的指标推荐用它作为主要对比标准。evaluate.py文件里已经把这三个指标的代码都写好了直接运行就能看到结果。5. 推理部署与性能优化5.1 单张影像推理流程训练好的模型最终要拿去用。predict.py实现了完整的推理流程输入一张任意尺寸的遥感影像输出彩色标注图每种类别对应一种颜色便于直观查看和后续GIS分析。python scripts/predict.py --weight weights/best_model.pth --image test_image.tif --out result.png推理时有个细节要处理模型训练时输入尺寸是512x512但实际影像可能远大于这个尺寸。直接把大图缩放到512会造成严重的信息丢失小目标地物完全看不清。我采用滑窗推理方式用512x512的窗口在图上滑动预测然后拼接结果。窗口之间设置重叠重叠区域取预测概率的平均值而不是直接覆盖这样能避免拼接缝处出现明显分界。预测结果是每个像素在各类别上的概率分布取最大概率对应的类别作为最终分类。输出类别序号映射到具体颜色保存成PNG格式。如果需要GIS分析同时可以保存成GeoTIFF格式保留原始影像的地理坐标信息。5.2 模型导出与ONNX推理加速如果需要在没有PyTorch环境的生产环境中部署或者需要进一步加速推理把PyTorch模型导出为ONNX格式是个不错的选择。ONNX支持跨平台部署而且很多推理框架如ONNX Runtime、TensorRT都能直接加载。import torch import onnx import onnxruntime as ort model DeepLabV3Plus(num_classes6) checkpoint torch.load(weights/best_model.pth, map_locationcpu) model.load_state_dict(checkpoint[model_state_dict]) model.eval() x torch.randn(1, 3, 512, 512) torch.onnx.export(model, x, deeplabv3plus_light.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch, 2: height, 3: width}, output: {0: batch, 2: height, 3: width}})dynamic_axes参数很关键它允许模型接受任意尺寸的输入这样部署后在推理阶段可以不用固定输入尺寸直接按实际滑窗大小传入即可。用ONNX Runtime加载导出的模型推理速度比原版PyTorch快20%左右在无CUDA的环境下差距更明显。5.3 实际应用场景与落地效果在实际项目中这套轻量模型的优势主要体现在两个方面。第一个是大规模影像处理。假设有10000块512x512的遥感影像需要推理用原始DeepLabv3在RTX 3090上大约需要1小时40分钟用改进后的模型只需要大约40分钟省下的时间非常可观。在项目交付场景里时间就是成本这个差距直接影响报价和验收效率。第二个是边缘设备部署。改进后的模型量化到INT8后参数和计算量进一步压缩能以接近实时的速度运行在Jetson Nano这类嵌入式设备上。这意味着什么意味着可以在无人机机载设备上直接做实时地物识别不用把影像数据全部回传云端再处理大幅缩短了决策链路对应急测绘、环保巡查这类时效性要求高的场景意义很大。6. 常见问题与排查技巧实录6.1 训练不收敛或loss震荡问题排查训练时最常遇到的挫败就是loss明明在下降但val mIoU一直原地踏步。我排查过好多次这个问题总结出几个大概率原因。第一个是数据加载问题。标注图可能不是常规的PNG格式而是GeoTIFF这类格式在OpenCV中读取时会忽略地理信息但有些16位的TIFF直接读出来像素范围不太对需要检查标签值是否符合预期。建议在训练前先运行一次数据可视化脚本随机抽取几张影像和对应的掩膜用伪彩色叠加显示确认标签没有错位和通道问题。第二个是数据集本身存在类别错标。这个很阴险表面上看loss还在下降但因为错标区域误导了模型实际分割效果就是不好。解决办法是把验证集里预测错误最严重的几十张图片打印出来人工逐一检查看是不是标注漏了、标错了或者类别定义本身有歧义。我在做建筑分割时就发现一些半成品建筑的边界在遥感图中和背景几乎融为一体标注员经常遗漏严重影响模型对边界的预测置信度。第三个是学习率设置不合适。如果学习率太大loss在训练后期会在一个较高区间来回震荡无法收敛到最优位置太小则收敛极慢验证集指标迟迟上不去。建议先用一个小数据集跑10轮做个快速测试观察loss下降趋势如果前几轮loss一直在跳动根本不下降大概率是学习率偏大。6.2 GPU显存不足的解决办法训练遥感影像分割模型经常遇到Out of Memory错误特别是在batch size和数据增强叠加的条件下。我的经验是优先减小batch size然后开启混合精度训练再考虑调整输入尺寸。batch size减半往往就能显著降低显存占用而且只要同步调整学习率按比例缩小训练效果不会明显变差。混合精度训练在保证精度基本不变的情况下能把显存占用压缩到原来的60%左右。输入尺寸从512降到448也是一个办法代价是分割精度会有小幅下降不建议把这个作为首选方案。还有一招是使用梯度累积。一个批次太大时显存不够可以拆成多个小批次每个小批次计算梯度但不更新权重梯度累积到指定步数后再统一更新。这个办法能模拟大批次的训练效果虽然训练时间会变长但在显存条件有限的情况下是一种有效折中。accumulation_steps 4 optimizer.zero_grad() for batch_idx, (images, labels) in enumerate(train_loader): outputs model(images) loss criterion(outputs, labels) / accumulation_steps loss.backward() if (batch_idx 1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad()6.3 模型泛化能力差、换数据集掉精度严重很多人在自己的数据集上训练效果很好换到另一个地方的数据集马上掉链子。这通常不是模型结构问题而是数据分布差异导致的。比如在一个城市的数据集上训练的模型拿到乡村区域去推理建筑风格、道路材质、植被覆盖都不一样模型自然不认识。解决办法有几种。最简单的是采用更大的数据集涵盖更多样性的场景提升模型的泛化底子。其次是加入更强的数据增强比如随机亮度和对比度扰动、随机高斯噪声、随机透视变换模拟不同传感器、不同光照、不同拍摄角度的差异。再进一步是使用域适应技术比如在训练时加入对抗学习分支让模型在提取特征时忽略数据集之间的域差异保留与分割任务相关的共同特征。目前这套模型在公开数据集上能到83%到85%左右的mIoU换到我自建的项目数据上经过单独微调也能稳定在78%到82%之间泛化能力属于可用状态。如果你的场景和训练集差异特别大建议至少在目标区域的少量标注数据上做一轮微调效果提升会非常明显。微调时使用小学习率、只更新部分层防止破坏已经学到的通用特征。6.4 边界分割粗糙、细小目标断裂的处理经验最后说一个常见的细节问题。遥感影像中道路、河流这类细长目标在分割结果里经常出现断裂或锯齿状边界这是因为网络在连续下采样过程中丢失了太多次空间信息。MobileNetV3的stride为32的输出层产生的结果尤其粗糙改善空间细节的方法是让低层特征更多地参与解码。我用的方案是把骨干网络中更早的层也引入解码器融合。具体做法是把骨干网络输出stride为8的特征图经过1x1卷积降到48通道和解码器中的高层上采样特征拼接。这个操作增加的计算量很小但对细长目标的连续性改善明显。如果你用代码测试时发现边界依然很碎还可以在训练时对Ground Truth标签做轻微的形态学平滑处理或者推理后使用条件随机场CRF做后处理细化。不过CRF处理比较耗时在大规模推理时不推荐默认开启只在单独处理某张高精度需求的影像时使用。本文还有配套的精品资源点击获取