写在前面 -> 样本准备 -> 模型训练 -> 模型推理。
01
—
写在前面
对于多数人来说,有可能还不了解什么是变化检测,那咱们就直接上图:
上图中显示的是两幅不同年份同一地区影像,通过卷帘之后我们可以清晰的看到,这个地区发生了很大的变化,新盖了很多房子。变化检测要做的事情,就是检测出来哪个地方变化了。在本文的场景中,主要是针对房屋的变化。
在了解完背景之后,还需要了解一下,如果想要折腾这个场景的话,必要的条件:
-
ArcGIS Pro版本>= 2.7
-
ArcGIS API for Python版本>=1.8.3
另外由于本文是直接参考Esri的官网案例,所以如果真的想要按照本文中的折腾的话,还需要ArcGIS Enterprise做联动,不过后续会再写一篇Lino自己实操的,本篇就相当于先预热啦。
02
—
样本准备
变化检测的样本准备有些特殊,因为我们不光需要变化的区域,还需要变化前的影像与变化后的影像作为模型输入影像,一般情况下我们拿到的影像有三个:before.tif,after.tif以及change_label.tif。分别对应着的就是前期影像、后期影像以及房屋变化样本。在Esri的案例中,由于影像是托管在服务器上的,所以代码如下:
# 连接上Enterprise
from arcgis.gis import GIS
gis = GIS('home')
#查找到变化前后的影像数据
input_data = gis.content.search('change_detection_input_rasters owner: api_Data_owner', 'Image Collection')[0]
input_data
#查找到标签数据,也就是change_label.tif
mask_polygons = gis.content.search('cd_mask_polygons owner: api_Data_owner', 'feature layer')[0]
mask_polygons
ChageDetector模型所需的训练样本包含三个文件夹:
三个文件夹见字如面,前期影像、后期影像以及变化的标签。另外这个三个文件夹都可以通过ArcGIS Pro中的`Export Training Data For Deep Learning`工具导出,不过要导出三次:
在这里需要注意的是,元数据格式为"Export Tiles",分别对三个tif文件执行三次导出操作,然后再将导出的文件夹合并成满足变化检测模型所需的样本格式。怎么合成呢?其实很简单,就是复制粘贴,然后重命名就OK了。不过大伙们实操的话,记得要看一下导出的文件里面的图片数量一样多。
03
—
模型训练
到了咱们熟悉的模型训练,训练过程中需要使用ArcGIS API for Python实现的,目前ArcGIS Pro中并没有直接提供此模型进行训练。不过别怕,代码就那几行,稳住,跟着写就OK了。
# 导包
import os
from pathlib import Path
from arcgis.learn import prepare_data, ChangeDetector
准备数据集,咱们后期在ArcGIS Pro中完成的样本导出的话,可以不用下面这部分代码,不过可以了解一下:
#从服务器上获取训练数据
training_data = gis.content.get('d284e2083b254f6b8508f9cf41f53713')
#从服务器上下载数据,然后解压缩,添加数据的路径
filepath = training_data.download(file_name=training_data.name)
importzipfile
with zipfile.ZipFile(filepath, 'r') as zip_ref:
zip_ref.extractall(Path(filepath).parent)
data_path=Path(os.path.join(os.path.splitext(filepath)[0]))
在上一步中,简单说,就是从Enterprise中下载数据,然后解压缩到本地,添加本地的路径到python变量中。接下来开始将数据读取到内存中:
data = prepare_data(data_path,
chip_size=256,
dataset_type='ChangeDetection',
batch_size=8
)
查看一下咱们的数据集:
data.show_batch()
这一步可以很清晰的看到之前我们准备的样本。接下来实例化模型:
cd = ChangeDetector(data, backbone='resnet50')
查找学习率:
lr = cd.lr_find()
lr
然后进行模型训练:
cd.fit(epochs=100,lr=lr)
模型训练完成之后,就可以查看一下当前模型的表现了:
cd.show_results(rows=8)
最右边的就是模型推理出来的结果,从右数第二个是咱们标注的标签看,可以看到,模型的表现还是很不错的。也可以查看量化之后的模型精度:
cd.precision_recall_score()
如果对模型精度还满意的话,便可以保存模型啦:
cd.save('change_detection_model_e200')
04
—
模型推理
模型保存之后,便可以进行推理,在本案例中,影像数据都是托管在服务器上的,所以需要从服务器上下载影像:
inference_data = gis.content.get('6b32a534228b44b284c14e75b3d3f5f5')
test_path = inference_data.download(file_name=inference_data.name)
import zipfile
with zipfile.ZipFile(test_path, 'r') as zip_ref:
zip_ref.extractall(Path(test_path).parent)
上面的代码中,就做了一件事,下载推理的数据,解压缩。接下来咱们加载数据,然后进行模型推理:
test_images=Path(os.path.join(os.path.splitext(test_path)[0]))
before_img = os.path.join(test_images, 'before.tif')
after_img = os.path.join(test_images, 'after.tif')
#模型推理
cd.predict(before_image=before_img,
after_image=after_img,
visualize=True)
推理完之后,看一下效果(友情提示:下图中的可视化,并非是上面的代码展示出来的,所以不用纠结按照上面的代码怎么不显示可视化的效果):
本篇到此就结束啦,点击左下角阅读原文,便可直接访问Esri官网案例地址。