2026/9/15 7:17:02

小波变换与平行注意力机制在多源遥感图像分类中的应用

小波变换与平行注意力机制在多源遥感图像分类中的应用 简介基于小波变换与平行注意力的多源遥感图像分类源码面向遥感图像处理研究人员、深度学习开发者及论文复现者提供一套完整可运行的分类实现。资源源自北京航空航天大学学报2023年论文可用于土地利用分类、环境监测、灾害预警等场景。包体共56个文件压缩包约2.97MB包含19个Python源文件模型定义、训练测试、数据可视化等、31个编译缓存文件、YAML环境配置文件与依赖清单以及论文PDF和说明文档结构清晰便于部署复现。已有159人学习下载。源码集成了FusatNet、AsyFFNet、DFINet等多个网络模型配合小波变换工具库支持多源遥感数据融合训练。通过平行注意力机制增强特征选择能力让分类更精准。配套环境配置和报告脚本可帮助读者快速搭建实验环境理解论文核心模块为后续改进和应用提供坚实基础。1. 多源遥感图像分类为什么不能只靠加深网络光学影像和合成孔径雷达SAR影像构成的多源遥感数据在实际地物分类任务里几乎是标配光学影像有丰富的光谱和纹理信息SAR 却能在阴雨和多云条件下稳定成像。两边的优势互补非常诱人但直接把它们拼在一起送进卷积网络效果往往差得离谱。原因在于光学和 SAR 的成像机理完全不同像素值分布、噪声特性、空间分辨率都不一致粗暴拼接等于逼着网络自己学一套隐式的对齐和权重分配这对数据量和训练时间都是巨大负担。小波变换在这里的价值不是去噪这么简单。它能把图像分解成低频主体和高频细节两个层次相当于把不同尺度的信息先拆开再让网络分别处理避免深层下采样把微小的地物细节整个抹掉。平行注意力机制解决的是另一个问题多源特征融合时网络不知道该信光学影像的哪个通道、也不知道 SAR 影像的哪个空间位置更可靠平行注意力让通道和空间两个维度的筛选同时进行互为补充。这篇文章面向正在做遥感分类课题的研究生以及需要在遥感影像上落地分类模型的算法工程。全文会围绕「小波变换能拆出什么、平行注意力怎么搭、两者怎么接进分类网络、训练和评估时什么指标才真正管事」这条线展开所有做法都会落到可运行的源码层面参数和踩坑点一并给出。2. 小波变换在遥感图像里的角色从去噪到特征增强小波变换在遥感领域的应用最常见的说法是去噪但在分类网络里它的作用远不止于此。多源遥感图像分类面对的三个现实问题——SAR 相干斑噪声、光学与 SAR 之间的分布差异、小目标地物在下采样中丢失——恰好都能和小波分解的特性对应上。2.1 多源遥感图像的三个现实问题第一个问题是 SAR 影像的相干斑噪声。SAR 图像天生带颗粒状的乘性噪声直接丢给卷积网络网络前几层的大部分卷积核都在拟合噪声纹理而不是地物结构。用高斯滤波能平滑掉一部分噪声但边缘也一起模糊了属于杀敌一千自损八百。第二个问题是两源图像的分辨率和灰度分布不在一个数量级。光学影像通常是 8bit 或 16bit 的多波段数据SAR 影像即使是同一区域像素值反映的是后向散射系数。把它们归一化到 0-1 后拼接网络需要自行学习两个分布之间的映射这个映射本质上是非线性的浅层网络根本拟合不动。第三个问题是小目标检测与分类。遥感图像里船只、小建筑物、零星树木这类地物可能只占几十个像素经过三层 stride2 的下采样特征图上的响应几乎被抹平分类头根本看不到这些目标的存在证据。2.2 小波分解的子带结构与参数选择二维离散小波变换DWT一次分解产生四个子带LL低频近似、LH水平高频、HL垂直高频、HH对角高频。LL 保留了图像的主体结构三个高频子带分别记录不同方向的边缘和纹理。下一层分解继续作用在 LL 上形成多分辨率金字塔。遥感分类场景里小波基的选择直接影响分解效果。Haar 小波最简单但它的不连续性会让重建图像出现方块效应用于 SAR 去噪时会在平坦区域留下人为痕迹。我一般会选 Daubechies 族的 db2 或 db4它们的支撑长度适中对遥感影像里常见的缓变地物边界拟合得比较好。分解层数取 2 层太少则高频噪声分离不干净太多则 LL 子带分辨率损失过大。参数推荐值说明小波基db2 / db4平衡重构质量与计算量分解层数2三源及以上数据建议保持 2 层阈值方式软阈值硬阈值容易产生振铃阈值估计VisuShrink / 自适应局部阈值全局阈值对非平稳的遥感噪声不友好边缘处理对称延拓symmetric避免周期性延拓在边界产生虚假高频2.3 小波变换图像增强的 Python 实现用 PyWavelets 库在 Python 里做小波分解和重构非常直接。下面的代码演示了如何对 SAR 单通道影像做小波去噪同时保留高频细节用于后续特征提取。import pywt import numpy as np def wavelet_denoise_sar(image, waveletdb2, level2, modesoft): 对 SAR 图像做小波软阈值去噪保留低频主体, 同时对高频子带做衰减而非彻底置零避免细节完全丢失。 image: (H, W) float32 数组, 值域建议归一化到 [0, 1] coeffs pywt.wavedec2(image, waveletwavelet, levellevel, modesymmetric) # coeffs[0] 是 LL 子带, 其余是每层的 (LH, HL, HH) 三元组 sigma np.median(np.abs(coeffs[-1][-1])) / 0.6745 # 噪声标准差估计 threshold sigma * np.sqrt(2 * np.log(image.size)) # VisuShrink 阈值 # 对高频子带做软阈值处理, 系数保留符号以避免边缘方向反转 new_coeffs [coeffs[0]] for detail in coeffs[1:]: new_detail tuple(pywt.threshold(d, threshold, modemode) for d in detail) new_coeffs.append(new_detail) return pywt.waverec2(new_coeffs, waveletwavelet, modesymmetric) # 对光学多光谱影像的每个波段单独调用, 或对 PCA 第一主成分做 denoised_sar wavelet_denoise_sar(sar_channel)这段代码里值得关注的是噪声标准差估计那一行。用 HH 子带的中值绝对偏差来估计噪声水平是遥感图像处理里的标准做法它不依赖图像的整体均值和方差对 SAR 这种非平稳噪声更稳健。阈值公式里的image.size是总像素数影像越大阈值越高过滤掉的噪声越多但也要警惕把细小的真实地物一并削弱所以最后用了软阈值系数向零收缩但不截断。2.4 小波分解作为特征图的用法与常见误用去噪只是预处理层面的用法更强的做法是把小波分解的结果直接当作多尺度特征图输入网络。常见做法是对影像做一次二级分解得到包含 LL、LH、HL、HH 的七个子带把它们按通道维度组织成一个多通道张量替代原本的单通道输入。这里有一个很容易踩的坑不要把 LL 子带和其他三个高频子带直接做批归一化。LL 的量级和分布特征与三个高频子带完全不同混在一起归一化会抹掉它们之间的相对关系网络等于又回到了看不见尺度差异的状态。正确的做法是先按子带分别归一化再拼接或者在网络第一层就用 depthwise 卷积分别处理不同子带。另一个常见误用是在小波重构后直接上池化。既然小波分解已经得到了低频近似合理的做法是用步长为 2 的卷积在 LL 子带上继续提取特征或者干脆用 LL 子带替代一次池化操作这样信息损失比 max pooling 更可控。3. 平行注意力机制通道与空间并行筛选多源特征注意力机制在遥感分类里的作用本质上是让网络学会「看哪里」和「信什么」。前者是空间注意力后者是通道注意力。常见的做法是把通道注意力接在空间注意力前面形成一条串行链路但串行结构存在的问题是通道筛选后的结果输入到空间分支时已经被加权过一次空间分支无法看到原始特征的全貌。3.1 为什么这里用平行注意力而不是串行结构多源遥感图像的融合场景里光学影像和 SAR 影像的噪声模式、信息密度不一样甚至它们的通道数都不一样光学多光谱有 4-8 个波段SAR 通常只有 1-2 个极化通道。如果通道注意力和空间注意力串行比如先算通道权重再算空间权重那么 SAR 影像里通道数少、单通道信息量大的特点会导致通道注意力几乎不起作用反过来先算空间注意力光学影像的丰富光谱信息又被缩减了。平行注意力让两个分支各自独立计算最后把两个权重相乘两个维度的重要性都不会被对方先验地掩盖。从可解释性的角度看平行注意力输出的两组权重图通道权重向量和空间权重矩阵分别对应了「哪种地物光谱最可靠」和「影像的哪些区域最值得关注」这两个维度的分析逻辑与遥感专家的判读经验一致方便后续做分类结果的可视化和溯源。3.2 平行注意力模块的 PyTorch 实现下面是一个可插入任意卷积网络的平行注意力模块输入形状为 (B, C, H, W)输出保持形状不变。import torch import torch.nn as nn class ParallelAttention(nn.Module): 平行注意力模块: 通道注意力与空间注意力并行计算, 输出相加融合。 之所以用相加而不是相乘, 是避免两路权重都小于1时特征幅度过度收缩。 def __init__(self, in_channels, reduction8): super().__init__() # 通道注意力分支: 全局平均池化 两层MLP self.channel_mlp nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Conv2d(in_channels, in_channels // reduction, 1), nn.ReLU(inplaceTrue), nn.Conv2d(in_channels // reduction, in_channels, 1), nn.Sigmoid() ) # 空间注意力分支: 1x1 卷积降维后卷积生成空间权重 self.spatial_conv nn.Sequential( nn.Conv2d(in_channels, 1, kernel_size1), nn.Sigmoid() ) def forward(self, x): # 通道注意力权重 shape: (B, C, 1, 1) ch_weight self.channel_mlp(x) # 空间注意力权重 shape: (B, 1, H, W) sp_weight self.spatial_conv(x) # 两个分支并行相乘后相加 return x * ch_weight x * sp_weight这个模块的关键参数是reduction它控制通道注意力 MLP 的压缩比率。reduction8表示先把通道数压缩到原来的 1/8 再恢复这个值设置过大会损失通道间的相关性设置过小则参数冗余。遥感多光谱数据我一般保持 8SAR 数据通道数少可以调到 4。空间注意力分支只用了一层 1x1 卷积理由是多源影像经过前期特征提取后空间维度的关键信息主要落在局部区域如建筑群边界、水体边缘不需要过大的感受野。如果换成 3x3 卷积会增加不少计算量对精度的提升在遥感分类任务里通常不明显。3.3 双流主干与小波子带的融合设计平行注意力模块加在哪里直接决定整个模型的表现。多源遥感图像分类里典型的主干结构是共享权重的双流网络光学影像和 SAR 影像各自经过一个相同结构的编码器分支在中间层的融合点汇合。融合位置流程与张量尺寸变化适用场景输入级融合小波子带与原始影像拼接 → (B, C7, H, W) → 单流网络两源影像空间分辨率一致追求简单实现特征级融合推荐双流分别提取 → 各自过平行注意力 → 通道拼接 → (B, C1C2, H, W) → 分类头两源影像特征分布差异大需要分别建模决策级融合两支分别分类 → 对 Softmax 概率加权平均两源影像单侧噪声极大时应急用的兜底方案特征级融合是我在多数项目里优先考虑的方案因为它在灵活性和精度之间最平衡。具体做法是光学流提取到第 4 个 stage 时输出特征 F_optSAR 流对应输出 F_sar把两者分别送进平行注意力模块得到加权后的特征后再沿通道维度拼接。这样每个模态先通过注意力强调了自己内部最有判别性的维度拼接后的特征不会出现某一模态主导的情况。小波子带在这个架构里的接入点是第二层或第三层 stage。将小波分解得到的高频子带 resize 到当前特征图尺寸后与空间注意力分支输出的权重做逐元素相乘相当于用高频细节对空间注意力权重做一次校正。这个操作能让那些在光学影像里被云遮挡、在 SAR 影像里被噪声掩盖的微小目标重新获得权重。3.4 源码实现里最常踩的三个形状问题平行注意力模块本身实现简单麻烦总出在输入数据准备阶段。第一个问题是小波分解后的子带尺寸不一致。pywt.wavedec2在图像尺寸不是 2 的整数次幂时会返回不同尺寸的子带。解决办法是在分解前对影像做 padding 到能被 $2^{level}$ 整除或者用pywt.pad配合对称延拓保证每个子带尺寸相同。第二个问题是光学多波段影像的通道顺序。部分遥感数据集以 (H, W, C) 存储而 PyTorch 卷积输入要求 (C, H, W)。np.transpose转换后小波分解需要对每个通道单独进行不要在通道维上直接分解。第三个问题是 batch size 与归一化统计量。注意力模块里的nn.Sigmoid对输入幅度敏感如果 batch size 只有 2-4批归一化的均值方差估计不稳定会直接影响注意力权重的分布。我的做法是用层归一化替代前几层的批归一化或者在主干里保留sync_bn但把注意力模块放在归一化之后的特征上。4. 分类训练策略与损失函数长尾地物与噪声鲁棒性模型架构搭好后训练策略往往比结构设计更能决定最终精度。多源遥感图像分类的任务天然存在两个问题不同地物类别的样本数量极度不均衡比如水体、裸地样本多某些特定建筑类型样本很少以及噪声标签尤其是 SAR 影像解译的标注结果经常有错。这直接影响了损失函数和训练超参的选择。4.1 分类损失函数的选择与组合遥感图像分类的常见套路是直接用 Softmax 交叉熵但对于长尾分布的地物类别这个损失函数会把大量梯度分配给高频类别低频类别的分类精度总是提不上去。我在处理这类问题时会用标签平滑的交叉熵配合类别权重。import torch.nn.functional as F def weighted_label_smooth_loss(logits, labels, cls_weights, smoothing0.1): logits: (B, num_classes) 未经过 softmax 的原始输出 cls_weights: (num_classes,) 每个类别的样本数量倒数归一化后的权重 log_probs F.log_softmax(logits, dim-1) smooth_loss -log_probs.mean(dim-1) # 均匀分布那一项 # 构造平滑后的标签分布 n logits.size(-1) with torch.no_grad(): smoothed torch.zeros_like(log_probs).fill_(smoothing / (n - 1)) smoothed.scatter_(1, labels.unsqueeze(1), 1.0 - smoothing) loss -(smoothed * log_probs * cls_weights.unsqueeze(0)).sum(dim-1) return (loss smoothing * smooth_loss * cls_weights[labels]).mean()cls_weights的计算方式是每个类别样本数的倒数再归一化让少数类别的样本在 loss 中获得更大的梯度。标签平滑系数smoothing0.1是为了防止模型对标注不完全准确的训练集产生过拟合——SAR 影像的解译标注边界经常是模糊的硬标签会让模型强行记住不确定的边界。训练初期我还会叠加一个 focal loss 变体它的核心思想是让模型集中注意力在分类困难的样本上。遥感场景里难样本通常就是那批被云覆盖一半、或者小到只有几十个像素的目标。实际使用时把加权交叉熵作为主损失focal loss 作为辅助损失两者加权相加辅助损失的权重从 0.5 开始逐步衰减到 0避免训练后期难样本中的噪声被过度放大。4.2 训练超参数参考多源遥感图像分类的训练超参数和常规 ImageNet 分类有较大差异主要因为遥感数据集的规模通常在几万张量级远小于自然图像数据集且类别数少则十来个、多则上百个。超参数推荐值调试说明初始学习率3e-4AdamW 下比常见 1e-3 更稳预训练主干用 1e-4Batch Size16-32取决显存小 batch 配 LayerNorm 代替 BatchNorm优化器AdamWweight_decay 设 1e-2 到 5e-2防止大模型过拟合学习率策略Warmup 5 epochs Cosine Annealingwarmup 让注意力模块的 Sigmoid 输出不至于开局饱和训练轮数60-100遥感图像分类任务 100 轮左右足够收敛数据增强RandomCrop Flip 色彩抖动不要对 SAR 影像做色彩增强破坏后向散射的物理意义SAR 影像的数据增强与光学影像必须分开写。对 SAR 做颜色抖动、随机亮度这类增强是物理上错误的操作因为 SAR 的像素值对应的是地表粗糙度和介电常数随机改变亮度等于人为制造了不存在的散射特性。SAR 侧只做几何增强翻转、旋转、裁剪光学侧可以加色彩类增强。4.3 分类评估指标整体准确率会骗人遥感图像分类的评估指标上整体准确率Overall Accuracy, OA是最直观但也最容易误导人的指标。在类别长尾分布下哪怕某一类地物完全没被识别出来只要其他类别样本多OA 依然能到 90% 以上。真正要看的分类评估指标是这三个Kappa 系数、宏平均 F1Macro-F1和混淆矩阵。Kappa 系数衡量的是分类结果与随机分类相比提升了多少数值低于 0.6 说明模型并没有学到有效的判别特征。宏平均 F1 对每个类别单独计算 F1 再平均低频类别和低频类别的贡献一致不会被高频类别淹没。混淆矩阵则用于定位具体的类别混淆对——在遥感分类里最常见的混淆对是「裸地」和「低密度建筑区」两者在 SAR 影像上的后向散射特征很接近。from sklearn.metrics import cohen_kappa_score, f1_score, confusion_matrix import numpy as np def evaluate_classification(all_labels, all_preds, class_names): 针对遥感多类别长尾分布的综合评估 kappa cohen_kappa_score(all_labels, all_preds, weightslinear) macro_f1 f1_score(all_labels, all_preds, averagemacro, zero_division0) # weighted_f1 与 OA 的相关性高, 只作辅助参考 weighted_f1 f1_score(all_labels, all_preds, averageweighted, zero_division0) cm confusion_matrix(all_labels, all_preds) # 计算每个类别的类别准确率 (Recall) recall cm.diagonal() / (cm.sum(axis1) 1e-7) print(fKappa: {kappa:.4f} | Macro-F1: {macro_f1:.4f}) for i, name in enumerate(class_names): print(f{name:12s} Recall: {recall[i]:.4f})在实际项目中我会额外统计每个类别 recall 的最小值。如果某个类别的 recall 长期低于 0.5先检查标注质量再看是否需要为该类别合成训练样本。遥感图像不做随机过采样因为简单的样本复制会让模型对特定影像的噪声纹理产生记忆正确做法是用小波重构来生成合理的变换样本。4.4 验证集划分里的一个隐蔽错误遥感图像的验证集划分有个容易忽略的陷阱相邻影像之间存在空间相关性。如果训练集和验证集的地块在地理位置上相邻模型实际上见过验证集区域的周边上下文评估结果会偏乐观。从业资料里把这种泄漏称为「空间数据泄漏」在Kaggle 这类竞赛里见过不少翻车案例在地理信息相关的实际项目里影响更大。正确做法是按地块patch划分而不是按单张切片划分。把整幅遥感影像划分成若干互不重叠的大地块每个大地块内部再切训练样本训练集和验证集使用不同的大地块。这样验证集与训练集的间距至少大于一个地块的尺寸空间自相关的影响能被控制住。5. 快速验证小波与注意力模块是否生效的技巧模型训练完精度指标再好看也需要回答一个问题精度提升到底是小波变换和平行注意力带来的还是单纯因为模型参数变多了这直接关系到这套方案能不能迁移到新的数据集上。答案来自消融实验但消融实验怎么做才有效率有具体的门道。最基本的消融设计是三个配置完整模型小波 平行注意力、去掉小波分支只保留平行注意力、两者都去掉退化为普通的双流拼接网络。三组实验用同一份数据、同一组超参数、同样的训练轮数。最后对比 Macro-F1 和 Kappa。如果加了小波分支后宏平均 F1 提升了不到 0.5 个百分点说明小波在这个数据集上只是锦上添花可以为了推理速度砍掉如果提升超过 2 个百分点说明数据集里确实存在大量依赖高频细节才能区分的地物。第二个值得做的验证是检查平行注意力两个分支的权重分布。把空间注意力分支的输出做可视化如果权重高亮区域与影像里的地物边界高度吻合说明注意力学到了有物理意义的位置信息如果高亮区域随机散布就要检查是不是训练轮数不足或者批归一化统计量不稳定。第三个小技巧是手动构造一个损坏样本集来测试模型的鲁棒性。从测试集中挑一批光学影像加入模拟云遮挡再挑一批 SAR 影像加入更强的高斯噪声分别输入到完整模型和消融模型里观察精度的下降幅度。这个测试能直接回答「小波去噪到底有没有在输入端起到稳定作用」——如果加了小波分支后精度下降幅度更小说明它确实让特征提取对噪声更鲁棒否则说明输入级的小波处理只是把噪声搬了个位置。最后说一个模型扩展的方向。当数据源从两个增加到三个比如加入高光谱影像时平行注意力模块不需要任何结构性改动直接把第三个模态接入双流主干变成三流结构即可。小波分解同样逐模态独立进行。真正需要调整的是融合层——第三模态加入后通道拼接的参数量会激增这时可以考虑把融合方式从拼接改为加权求和权重由一个小型的注意力网络动态生成。这种做法能在扩展模态的同时控制模型体积的增长是工程上比较实用的演进路径。本文还有配套的精品资源点击获取