手把手教你用UNetFormer实现遥感图像分割:从环境配置到模型训练全流程
手把手教你用UNetFormer实现遥感图像分割:从环境配置到模型训练全流程
遥感图像分割是计算机视觉领域的重要应用方向,尤其在城市规划、灾害监测和农业评估等领域发挥着关键作用。近年来,Transformer架构在视觉任务中展现出强大的全局建模能力,而UNetFormer作为结合CNN与Transformer优势的混合架构,为遥感图像分割提供了新的解决方案。
1. 环境配置与依赖安装
实现UNetFormer的第一步是搭建合适的开发环境。推荐使用Python 3.8+和PyTorch 1.10+的组合,这是目前最稳定的深度学习开发环境之一。
核心依赖包括:
- PyTorch及其vision扩展包
- OpenCV用于图像处理
- NumPy和Pandas用于数据操作
- Matplotlib和Seaborn用于可视化
# 创建conda环境(推荐) conda create -n unetformer python=3.8 conda activate unetformer # 安装PyTorch(根据CUDA版本选择) pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113 # 安装其他依赖 pip install opencv-python numpy pandas matplotlib seaborn tqdm提示:如果使用GPU加速,请确保已正确安装对应版本的CUDA和cuDNN。可以通过
nvidia-smi命令验证GPU是否可用。
对于遥感图像处理,还需要安装一些专业库:
pip install rasterio gdal pillow2. 数据集准备与预处理
遥感图像分割的质量很大程度上取决于数据准备的质量。常用的公开数据集包括:
- LoveDA:包含城市和农村场景的多时相遥感图像
- ISPRS Vaihingen:高分辨率航空图像
- DeepGlobe Land Cover:专注于土地覆盖分类
数据预处理的关键步骤:
- 图像裁剪:将大尺寸遥感图像裁剪为适合模型输入的patch(如512×512)
- 数据增强:旋转、翻转、色彩抖动等
- 归一化处理:将像素值归一化到[0,1]范围
import cv2 import numpy as np def preprocess_image(image_path, target_size=(512, 512)): # 读取图像 img = cv2.imread(image_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 归一化 img = img.astype(np.float32) / 255.0 # 裁剪或填充到目标尺寸 h, w = img.shape[:2] if h != target_size[0] or w != target_size[1]: img = cv2.resize(img, target_size, interpolation=cv2.INTER_LINEAR) # 转换为PyTorch张量格式 img = torch.from_numpy(img).permute(2, 0, 1).float() return img3. UNetFormer模型架构解析
UNetFormer的创新之处在于其混合架构设计:
| 组件 | 描述 | 优势 |
|---|---|---|
| CNN编码器 | 使用ResNet18提取局部特征 | 保留空间细节,计算高效 |
| Transformer解码器 | 全局-局部注意力机制 | 捕获长程依赖关系 |
| 特征细化头(FRH) | 融合浅层和深层特征 | 提升边界精度 |
模型的核心是全局-局部Transformer块(GLTB),其工作流程:
- 局部分支:使用3×3和1×1卷积提取局部上下文
- 全局分支:基于窗口的多头自注意力捕获全局关系
- 特征融合:通过十字形窗口交互模块整合跨窗口信息
import torch import torch.nn as nn from torchvision.models import resnet18 class GLTB(nn.Module): def __init__(self, dim, num_heads=8, window_size=8): super().__init__() # 局部分支 self.local_path = nn.Sequential( nn.Conv2d(dim, dim, kernel_size=3, padding=1, groups=dim), nn.Conv2d(dim, dim, kernel_size=1), nn.BatchNorm2d(dim), nn.GELU() ) # 全局分支 self.num_heads = num_heads self.window_size = window_size self.qkv = nn.Linear(dim, dim * 3) self.proj = nn.Linear(dim, dim) def forward(self, x): B, C, H, W = x.shape # 局部分支 local_feat = self.local_path(x) # 全局分支 x = x.permute(0, 2, 3, 1) # B,H,W,C qkv = self.qkv(x).reshape(B, H, W, 3, self.num_heads, C // self.num_heads) qkv = qkv.permute(3, 0, 4, 1, 2, 5) # 3,B,num_heads,H,W,C/num_heads q, k, v = qkv[0], qkv[1], qkv[2] # 窗口划分和注意力计算 # ... (省略具体实现细节) x = self.proj(x) x = x.permute(0, 3, 1, 2) # B,C,H,W # 特征融合 out = local_feat + x return out4. 模型训练与调优技巧
训练UNetFormer需要特别注意以下几个关键点:
优化器配置:
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.01) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)损失函数选择:
- 交叉熵损失:基础分类损失
- Dice损失:处理类别不平衡
- Lovász-Softmax:优化IoU指标
class DiceLoss(nn.Module): def __init__(self, smooth=1.): super(DiceLoss, self).__init__() self.smooth = smooth def forward(self, pred, target): pred = pred.contiguous() target = target.contiguous() intersection = (pred * target).sum(dim=2).sum(dim=2) loss = (1 - ((2. * intersection + self.smooth) / (pred.sum(dim=2).sum(dim=2) + target.sum(dim=2).sum(dim=2) + self.smooth))) return loss.mean()训练技巧:
- 渐进式学习率预热:前5个epoch线性增加学习率
- 混合精度训练:使用AMP减少显存占用
- 类别权重调整:根据类别频率设置不同权重
- 早停机制:验证集性能不再提升时停止训练
注意:遥感图像通常存在严重的类别不平衡问题,建议在计算损失时为不同类别设置权重,权重与类别频率成反比。
5. 结果可视化与性能评估
模型评估是项目的重要环节,常用的指标包括:
- 像素精度:整体分类准确率
- 平均IoU:各类别IoU的平均值
- F1分数:精确率和召回率的调和平均
可视化工具的实现:
import matplotlib.pyplot as plt def visualize_results(image, mask, pred, class_colors): fig, ax = plt.subplots(1, 3, figsize=(15, 5)) # 原始图像 ax[0].imshow(image) ax[0].set_title('Input Image') ax[0].axis('off') # 真实标注 gt_viz = np.zeros_like(mask) for cls, color in enumerate(class_colors): gt_viz[mask == cls] = color ax[1].imshow(gt_viz) ax[1].set_title('Ground Truth') ax[1].axis('off') # 预测结果 pred_viz = np.zeros_like(pred) for cls, color in enumerate(class_colors): pred_viz[pred == cls] = color ax[2].imshow(pred_viz) ax[2].set_title('Prediction') ax[2].axis('off') plt.tight_layout() return fig在实际项目中,我们发现UNetFormer相比传统UNet在边缘细节和细小目标的识别上有明显提升,特别是在处理大尺度遥感图像时,其全局注意力机制能够有效建模长距离依赖关系。通过合理调整窗口大小和注意力头数,可以在精度和效率之间取得良好平衡。
