ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于PaddlePaddle的遥感图像解译平台实战:从赛题到部署

基于PaddlePaddle的遥感图像解译平台实战:从赛题到部署 简介这份资源是「中国软件杯」A4赛题的完整项目源码包基于百度飞桨PaddlePaddle构建遥感图像解译平台面向参加软件杯赛事的高校学生、人工智能方向初学者及需要遥感解译课程设计或毕业设计的进阶学习者。项目涵盖前后端与深度学习推理模块可帮助读者理解遥感图像分类、目标检测等任务的工程化落地流程并作为赛题复刻与二次开发的起点。压缩包共130个文件以49个py源码与78个pyc编译文件为主另含少量md说明、txt配置及gitignore等辅助文件整体约88KB体量轻便便于快速部署与阅读。目录中可见views、predictors、settings、models及数据库迁移脚本等模块结构清晰能直观呈现Django后端与飞桨推理服务的组织方式。目前已有205人学习下载适合希望借鉴赛题方案、梳理遥感解译项目架构或在此基础上扩展功能的读者参考使用。1. 从一份赛题压缩包说起遥感图像解译平台到底在解什么中国软件杯的 A4 赛题把「基于百度 PaddlePaddle 的遥感图像解译平台」摆到台面上时很多人第一反应是「不就是跑个分割模型」。真上手才发现遥感图像解译平台要解决的是从卫星或航拍影像里把地物「认出来、框出来、量出来」的完整链路地物分类、目标检测、语义分割、变化检测每一环都有独立的输入输出规范。赛题给的是一个压缩包里面通常包含数据集说明、评测脚本、提交格式模板而不是一份能直接跑通的工程。这意味着参赛者要自己补齐数据读取、模型选型、训练调参、推理封装、结果导出这一整条流水线。这篇文章面向准备打这个赛题、或者想用 PaddlePaddle 搭一套遥感解译原型的工程师把选型理由、可复现的命令、参数含义和踩过的坑一次讲清楚让你拿到压缩包后知道先动哪一块。2. 遥感解译平台的技术栈拆解与 PaddlePaddle 选型理由遥感图像和自然图像最大的差别在于成像方式多光谱、高分辨率、大画幅、目标尺度跨度极大。一张 10000×10000 的影像里既有几十像素的车辆也有上千像素的机场跑道。这决定了框架选型不能只看「能不能跑 ResNet」而要看有没有针对大图切分、多尺度训练、稀疏标注的现成工具。PaddlePaddle 在这个场景下的优势集中在三点PaddleSeg 提供滑动窗口推理和 overlap 拼接PaddleDetection 内置了旋转框检测遥感目标带方向PaddleRS 本身就是遥感专用套件。下面把平台需要的能力和对应模块对齐。2.1 解译任务分类与对应模型族遥感解译不是单一任务赛题通常会在以下几类里选一到两类作为评测目标任务类型输入输出PaddlePaddle 常用模型地物分类影像块类别标签ResNet50 / PP-LCNet目标检测整幅影像水平框或旋转框PP-YOLOE / RT-DETR语义分割整幅影像逐像素类别DeepLabV3 / PP-MobileSeg变化检测双时相影像变化区域掩膜ChangeStar / BIT选型时先确认赛题评测指标如果是 mIoU走分割如果是 mAP走检测如果要求输出矢量 shp那分割后还要做栅格转矢量。很多队伍翻车就翻在没看清提交格式训了三天分割模型结果评测脚本读的是检测框的 json。2.2 环境搭建从零装好 PaddlePaddle 与遥感套件赛题环境一般是 Linux CUDA。先确认显卡驱动和 CUDA 版本再装对应版本的 PaddlePaddle。不要直接pip install paddlepaddle装 CPU 版然后抱怨训练慢。# 查看 CUDA 版本决定装哪个 wheel nvcc --version nvidia-smi # 以 CUDA 11.8 为例装 GPU 版 PaddlePaddle python -m pip install paddlepaddle-gpu2.6.1.post118 \ -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html # 验证 GPU 是否可用 python -c import paddle; paddle.utils.run_check()run_check()会打印 PaddlePaddle 版本、CUDA 版本和可用显卡数量。如果显示PaddlePaddle is installed successfully但CUDA available: False说明 wheel 版本和驱动不匹配换一个 post 版本重装。装完框架再装 PaddleSeg 和 PaddleDetectiongit clone https://github.com/PaddlePaddle/PaddleSeg.git cd PaddleSeg pip install -r requirements.txt pip install -v -e .-e是 editable 安装改源码后不用重装。PaddleDetection 同理。遥感套件 PaddleRS 如果赛题没强制要求可以只借用它的数据增强算子不必全量安装避免依赖冲突。2.3 数据管线的第一道坎大图切分与标签对齐遥感影像动辄上万像素直接 resize 到 512 会丢失小目标。常见做法是滑动窗口切分训练时切 patch推理时切 patch 再拼回整图。切分脚本要保证影像和标签用同一套坐标否则标签错位模型学到的全是噪声。import numpy as np def slide_crop(img, label, crop_size512, stride256): 滑动窗口切分stride 小于 crop_size 保证重叠避免边缘目标被切断 h, w img.shape[:2] patches [] for y in range(0, h - crop_size 1, stride): for x in range(0, w - crop_size 1, stride): img_patch img[y:ycrop_size, x:xcrop_size] label_patch label[y:ycrop_size, x:xcrop_size] # 过滤掉全背景 patch减少正负样本失衡 if label_patch.sum() 0 and np.random.rand() 0.1: continue patches.append((img_patch, label_patch, y, x)) return patchescrop_size根据显存定8G 显存跑 512 比较稳。stride设为 crop_size 的一半重叠区域在推理拼接时用加权平均消除接缝。y, x记录左上角坐标拼接时靠它还原位置。全背景 patch 保留 10% 是为了让模型见到负样本全丢掉会导致误检率飙升。3. 训练配置从配置文件到能收敛的超参PaddleSeg 和 PaddleDetection 都走配置文件驱动改模型结构、数据路径、学习率都在 yaml 里。很多人直接拿官方 config 改个数据集路径就开跑结果 loss 不降问题多半出在归一化参数和类别数没对齐。3.1 配置文件的关键字段逐个说清以 PaddleSeg 的 DeepLabV3 为例核心字段如下batch_size: 4 iters: 40000 train_dataset: type: Dataset dataset_root: data/remote_sense num_classes: 6 # 必须和标注类别数一致多一个少一个都报错 transforms: - type: Normalize mean: [0.42, 0.38, 0.30] # 遥感影像的均值不是 ImageNet 的 std: [0.20, 0.18, 0.17] mode: train optimizer: type: AdamW lr: 0.0001 weight_decay: 0.01 lr_scheduler: type: PolynomialDecay power: 0.9mean和std是第一个坑。遥感影像的波段分布和自然图像差异大直接用 ImageNet 的[0.485, 0.456, 0.406]会让输入分布偏移收敛变慢。正确做法是统计自己数据集的均值和方差跑一遍tools/analyze_dataset.py或者手写几行 numpy 算。num_classes要和标注里的类别 ID 严格对应如果标注从 1 开始编号而配置写 6最后一类永远学不到。lr用 AdamW 时 1e-4 是安全起点太大前期震荡太小 40000 iter 都收敛不完。3.2 启动训练与断点续训配置改好后启动训练单卡和多卡命令不同# 单卡训练 python tools/train.py \ --config configs/deeplabv3p/deeplabv3p_resnet50_os8_remote_512x512.yml \ --do_eval \ --use_vdl \ --save_interval 2000 \ --save_dir output/deeplabv3p # 多卡训练4 卡 python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py \ --config configs/deeplabv3p/deeplabv3p_resnet50_os8_remote_512x512.yml \ --do_eval \ --save_dir output/deeplabv3p_4gpu--do_eval每轮训练后跑验证集方便观察 mIoU 曲线。--use_vdl开可视化日志浏览器里能看 loss 和指标。--save_interval 2000每 2000 iter 存一次权重遥感训练动辄几小时不存中间权重一旦崩了就得重来。多卡训练时batch_size是单卡的值总 batch 等于单卡乘以卡数学习率要相应放大一般线性缩放4 卡就把 lr 乘 4。3.3 学习率与损失函数的调参边界遥感分割最常见的两个问题是小目标被淹没和类别极不平衡。损失函数上交叉熵对不平衡数据不友好换成带权重的 CE 或者 Dice Loss 组合loss: types: - type: CrossEntropyLoss weight: [1.0, 2.0, 2.0, 3.0, 3.0, 1.0] # 稀有类别给高权重 - type: DiceLoss coef: [1, 1]weight数组长度等于类别数稀有类别比如飞机、船给 2 到 3 倍权重背景类给 1。coef是两个 loss 的加权系数各给 1 让它们量级相当。学习率调度用 PolynomialDecaypower设 0.9前期下降快后期平缓比 StepDecay 更适合长训练。如果发现 mIoU 在 20000 iter 后卡住不动先别急着换模型把 lr 降一个数量级再跑 5000 iter很多时候是学习率太大在最优解附近震荡。4. 推理、拼接与提交格式把模型输出变成评测能读的文件训练完拿到权重只是半程赛题评测读的是特定格式的结果文件。分割任务要输出逐像素标签图检测任务要输出带坐标的 json 或 xml。这一步出错前面训得再好也是零分。4.1 滑动窗口推理与重叠区拼接大图推理不能整图塞进网络必须切 patch 推理再拼回。PaddleSeg 提供了tools/predict.py支持滑动窗口但默认参数不一定适配你的数据。python tools/predict.py \ --config configs/deeplabv3p/deeplabv3p_resnet50_os8_remote_512x512.yml \ --model_path output/deeplabv3p/best_model/model.pdparams \ --image_path data/test_images \ --save_dir output/predict_result \ --aug_pred \ --is_slide \ --crop_size 512 512 \ --stride 256 256--is_slide开启滑动窗口--crop_size和--stride要和训练时一致否则尺度不匹配精度掉得厉害。--aug_pred开多尺度翻转增强推理能涨一两个点 mIoU代价是推理时间翻几倍。拼接时重叠区用概率平均PaddleSeg 内部已经处理自己写脚本的话记得对 logits 做 softmax 后再平均直接平均类别 ID 会出错。4.2 栅格转矢量与提交文件生成如果赛题要求提交 shp 或 geojson分割结果还要做栅格转矢量。用 GDAL 或 rasterio 都行import rasterio from rasterio.features import shapes from shapely.geometry import shape import geopandas as gpd with rasterio.open(output/predict_result/mask.tif) as src: mask src.read(1) transform src.transform # 提取每个类别的多边形 results [] for geom, value in shapes(mask, transformtransform): if value 0: # 跳过背景 continue results.append({geometry: shape(geom), class: int(value)}) gdf gpd.GeoDataFrame(results, crsEPSG:4326) gdf.to_file(submit/result.shp, encodingutf-8)shapes逐像素追踪边界生成多边形value是类别 ID。背景类要跳过否则提交文件里全是无效多边形。crs要和原始影像一致遥感影像常用 UTM 投影写错坐标系评测时位置全偏。生成的多边形可能有大量小碎块提交前做一次面积过滤去掉小于 10 像素的噪声区域。4.3 评测脚本本地自测赛题压缩包里一般带评测脚本提交前务必本地跑一遍。常见评测脚本读的是特定目录结构比如submit/images/放预测图submit/labels/放真值。先拿验证集当测试集跑一遍确认脚本能正常读出结果并算出指标再提交。如果脚本报KeyError或shape mismatch八成是文件名没对齐或者图像尺寸不一致逐张检查。5. 避坑与排查那些让队伍通宵的常见问题遥感赛题的坑集中在数据、显存和格式三块。下面五条是实际比赛里高频出现的每条按现象、原因、解决写。现象训练 loss 从第一个 iter 就是 nan。原因学习率太大或者数据里有异常值比如标签全是 255 的忽略区域没处理。解决先把 lr 降到 1e-5 跑几百 iter 确认能降再逐步调回检查标注里是否有超出num_classes的像素值用np.unique(label)扫一遍。现象验证集 mIoU 很高但提交后得分极低。原因训练时做了 resize 或归一化推理时忘了同步或者提交格式和评测脚本要求不一致。解决把推理脚本的输出可视化几张和原图叠加看位置对不对对照赛题说明逐字段检查提交文件。现象多卡训练比单卡还慢。原因数据读取成了瓶颈或者卡间通信开销大于计算收益。解决把num_workers调大用--reader_threads加速数据加载小模型小 batch 场景下多卡收益有限不如单卡调大 batch。现象显存溢出batch_size 降到 1 还是 OOM。原因输入尺寸太大或者模型里某层特征图没控制住。解决把 crop_size 从 1024 降到 512开混合精度训练--fp16能省近一半显存检查是否有不必要的中间变量没释放。现象推理结果边缘有明显接缝。原因滑动窗口 stride 等于 crop_size没有重叠区或者拼接时直接覆盖没做加权。解决stride 设为 crop_size 的一半拼接时重叠区按距离加权平均越靠近 patch 中心权重越高。6. 进阶技巧用伪标签和模型集成把分数再抬一档打到后期单模型精度到瓶颈想再涨点就得靠数据侧和集成侧的手段。伪标签是性价比最高的一招用当前最好的模型对测试集推理挑置信度高的结果当伪标签混进训练集再训一轮。置信度阈值一般设 0.9太低引入噪声太高伪标签太少没效果。第二轮训练时伪标签样本的 loss 权重降到 0.5避免模型被自己的错误强化。模型集成上分割任务常用多模型概率平均训一个 DeepLabV3 和一个 PP-MobileSeg推理时把两者的 softmax 输出按 0.6 和 0.4 加权平均再取 argmax。两个模型结构差异越大集成收益越明显同结构不同 seed 的集成收益有限。检测任务可以用 WBF加权框融合替代 NMS对重叠目标的召回更友好。验证集成是否有效别只看整体 mIoU要分类别看。如果小目标类别涨了但大目标类别掉了说明权重分配有问题调一下加权系数。我自己的习惯是每次改动只动一个变量跑完验证集记录指标攒够三次对比再决定保留哪个方案。遥感赛题的数据量通常不大过拟合来得快早停和权重衰减比堆模型更管用。希望这些能帮你在赛题里少走几个通宵的弯路。本文还有配套的精品资源点击获取
返回列表