Million-AID是一个包含百万实例的用于遥感场景分类的大型基准数据集。其包含了广泛的语义类别,即51个场景类别,由三级树的分级类别网络组织而成:51个叶节点分为第二层的28个父节点,父节点又分组为第一级的8个节点,分别代表农业用地、商业用地、工业用地、公共服务用地、居住用地、交通用地、未利用地和水域8个底层场景类别。场景类别网络为数据集提供了良好的不同场景类别之间的关系组织和可扩展性。每个场景类别的图像数量大约在2000到45000之间,这使得数据集具有长尾分布的特性。此外,Million-AID具有空间分辨率高、规模大、分布全球等优势,优于现有的场景分类数据集。
上图为Million-AID三级树分类结构
Million-AID Dataset Download
要编写一个完整的神经网络模型,其中最重要的有三点,模型定义、数据加载、训练和测试
data/
__init__.py
dataset.py
get_data.py
models/
__init__.py
LenetModel.py
ViT.py
..
utils/
__init__.py
train.py
test.py
各个文件的内容和作用如下:
data/:包括数据预处理,数据加载等。
models/:用于模型定义,可定义多个模型,如上述的Lenet和ViT模型
utils/:添加可能用到的工具函数,包括可视化工具等。
train.py 和 test.py 分别是训练和测试程序的入口
import os
import numpy as np
import torch
from PIL import Image
from torch.utils import data
import matplotlib.pyplot as plt
import matplotlib.image as ig
class RemoteSensingImage(data.Dataset):
def __init__(self, Imageroot):
images = os.listdir(Imageroot)
# 获得加载的训练集所有图片路径
self.images = [os.path.join(Imageroot, image) for image in images]
# 将图片所在路径与图片名拼接,得到绝对路径
def __getitem__(self, index):
image_path = self.images[index]
label = 1
# 这里只加载了Million-AID中农业用地-耕种用地-干燥土地一类,因此简单的置标签为1
image_show = Image.open(image_path)
# 图片读取
array = np.array(image_show)
# 将图片数据转换为数组
data = torch.from_numpy(array)
# 将数据数组转换为Tensor
return data, label, image_path
def __len__(self):
return len(self.images)
# 返回数据长度
def main():
root = 'D:\\Paper\\Dataset\\Million-AID\\train\\train\\train\\train\\agriculture_land\\arable_land\\dry_field'
dataset = RemoteSensingImage(root)
image, lable,path = dataset.__getitem__(0)
length = dataset.__len__()
print(image.size(),lable, length, path)
# 输出图片尺寸,标签,数据集大小,图片路径
rootimage = str(path)
img = ig.imread(rootimage)
plt.imshow(img)
plt.show()
# 显示图片
if __name__ == '__main__':
main()
由上述代码我们可以定义自己的数据集,但是还存在问题,直接读取的数据不一定就适合实际使用,图片的大小可能不一,返回图片的灰度值在0~255之间,没有进行归一化等。
Pytorch提供了torchvision,它是一个视觉工具包,提供了许多图像处理的工具,其中transforms模块提供了对PIL Image对象和Tensor对象的常用操作
对PIL image的操作如下:
Resize or Scale: 调整图像尺寸,如transforms.Resize((256,256)),将图像转为尺寸大小为256*256。
CenterCrop、RandomCrop、RandomSizedCrop:中心裁剪,随机裁剪等。
Pad:填充。
ToTensor:将PIL Image对象转为Tensor,且将灰度值由[0,255]归一化到[0,1]
Normalize:标准化,即减均值除以标准差。
ToPILImage:将Tensor转换为PILImage对象
并且可以调用transforms中的Compose方法将所要做的所有操作拼接起来,类似于nn.Sequential堆叠层。
import os
import torch
from PIL import Image
import os
import numpy as np
from torchvision import transforms as TRAN
from torch.utils import data
import matplotlib.pyplot as plt
import matplotlib.image as ig
transforms = TRAN.Compose([
TRAN.Resize(256),
TRAN.CenterCrop(256),
TRAN.ToTensor(),
TRAN.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
])
class RemoteSensingImage(data.Dataset):
def __init__(self, Imageroot):
images = os.listdir(Imageroot)
# 获得加载的训练集所有图片路径
self.images = [os.path.join(Imageroot, image) for image in images]
# 将图片所在路径与图片名拼接,得到绝对路径
self.transforms = transforms
def __getitem__(self, index):
image_path = self.images[index]
label = 1
# 这里只加载了Million-AID中农业用地-耕种用地-干燥土地一类,因此简单的置标签为1
data = Image.open(image_path)
# 图片读取
if self.transforms:
data = self.transforms(data)
return data, label, image_path
def __len__(self):
return len(self.images)
# 返回数据长度
def main():
root = 'D:\\Paper\\Dataset\\Million-AID\\train\\train\\train\\train\\agriculture_land\\arable_land\\dry_field'
dataset = RemoteSensingImage(root)
image, lable, path = dataset.__getitem__(1)
length = dataset.__len__()
print(image.size(), lable, length,'\n',path)
rootimage = str(path)
img = ig.imread(rootimage)
plt.imshow(img)
plt.show()
if __name__ == '__main__':
main()