每年汛期一过,做地质灾害的人就开始盯着一堆遥感影像发愁。山坡上一块一块找滑坡,找到之后还要手动画边界、标范围、核对前后期影像,熟练的作业员一天能处理几十平方公里已经算快手。可一场暴雨下来,隐患点经常是几十上百个,这个工作量根本不是纯人工能扛住的。
成都理工大学这个 SCDUNet++ 项目,做的事情说白了就一句话:把“人眼在影像里找滑坡”变成“模型逐像素自动圈出滑坡范围”。这套思路属于遥感语义分割的范畴,模型整体是在 U-Net++ 的基础上改出来的,名字里的 SC 我理解大概率是空间与通道注意力相关模块的缩写,D 代表 Dense,也就是引入了密集连接。再配合迁移学习解决滑坡样本少、标注贵的问题。这篇文章我就从模型结构、迁移学习方案、数据工程到训练调参,完整复盘一遍这类滑坡测绘项目的落地逻辑,给同样在做遥感分割、灾害识别方向的同学当个参考。
1. 先把场景讲清楚:滑坡测绘为什么需要专门的深度学习模型
1.1 人工解译的瓶颈在哪
传统滑坡测绘基本靠遥感影像目视解译。作业员拿高分影像,对比灾前灾后图像,靠纹理、色调、形态、阴影这些特征判断哪里发生过滑动。这个方法在点位少、范围小的时候是有效的,但放到大范围应急场景里就有几个绕不开的问题。
首先是效率。一个县的山地面积动辄上千平方公里,即便只看重点区段,人工筛查也要按天计算。其次是标准不统一,不同解译员对“滑坡边界”的理解有差异,同一幅影像不同人圈出来的范围可能差不少。再加上滑坡发生后,边界区域往往被松散堆积物覆盖,颜色跟周围裸土接近,光靠肉眼很容易漏判。
这时候深度学习语义分割模型的优势就很明显:模型一旦训练好,处理一幅影像的推理时间是以秒或者分钟计的,而且输出结果稳定,不会因为疲劳、状态导致标准漂移。这也是滑坡测绘逐渐从“人工解译为主”转向“模型初筛+人工复核”的根本原因。
1.2 滑坡语义分割的特殊难点
滑坡识别和普通的地物分类、道路提取不太一样,它有很强的“类内多样性”。同一个滑坡体上,可能有裸露的土体、碎裂的岩块、倒伏的树木、堆积的碎石,这些区域在影像里的颜色和纹理差异很大。而滑坡边界外,又有大量和滑坡体相似的裸露地表,比如农田翻耕地、施工开挖面、河滩冲积地,模型很容易把这一类东西误判成滑坡。
再加上高分辨率遥感影像里,阴影、云雾遮挡、植被覆盖都会造成滑坡体部分不可见。即便一个滑坡确实发生了,如果滑源区被植被盖住,影像上能看到的可能只有中部的一条擦痕和坡脚的堆积体。这种“不完整目标”对分割模型非常不友好。
还有一点经常被忽略:滑坡样本在整幅影像里占比极小。一个 512×512 像素的切片,滑坡区域可能只占几百到几千个像素,其他都是背景。类别不平衡一严重,模型训练出来就会偏向预测背景,漏检率极高。这些问题决定了滑坡测绘不能直接套一个最基础的语义分割模型,必须针对场景做一些结构上的定制。
1.3 SCDUNet++ 在整体方案里扮演什么角色
SCDUNet++ 解决的问题是“如何从高分辨率遥感影像里,端到端地输出滑坡区域的像素级掩膜”。放在整个项目流程里,它的位置非常靠前:输入是经过预处理的遥感影像切片,输出的是每个像素属于滑坡的概率图,后续把概率图矢量化、叠加到 GIS 里做面积统计和风险评估,那就是测绘和地灾业务环节了。
所以说,模型承担的是整个自动化流程中“眼睛”的部分。它识别得准不准、边界贴不贴、小目标漏不漏,直接决定了后续业务环节的工作量。如果模型初筛能把绝大多数真实滑坡都框出来,同时把误报控制在可接受范围内,人工复核的工作量就会大幅下降。这也是为什么团队要把大量精力花在模型结构改造和迁移学习策略上,而不是简单训一个现成的 U-Net 就完事。
2. 从 U-Net++ 到 SCDUNet++:结构演进与设计逻辑
2.1 U-Net 为什么是遥感分割的“地基”
搞图像分割的人对 U-Net 再熟悉不过了。它的结构分两条路径:左边是编码器,通过卷积和池化逐步下采样,把输入图像压缩成越来越抽象的特征图;右边是解码器,通过上采样把低分辨率的特征图逐步恢复到原始分辨率。关键是中间有一系列跳跃连接,把编码器每层的高分辨率特征直接拼到解码器对应层,这样解码器在恢复细节的时候,可以直接利用浅层的边缘、纹理信息。
这个设计非常契合遥感分割的痛点。滑坡边界细节多,浅层特征重要;语义判断需要看全局,深层特征重要。U-Net 的跳跃连接相当于给解码器开了个“细节直通车”,这也是它在医学影像分割被验证成功之后,迅速被遥感领域大量采用的原因。
2.2 U-Net++ 的改进:嵌套连接与深度监督
U-Net 本身已经很好用,但它有个潜在问题:跳跃连接只是简单地把编码器特征原样拼过来,没有做任何融合处理。编码器和解码器特征图的语义层级如果差太多,直接拼接反而会带来噪声。U-Net++ 的思路是在这个连接上做文章,把原先的“直连”改成一系列嵌套的卷积节点,用一个密集连接的子网络把编码器特征逐步提炼,再送入解码器。
同时 U-Net++ 引入了一个很有用的训练技巧——深度监督。意思是模型在解码器的不同层级都有输出分支,每个分支都算损失,训练时把多个层级的损失相加回传。好处是浅层的分支可以直接收到梯度,相当于给网络加了多个“辅导老师”,训练更稳,收敛更快。在训练数据量不大的滑坡任务里,这个特性很实用。
2.3 SCDUNet++:我理解中的三个关键设计
由于没有拿到论文原文的完整结构图,这部分结合实际项目的常规命名习惯做一个合理还原,正式定义以团队发表的论文为准。从名字拆解,SCDUNet++ 至少包含三方面设计:
第一是密集连接(Dense Connection)。在 U-Net++ 的卷积节点内部,把普通卷积串联改成 Dense Block 形式,每层的输入是前面所有层的输出拼接。密集连接的好处是特征复用率极高,梯度传导路径更短,即使网络加深也不容易出现梯度消失。对小样本滑坡数据来说,更强的梯度传导意味着模型能更充分地利用有限标注。
第二是空间和通道注意力。这正是“SC”最常见的含义,也就是 Spatial 和 Channel。通道注意力让模型学会“哪些特征通道重要”,比如某个通道可能对应土体纹理,那就给它更高权重;空间注意力让模型学会“图像哪些位置重要”,把注意力集中在坡体区域,减少背景干扰。两者串在一起,等于在特征提取的同时加了一个“打光”的过程,让有用信息更有存在感。
第三是在关键层级引入空洞卷积或者多尺度池化,用来扩大感受野。滑坡体大小差异很大,小到几十平方米的浅表层滑动,大到几平方公里的深层滑坡体。如果模型感受野太小,大滑坡只能看到局部纹理,很难判断整体结构;如果感受野过大,小目标的细节又会丢失。通过多尺度特征融合,模型可以在不同尺度上同时捕捉目标。
2.4 计算量与感受野怎么平衡
模型结构改得越复杂,参数和计算量涨得越快。滑坡遥感常用的输入切片是 256×256 或 512×512,一批次可能要同时塞 4 到 8 张图进 GPU。基础的 U-Net++ 在 512×512 输入下参数量大概在 9M 左右,加入密集连接和注意力之后,参数量大概会到 12M 到 15M 这个量级。对一张一块钱的消费级显卡来说还算可控,但再往上加模块就要小心了,尤其要留意显存占用和训练速度。
我见过不少团队在这个环节翻车:结构堆得很豪华,结果数据量跟不上,训练集只有几百张切片,模型直接过拟合,训练到后面验证集分数越走越低,训练集分数逼近满分。所以在实际项目里,模型结构的设计要和数据量匹配。SCDUNet++ 这类模型能跑通,背后一定配套了迁移学习来补充先验知识,否则单靠小样本从头训练,结构越复杂死得越快。
3. 迁移学习在滑坡测绘中的落地方式
3.1 样本少的现实问题
滑坡分割最卡的从来不是模型,而是数据。做一个省级范围内的滑坡识别模型,标注样本至少需要几千张包含滑坡的影像切片。每个滑坡区域需要专业人员人工圈定,边界怎么画、堆积区算不算、裂缝带算不算,都有讲究。一个熟练作业员,一天能精细标注几十个滑坡点就算很快了。更麻烦的是有些影像里滑坡极其不明显,需要结合 DEM、多时相数据才能确认,这种样本的标注成本非常高。
公开的滑坡分割数据集又少,不同数据集的影像来源、分辨率、地貌类型、标注标准差异很大,直接混在一起训练,模型往往学不到统一的滑坡特征。这么一来就陷入一个死循环:想训练好模型需要大量数据,可数据又贵又少。迁移学习就是这个循环里最重要的“解扣”手段。
3.2 归纳式和直推式,到底该选哪个
迁移学习在滑坡测绘里有两个应用层次,很多人会混在一起说,得理清楚。
归纳式迁移学习是最常见的做法。思路是先在数据量大的源任务上训练模型,让它学到通用的视觉特征,然后在目标任务的小样本数据上微调。放到滑坡测绘里,就是先在大型遥感影像数据集上做预训练,再把权重迁移到滑坡分割模型,在有限的滑坡标注数据上继续训练。这种做法简单实用,是工程首选。
直推式迁移学习更接近“域适应”的概念。它的特点是源域(比如通用遥感数据集)和目标域(滑坡影像)有相同的任务,但目标域只有未标注样本或极少标注样本。训练时,模型不仅要利用源域的已有标注,还要通过目标域的未标注影像去对齐特征分布。举个例子,通用遥感影像里有很多城市、农田,滑坡影像里则是大量山区裸地,两个域的影像风格差异很大。直推式方法会利用目标域无标注数据做统计特征对齐,让模型在训练阶段就提前“适应”山区的视觉环境,而不是等到推理时才面对分布差异。
说到热词里的“直推式迁移学习”,在滑坡这种标注极端匮乏的场景下确实很有价值。工程落地时,可以先在通用遥感数据上预训练拿到一个基础模型,然后拿大量无标注的滑坡区域影像做一致性训练,比如对同一影像做不同增强,要求模型输出保持一致;再拿少量有标注样本做监督微调。这种半监督式的流程,思路本质上就带着直推式迁移的味道。
3.3 从哪个数据集预训练更靠谱
很多做自然图像的人拿到问题,第一反应是把 ImageNet 的预训练权重拿来微调。但遥感影像和 ImageNet 里的日常照片差异太大了。遥感影像是俯视视角,目标尺度、纹理、光谱特征都不同,直接迁移 ImageNet 权重,虽然也能用,但效果往往一般。
更好的选择是用遥感领域的公开数据集做预训练,比如 BigEarthNet、RESISC45、OpenEarthMap、FBP 这些。它们覆盖了不同传感器、不同分辨率的遥感影像,模型在这些数据上能学到更贴近遥感任务的底层特征,比如地物纹理、空间布局、尺度关系,之后再迁移到滑坡任务,起跑线就完全不一样了。
还要注意一个波段问题。很多遥感影像是多光谱的,除了 RGB 还有近红外等波段。如果预训练模型是在 RGB 三通道上训练的,而目标数据有 4 个或更多波段,最简单的做法是先用 RGB 三通道去匹配预训练权重,把多光谱里的额外波段用随机初始化补齐,然后训练时让模型自动学这些额外波段的信息。千万不要因为多光谱通道数不一致就放弃预训练权重,那损失的信息远远大于补几个随机通道带来的影响。
3.4 迁移加载的工程实现:冻结、微调与学习率
理论归理论,落到代码上还是有不少细节。以 PyTorch 为例,假设模型类叫 SCDUNetPlusPlus,预训练权重只覆盖 encoder 部分,加载的时候需要按 key 过滤,不能让 strict 模式直接报错。
import torch model = SCDUNetPlusPlus(in_channels=5, num_classes=1) pretrained = torch.load("./bigearthnet_resnet.pth", map_location="cpu") # 只保留 encoder 部分,跳过 decoder 和 head new_state = {k: v for k, v in pretrained.items() if k.startswith("encoder.")} missing, unexpected = model.load_state_dict(new_state, strict=False) print("缺失参数:", missing) print("未匹配参数:", unexpected)加载完成后,最忌讳的做法就是直接整网开满学习率去训练。小样本场景下,随机初始化的解码器会输出很大的梯度,容易把已经训练好的编码器参数冲乱。实际项目中我建议分两步走:
# 第一步:冻结编码器,只训练解码器 for name, param in model.named_parameters(): if name.startswith("encoder."): param.requires_grad = False # 等解码器loss明显下降后,再解冻全部参数 for name, param in model.named_parameters(): param.requires_grad = True解冻之后还有一个细节是学习率分层。编码器来自预训练,学习率设小一点,比如 1e-5 到 3e-5;解码器是随机初始化的,学习率可以设到 1e-4。如果用一个统一学习率,容易出现编码器还没动,解码器先抖起来的局面。分组设置学习率其实就几行代码的事,但对训练稳定性帮助很大。
4. 完整实操链路:数据、训练与评估
4.1 数据集怎么造才不容易翻车
滑坡影像分割的数据集构建,核心原则是切片加增强。原始遥感影像动辄几千乘几千像素,不能整张图塞进模型,必须切成小块。切片大小我一般选 512×512,兼顾感受野和显存占用;如果显存紧张,256×256 也能跑,只是大目标会需要更大的步幅重叠来保证覆盖。
切片的时候要设置重叠区域,重叠率通常 10% 到 25%。原因是滑坡边界可能恰好被切成两半,如果一个目标被切到两张切片里都是残影,模型很难学到完整特征。重叠切片加上推理时的拼接策略,可以很大程度减少这类问题。
数据增强在滑坡任务里要谨慎。常规的随机翻转、旋转 90 度、小角度旋转都建议加,这相当于免费扩充训练样本。但光学变换要克制,尤其是色相、饱和度、亮度的大范围抖动。滑坡识别的核心特征是土体颜色和纹理,如果增强把灰褐色土体变成了绿色,模型就会学到错误关联。
再说一个很容易踩的坑:训练验证集划分一定要按空间划分,不能按切片随机划分。同一块滑坡区域生成的切片高度重叠,如果一部分切片在训练集,一部分在验证集,验证结果会虚高,因为模型在训练时已经见过同一块区域的绝大部分内容。正确做法是先按滑坡区域或地理坐标把影像分成块,再按块划分数据,保证训练和验证集在空间上互不重叠。
4.2 标签数据处理的几个关键细节
标签的质量比数量更重要,这一点在滑坡分割里体现得最明显。矢量标注转栅格的环节经常出问题:原始滑坡范围是 GIS 里的面要素,转成栅格时一定要和影像保持相同的分辨率、投影和范围,否则模型输入和标签错位,训练出来边界会整体偏移一圈。
实际数据里还有一种常见情况:滑坡体边界不是一条清晰的线,而是一个过渡带,从完全滑动的土体渐变到未受影响的地表。这时候用硬标签一刀切,会把过渡带里的像素强制归为前景或背景,增加训练噪音。我的经验是,标注时尽量把明确的滑坡主体、堆积体画进去,边缘模糊带宁可不标,也不要乱标。模型对模糊区域有争议是正常的,强制统一标注只会让收敛变差。
另外,统计一下数据集中滑坡像素的占比非常有必要。如果所有切片里滑坡像素平均只占 1% 到 2%,那训练时就要高度重视类别平衡问题。
4.3 训练参数、损失函数与评价指标
损失函数方面,纯用交叉熵在滑坡场景下效果很一般,因为背景像素占绝对大头,交叉熵会让模型倾向把所有像素都预测成背景。常用方案是 Dice Loss 和 Focal Loss 的组合。
Dice Loss 直接优化目标区域的重叠度:
DiceLoss = 1 - (2 × |预测∩真实|) / (|预测| + |真实|)
它对前景区域的大小不敏感,特别适合前景占比很小的任务。Focal Loss 的公式长这样:
FocalLoss = -α × (1 - p)^γ × log(p)
核心思想是降低易分样本的权重,让模型把注意力放在难分样本上。实际项目中我会用 0.6 的 Dice Loss 加 0.4 的 BCE Loss,或者 0.5 Dice 加 0.5 Focal,两种组合都试过,稳定性和精度都还不错。
优化器推荐 AdamW,初始学习率 1e-4,配合余弦退火或者 ReduceLROnPlateau。批次大小根据显存来,8 到 16 都可以,如果显存只有 8G,512×512 输入下批次 4 到 6 是常见选择。混合精度训练非常建议开,能把训练速度提升 30% 以上,同时显存占用降低不少。
评估指标按遥感分割惯例看 IoU、F1、像素精度这几项。IoU 是对分割结果非常严格的度量:
IoU = TP / (TP + FP + FN)
滑坡区域小,即便像素精度做到 99%,IoU 也可能只有 40% 到 60%,这个阶段不要慌,因为目标小,IoU 天然偏低。真正要看的是一对组合:查准率(预测出的滑坡中有多少是真的)和查全率(真实滑坡中有多少被找出来了)。应急场景下,查全率通常更重要,漏掉一个滑坡比多报几个嫌疑点严重得多。调阈值或者调损失权重时思路就要往这个方向偏。
4.4 推理时如何拼大图
模型推理和训练是两回事。训练时是独立的切片,推理时面对的是完整的大幅影像,必须用滑动窗口遍历整幅图,然后把所有窗口的预测结果拼回去。直接硬拼会出现明显的接缝效应——窗口边缘的预测不稳定,造成边界处出现条带。
解决办法是窗口重叠加上概率平均。比如窗口大小 512,步幅设为 384,这样每个位置会被多个窗口覆盖,推理时取重叠区域的预测概率均值。这个操作能显著改善接缝问题,代价是推理时间增加,但对离线测绘任务来说完全可接受。如果有 GPU,建议在推理时把多个窗口打包成批次一次算,别一张一张送进模型,速度能差好几倍。
5. 训练与推理中的常见问题速查
5.1 模型不收敛,先别急着加数据
训练早期如果 Loss 不降或者直接震荡发散,第一件事是检查输入和标签的对应关系。遥感项目里影像波段顺序弄错、标签和影像分辨率不匹配、归一化参数用错,都是常见问题。我见过有人把多光谱的 R、G、B 顺序搞混,模型训练了两天 Loss 还在 0.7 附近晃,一查是波段顺序和预训练权重不一致。
如果输入输出确实没问题,那就是学习率的问题。试一下更小的学习率,比如 1e-5,排除学习率过高的因素。训练初期可以选一张影像切片,把预测结果可视化出来看一眼。如果模型一片空白,大概率是损失函数里背景权重太大,把预测整体压没了;如果预测形状乱七八糟,大概率是标签和输入错位。可视化调试是最高效的排查手段,别只盯着 Loss 数字猜。
5.2 迁移之后反而变差,大概率是负迁移
负迁移这个现象在小样本任务里特别容易出现。明明用了预训练权重,效果反而不如从头训练,这是为什么?核心原因在于源域和目标域的分布差异太大。比如用 ImageNet 预训练权重迁移到多光谱滑坡影像上,ImageNet 学到的是自然图像的纹理和物体形状,而滑坡影像的核心特征是光谱反射和地形走向,两者交集很少,强行微调后模型可能被带偏。
另一个原因是预训练权重来自多分类任务,跟分割任务的任务头结构差别很大。如果简单粗暴地把全连接分类层的权重也迁移过来,反而会引入无用信息。解决负迁移的办法有几种:尽量选择遥感域预训练权重;加载权重后先冻结编码器,用目标域数据训练解码器,给编码器一个“稳定期”;还有一个是增大目标域数据增强,让模型不至于被源域特征束缚死。如果这些手段都试过仍然没有缓解,那就果断回退到从头训练,用更轻量的模型结构配合更强增强,效果也不会差。
5.3 小滑坡漏检、边界不齐怎么调
小目标漏检是滑坡分割最让人头疼的问题之一。一个只有二三十米宽的浅层滑坡,在 512×512 切片里可能只占一个角上的小块区域。模型下采样四次之后,这个小目标的特征可能已经在深层特征图里消失了。
针对小目标漏检,最直接的手段是减小切片尺寸,让目标在切片里的相对尺寸变大。比如从 512×512 降到 320×320 或 256×256,小目标的像素占比会成倍提高。代价是模型感受野变小,对大型滑坡的整体把握会变差,所以需要权衡或者做多尺度训练。另一个思路是提高输入影像分辨率,如果有更高分辨率的影像源,优先保证分辨率。
边界不齐则更多是标签问题或者后处理不足。模型输出的是像素级概率,如果直接按 0.5 阈值二值化,边界会很细碎。后处理可以做简单的形态学开闭运算,去掉零散噪点和补上细小空洞。如果边界还是参差不齐,可以尝试在损失函数里加一个 boundary loss 相关的项,或者把边缘检测任务整合成多任务学习,让模型在解分割的同时显式学习边界。从实际效果看,多任务学习对边界质量的提升非常明显。
5.4 显存不够和推理太慢的工程解法
训练时显存不够是最常见的工程瓶颈。除了降低批次大小、减小输入尺寸这些基本操作,有几个更优雅的解法:混合精度训练是最快见效的,显存能省 30% 到 40%;梯度累积可以让小批次在效果上模拟大批次,虽然单步速度没变,但稳定性提升明显;如果结构允许,把 BatchNorm 换成 GroupNorm,能放宽对批次大小的依赖,小批次训练时会更稳。
推理太慢的问题,核心思路是减少不必要的计算。模型推理前可以先用一个非常轻量的规则或分类模型筛掉明显不含滑坡的切片,只有被初筛标记为“疑似”的切片才进入完整的分割模型。一套二阶段推理流程,在滑坡这种目标稀疏的场景下能把总推理时间压缩 60% 以上。
6. 往后还能怎么扩展
6.1 多时相变化信息很重要
目前多数滑坡分割模型用的是单时相影像,也就是只看某一时刻的静态特征。可滑坡识别的本质是“变化”,灾前和灾后影像的差异是判断滑坡发生的最强信号。未来的方向很自然是把模型从单帧分割扩展成双时相变化检测:输入两期影像,让模型自己比较差异,再输出变化区域。这种思路对缓解误报会有显著帮助,比如把施工开挖、耕地翻整这类本就存在的裸地区域,通过“前后无变化”这个信号直接过滤掉。
6.2 与InSAR、DEM等多模态数据融合
光学影像再清晰,看到的也只是地表。滑坡真正的滑动面、形变位移、地形起伏,需要 DEM 和 InSAR 数据来补充。把 DEM、坡度、坡向作为额外通道和光学影像一起输入模型,已经是很多滑坡项目的标准做法。更进一步的思路是在特征层面做多模态融合,光学特征用来判断滑坡的表观特征,地形特征用来约束滑坡的地形合理性,两者互为补充,能显著减少把河流阶地、堆土场误判为滑坡的情况。
6.3 从区域模型走向通用基础模型
滑坡分割目前还是一个相对垂直的场景,训练出来的模型往往只能在特定区域、特定影像源上表现良好。换个卫星、换个地区的影像,效果就明显下降。如果要做通用化,核心还是回到迁移学习这条路上:先在覆盖全球、多传感器、多地形的大型遥感数据上训练一个通用分割基础模型,然后在滑坡这个细分任务上做微调。这条路对数据和算力的要求很高,但确实是滑坡测绘从“单点项目”走向“规模化业务”的必经之路。
我个人在实际项目中的体会是,模型结构能带来的提升是有上限的,真正决定项目生死的是数据和迁移策略。SCDUNet++ 的价值在于把 U-Net++ 在细节恢复上的优势和密集连接、注意力机制对特征的强化结合在了一起,而在小样本条件下,这套结构能不能发挥出来,关键看迁移学习做得细不细。预训练数据集选对、加载方式合理、微调流程稳健,模型的效果才有保障。如果你正在做类似方向的遥感分割项目,我建议先把数据和时间域的分布差异理清楚,再动手调结构。另外有个小技巧值得分享:训练过程中每隔几个 epoch 保存一次 checkpoint,回看每个 checkpoint 的验证 IoU,很多时候模型在某个中间状态反而表现最好,别一直拿着最后一个 epoch 的结果去评测。