4、遥感数据集构建:从数据到训练集的完整流程
做遥感深度学习,说白了就是让模型学会看卫星图。但模型不是天生就会的——你得先喂它数据。我见过太多同学一上来就调模型参数,结果数据没处理好,折腾半天精度上不去。嗯,今天我们就聊聊数据集构建这件事。
4.1 常见遥感数据集介绍
先说说几个经典数据集。我个人习惯把它们分成两类:场景分类数据集和目标检测数据集。
4.1.1 UC Merced 数据集
这是遥感领域的「Hello World」。2100张图像,21个类别,每类100张。图像大小256×256像素,分辨率1英尺。类别包括农田、飞机、棒球场、海滩、森林等等。
说实话,这个数据集现在有点过时了。我在2018年做实验时用它,当时觉得还行。但现在来看,数据量太小,场景也偏简单。不过作为入门练手,它还是不错的——训练快,几分钟就能跑完一个实验。
4.1.2 AID 数据集
AID是华中科技大学和武汉大学联合发布的。10000张图像,30个类别。每类大概200-400张。图像尺寸600×600像素,分辨率从0.5米到8米不等。
这个数据集我特别喜欢。为什么?因为它包含了多源遥感数据,有Google Earth的,也有航拍图。场景多样性比UC Merced好很多。我建议初学者用AID做场景分类实验,效果比较有说服力。
4.1.3 DIOR 数据集
DIOR是目标检测领域的标杆数据集。23463张图像,20个类别,共192472个标注实例。图像尺寸800×800像素。
这个数据集有个特点——它包含了不同季节、不同天气条件下的同一场景。比如同一个机场,夏天和冬天的样子完全不一样。我在项目中遇到过这种情况:模型在夏季数据上表现很好,一到冬季数据就崩了。DIOR正好能帮你测试模型的鲁棒性。
4.1.4 DeepGlobe 数据集
DeepGlobe是CVPR 2018挑战赛的数据集。它包含三个子任务:道路提取、建筑检测和土地分类。图像尺寸1024×1024像素,分辨率0.5米。
这个数据集最大的价值在于——它是高分辨率遥感数据。你想想看,0.5米的分辨率意味着什么?一辆车在图像上都有几十个像素。做语义分割任务时,DeepGlobe是很好的选择。
数据集选择建议:
- 入门练手:UC Merced(场景分类)
- 进阶实验:AID(场景分类)、DIOR(目标检测)
- 实战项目:DeepGlobe(语义分割)
4.2 数据标注工具
有了公开数据集还不够。实际项目中,你经常需要标注自己的数据。我推荐两个工具:LabelMe和QGIS。
4.2.1 LabelMe
LabelMe是MIT开发的在线标注工具。它支持多边形标注、矩形标注、圆形标注。标注结果保存为JSON格式。
我个人习惯用LabelMe做目标检测和语义分割的标注。操作很简单:打开图像,沿着目标边缘点几个点,闭合多边形,输入标签名称。搞定。
这里有个坑——我曾经标注了500张图像,结果发现标注文件里有个字段写错了。嗯,后来我写了个脚本批量修复。所以建议你标注前先检查一下配置文件,别像我一样走弯路。
# LabelMe标注文件示例(JSON格式)
{
"version": "4.5.6",
"flags": {},
"shapes": [
{
"label": "airplane",
"points": [
[120, 45],
[180, 45],
[180, 80],
[120, 80]
],
"group_id": null,
"shape_type": "rectangle",
"flags": {}
}
],
"imagePath": "001.jpg",
"imageData": null
}
4.2.2 QGIS
QGIS是开源的地理信息系统软件。它不仅能标注,还能处理地理坐标、投影转换等专业问题。
做遥感项目时,我经常遇到这种情况:原始数据是GeoTIFF格式的,带有地理坐标信息。如果用LabelMe标注,坐标信息就丢了。这时候QGIS就派上用场了——它可以直接在GeoTIFF上标注,标注结果保留地理坐标。
QGIS的标注流程:加载GeoTIFF → 创建矢量图层 → 开始标注 → 导出为Shapefile或GeoJSON。
工具选择建议:
- 简单标注任务(目标检测、语义分割):用LabelMe
- 需要保留地理坐标的任务:用QGIS
- 大规模标注项目:可以考虑LabelMe + QGIS组合使用
4.3 训练/验证/测试集划分
数据准备好了,接下来就是划分数据集。这个环节看似简单,但做不好会直接影响模型评估的可靠性。
4.3.1 划分比例
常见的划分比例是:训练集70%、验证集15%、测试集15%。但这不是绝对的。我根据项目经验总结了一个表格:
| 数据量 | 训练集 | 验证集 | 测试集 |
|---|---|---|---|
| < 1000张 | 70% | 15% | 15% |
| 1000-10000张 | 80% | 10% | 10% |
| > 10000张 | 85% | 7.5% | 7.5% |
数据量越大,训练集比例可以越高。为什么?因为验证集和测试集只需要足够评估模型性能就行,不需要太多。
4.3.2 划分原则
这里有几个原则必须遵守:
- 随机性:不要按文件名顺序划分,要随机打乱
- 分层采样:每个类别的样本在三个集合中的比例要一致
- 时间隔离:如果是时序数据,要用时间划分,不能用随机划分
- 空间隔离:同一场景的不同图像不能同时出现在训练集和测试集
我曾经犯过一个错误:用随机划分处理时序遥感数据。结果模型在测试集上表现很好,但实际部署时完全不行。后来才发现,训练集和测试集里包含了同一时间段的图像,模型学到了时间相关性,而不是真正的特征。
4.3.3 代码实现
下面是我常用的数据集划分脚本:
import os
import random
import shutil
from sklearn.model_selection import train_test_split
def split_dataset(data_dir, output_dir, train_ratio=0.7, val_ratio=0.15, test_ratio=0.15):
# 获取所有图像路径
images = [f for f in os.listdir(data_dir) if f.endswith(('.jpg', '.png', '.tif'))]
# 先划分训练集和临时集
train_images, temp_images = train_test_split(
images, test_size=(1 - train_ratio), random_state=42
)
# 再从临时集中划分验证集和测试集
val_images, test_images = train_test_split(
temp_images, test_size=test_ratio/(val_ratio + test_ratio), random_state=42
)
# 复制文件到对应目录
for split_name, split_images in zip(
['train', 'val', 'test'],
[train_images, val_images, test_images]
):
split_dir = os.path.join(output_dir, split_name)
os.makedirs(split_dir, exist_ok=True)
for img in split_images:
shutil.copy(
os.path.join(data_dir, img),
os.path.join(split_dir, img)
)
print(f"训练集: {len(train_images)} 张")
print(f"验证集: {len(val_images)} 张")
print(f"测试集: {len(test_images)} 张")
重要提醒:
- 划分完成后,验证集和测试集就不要再动了
- 不要用测试集做调参,否则评估结果会偏乐观
- 每次实验使用相同的划分,保证结果可复现
4.4 本章知识体系
下面这张图展示了数据集构建的完整流程:
从这张图可以看出,数据集构建不是简单的「下载-标注-划分」三步走。每个环节都有需要注意的细节。公开数据集可以直接用,但自建数据集需要标注工具辅助。混合数据集则要特别注意不同来源数据的格式统一问题。
好了,数据集构建这部分就聊到这里。记住一句话:数据质量决定了模型性能的上限。花时间把数据处理好,后面训练模型会省心很多。
公众号:蓝海资料掘金营,微信deep3321