概述
在本教程中,您将学习如何使用 Amazon SageMaker 地理空间功能轻松获取可用的地理空间数据、进行机器学习预测并将结果可视化。
借助 Amazon SageMaker 地理空间功能,您可以使用地理空间数据构建、训练和部署机器学习模型。您可以高效地转换或丰富大规模地理空间数据集,利用预训练的机器学习模型加速模型构建,使用 3D 加速图形和内置可视化工具在交互式地图上探索模型预测结果。
地理空间数据可用于多种使用场景,包括自然灾害管理和响应、最大限度提高粮食产量、维护粮食安全、支持城市可持续发展等。在本教程中,我们将使用 SageMaker 地理空间功能来评估野火造成的损失。通过创建地球观测作业并将其可视化来执行土地覆盖分割,各组织可以评估野火造成的植被损失,并采取有效行动减轻损失。
要完成的目标
在本教程中,您将:
- 开始使用 Amazon SageMaker Studio 域访问 Amazon SageMaker 地理空间功能
- 创建并运行地球观测作业 (EOJ) 以执行土地覆盖分割
- 在交互式地图上实现作业输入和输出可视化
- 将任务输出导出到 Amazon S3
- 分析导出的数据并对导出的分割掩码进行进一步计算
前提条件
开始本指南之前,您需要先满足以下条件:
- AWS 账户:如果您还没有 AWS 账户,请遵循设置 AWS 环境入门指南中的说明获取快速概览。
受众
数据科学家、机器学习工程师
完成时间
45 分钟
使用场景
机器学习
所需费用
请参考 Amazon SageMaker for Geospatial ML 定价 来估算本教程所需成本。
级别
新手
使用的服务
上次更新时间
2023 年 4 月 19 日
操作步骤
步骤 1:设置 Amazon SageMaker Studio 域
在本教程中,您将使用 Amazon SageMaker Studio 访问 Amazon SageMaker 地理空间功能。
Amazon SageMaker Studio 是一个集成开发环境 (IDE),它提供了一个基于 Web 的单一可视化界面,您可以在此使用专门构建的工具,可执行从准备数据到构建、训练和部署机器学习模型的所有机器学习开发步骤。
如果您已经拥有一个美国西部(俄勒冈)区域的 SageMaker Studio 域,请按照 SageMaker Studio 设置指南将所需的 AWS IAM 策略附加到您的 SageMaker Studio 账户,然后跳过步骤 1,直接执行步骤 2。
如果没有现有的 SageMaker Studio 域,请继续执行步骤 1,运行 AWS CloudFormation 模板,创建 SageMaker Studio 域并添加本教程后续步骤所需的权限。
a. 选择 AWS CloudFormation 堆栈链接。您将通过此链接打开 AWS CloudFormation 控制台,并创建 SageMaker Studio 域和名为 studio-user 的用户。您还将为您的 SageMaker Studio 账户添加所需的权限。在 CloudFormation 控制台上,确认右上角显示的区域是美国西部(俄勒冈)。堆栈名称应为 CFN-SM-Geospatial,不应更改。系统需要 10 分钟左右来创建此堆栈的所有资源。
此堆栈假定您已在账户中设置了公共 VPC。如果没有公共 VPC,请参阅使用单个公有子网的 VPC 了解如何创建公共 VPC。
b. 完成堆栈创建后,就可以进入下一节,设置 SageMaker Studio 笔记本。
步骤 2:设置 SageMaker Studio 笔记本
在此步骤中,您将启动一个带有 SageMaker 地理空间镜像的新 SageMaker Studio 笔记本,这是一个 Python 镜像,由 GDAL、Fiona、GeoPandas、Shapely 和 Rasterio 等常用地理空间库组成,您可以在 SageMaker 中实现地理空间数据可视化。
a. 在控制台搜索栏中输入 SageMaker Studio,然后选择 SageMaker Studio。
b. 从 SageMaker 控制台右上角的区域下拉菜单中选择 US West (Oregon)(美国西部(俄勒冈))。
c. 若要启动应用程序,请从控制台左侧选择 Studio,然后选择 studio-user 配置文件并点击 Open Studio(打开 Studio)。
d. 此时将显示 SageMaker Studio 正在创建应用程序页面。应用程序需要几分钟进行加载。
e. 打开 SageMaker Studio 用户界面。在导航栏中,依次选择 File(文件)> New(新建)> Notebook(笔记本)。
f. 在 Set up notebook environment(设置笔记本环境)对话框中,在 Image(镜像)下选择 Geospatial 1.0。自动选择的内核是 Python 3。在 Instance type(实例类型)下,选择 ml.geospatial.interactive。然后,点击 Select(选择)。
g. 请耐心等待,直到笔记本内核启动为止。这时笔记本右上角的内核应当显示 Geospatial 1.0。
步骤 3:创建地球观测作业
在本步骤中,您将使用 Amazon SageMaker Studio 地理空间笔记本创建地球观测作业 (EOJ),它能让您获取、转换地理空间数据并将其可视化。
在本例中,您将使用预训练的机器学习模型进行土地覆盖分割。运行地球观测作业时,您可以根据具体使用场景从各种操作和模式中进行选择。
a. 在 Jupyter 笔记本中,复制以下代码并将其粘贴到一个新的代码单元格中,然后选择 Run(运行)。
- 这将初始化地理空间客户端并导入用于地理空间处理的库。
- 由于地理空间笔记本镜像已预装并配置了这些库,您无需安装它们。
import boto3
import sagemaker
import sagemaker_geospatial_map
import time
import datetime
import os
from glob import glob
import rasterio
from rasterio.plot import show
import matplotlib.colors
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np
import tifffile
sagemaker_session = sagemaker.Session()
export_bucket = sagemaker_session.default_bucket() # Alternatively you can use your custom bucket here.
session = boto3.Session()
execution_role = sagemaker.get_execution_role()
geospatial_client = session.client(service_name="sagemaker-geospatial")
b. 接下来,您将定义并启动一个新的地球观测作业 (EOJ)。
- 在地球观测作配置中,您可以定义感兴趣区域 (AOI)、时间范围和基于云覆盖率的过滤器。您也可以选择一个数据提供方。
- 在已提供的配置中,感兴趣区域是加利福尼亚州受迪克西野火影响的地区。基础数据来自哨兵 2 号卫星飞行任务。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
○ 任务创建后,可使用专用 ARN 对其进行引用。
eoj_input_config = {
"RasterDataCollectionQuery": {
"RasterDataCollectionArn": "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8",
"AreaOfInterest": {
"AreaOfInterestGeometry": {
"PolygonGeometry": {
"Coordinates": [
[
[-121.32559295351282, 40.386534879495315],
[-121.32559295351282, 40.09770246706907],
[-120.86738632168885, 40.09770246706907],
[-120.86738632168885, 40.386534879495315],
[-121.32559295351282, 40.386534879495315]
]
]
}
}
},
"TimeRangeFilter": {
"StartTime": "2021-06-01T00:00:00Z",
"EndTime": "2021-09-30T23:59:59Z",
},
"PropertyFilters": {
"Properties": [{"Property": {"EoCloudCover": {"LowerBound": 0, "UpperBound": 0.1}}}],
"LogicalOperator": "AND",
},
}
}
eoj_config = {"LandCoverSegmentationConfig": {}}
response = geospatial_client.start_earth_observation_job(
Name="dixie-wildfire-landcover-2021",
InputConfig=eoj_input_config,
JobConfig=eoj_config,
ExecutionRoleArn=execution_role,
)
eoj_arn = response["Arn"]
eoj_arn
e. 任务运行时,您可以查看用作地球观测作业输入的栅格数据。
- 使用地理空间 SDK 可以云优化 GeoTIFF (COG) 格式检索图像 URL。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
search_params = eoj_input_config.copy()
search_params["Arn"] = "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8"
search_params["RasterDataCollectionQuery"].pop("RasterDataCollectionArn", None)
search_params["RasterDataCollectionQuery"]["BandFilter"] = ["visual"]
cog_urls = []
search_result = geospatial_client.search_raster_data_collection(**search_params)
for item in search_result["Items"]:
asset_url = item["Assets"]["visual"]["Href"]
cog_urls.append(asset_url)
cog_urls
f. 接下来,您将使用 COG URL 将感兴趣区域的输入数据可视化。
- 这可以直观地对比野火发生前后的区域情况。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
cog_urls.sort(key=lambda x: x.split("TFK_")[1])
src_pre = rasterio.open(cog_urls[0])
src_post = rasterio.open(cog_urls[-1])
fig, (ax_before, ax_after) = plt.subplots(1, 2, figsize=(14,7))
subplot = show(src_pre, ax=ax_before)
subplot.axis('off')
subplot.set_title("Pre-wildfire ({})".format(cog_urls[0].split("TFK_")[1]))
subplot = show(src_post, ax=ax_after)
subplot.axis('off')
subplot.set_title("Post-wildfire ({})".format(cog_urls[-1].split("TFK_")[1]))
plt.show()
g. 继续执行后续步骤之前,您需要完成地球观测作业。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
- 该代码将持续输出作业的当前状态,并一直执行到地球观测作业完成为止。
- 请耐心等待,直到显示的状态变为 COMPLETED(已完成)为止。此过程可能需要 20-25 分钟。
# check status of created Earth Observation Job and wait until it is completed
eoj_completed = False
while not eoj_completed:
response = geospatial_client.get_earth_observation_job(Arn=eoj_arn)
print("Earth Observation Job status: {} (Last update: {})".format(response['Status'], datetime.datetime.now()), end='\r')
eoj_completed = True if response['Status'] == 'COMPLETED' else False
if not eoj_completed:
time.sleep(30)
步骤 4:实现地球观测作业可视化
在本步骤中,您将使用 Amazon SageMaker 地理空间功能提供的可视化功能,对地球观测作业的输入和输出进行可视化。
a. 在左侧导航栏中,点击 Data(数据)部分的箭头展开选项。然后,选择 Geospatial(地理空间)。
b. 在新的 Geospaction(地理空间)页签上,您将看到所有地球观测作业的概览。选择名为 dixie-wildfire-landcover-2021 的任务。
c. 在任务详情页面上,点击 Visualize job output(可视化任务输出)。
d. 可视化结果首先会根据 To Date(结束日期)字段显示最近日期的土地覆盖分割输出结果。
- 展示的图片呈现了野火肆虐后的土地覆盖数据。
- 深橙色像素代表植被覆盖区域(如地球观测作业图例所示)。
- 选择左侧的箭头,打开可视化选项。
e. 在可视化选项中,您可以选择和配置所有地理空间层和数据层。
- 对于输出栅格平铺图层,请选择隐藏符号。您将能够看到底层输入数据层。
f. 您还可以针对地球观测作业在不同时间段的输入和输出数据进行可视化。
- 在 To Date(结束日期)字段中,选择 2021 年 6 月 30 日。
g. 现在显示的数据是 2021 年 6 月 30 日之前的卫星图像。
- 这个时间段是在野火发生之前,植被(深橙色)的数量比之前查看的输出结果要高得多。
- 您这次仍然可以选择隐藏输出层,以查看底层的输入卫星图像(与上一步相同)。
- 若要进行到下一步,请选择 Untitled1.ipynb 页签,切换回笔记本。
步骤 5:将地球观测作业导出到 Amazon S3
在此步骤中,地球观测作业的输出数据将导出到 Amazon Simple Storage Service(Amazon S3)存储桶,导出的分割掩码也会进行下载以便进一步处理。
a. 您将使用地理空间 SDK 将地球观测作业的输出导出到 S3。
- 该操作需要 1-2 分钟完成。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
bucket_prefix = "eoj_dixie_wildfire_landcover"
response = geospatial_client.export_earth_observation_job(
Arn=eoj_arn,
ExecutionRoleArn=execution_role,
OutputConfig={
"S3Data": {"S3Uri": f"s3://{export_bucket}/{bucket_prefix}/"}
},
)
while not response['ExportStatus'] == 'SUCCEEDED':
response = geospatial_client.get_earth_observation_job(Arn=eoj_arn)
print("Export of Earth Observation Job status: {} (Last update: {})".format(response['ExportStatus'], datetime.datetime.now()), end='\r')
if not response['ExportStatus'] == 'SUCCEEDED':
time.sleep(30)
b. 接下来,将掩码文件从 S3 下载到 SageMaker Studio。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
s3_bucket = session.resource("s3").Bucket(export_bucket)
mask_dir = "./dixie-wildfire-landcover/masks"
os.makedirs(mask_dir, exist_ok=True)
for s3_object in s3_bucket.objects.filter(Prefix=bucket_prefix).all():
path, filename = os.path.split(s3_object.key)
if "output" in path:
mask_local_path = mask_dir + "/" + filename
s3_bucket.download_file(s3_object.key, mask_local_path)
print("Downloaded mask: " + mask_local_path)
mask_files = glob(os.path.join(mask_dir, "*.tif"))
mask_files.sort(key=lambda x: x.split("TFK_")[1])
步骤 6:分析导出的分割掩码
在这一步中,您将使用 SageMaker 地理空间镜像中包含的 Python 地理空间库,对导出的数据执行进一步操作。
a. 使用 numpy 和 tifffile 库,从掩码数据中提取专用的分割类别(植被和水),并将这些数据存储在变量中,以备后续使用。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
landcover_simple_colors = {"not vegetated": "khaki","vegetated": "olivedrab", "water": "lightsteelblue"}
def extract_masks(date_str):
mask_file = list(filter(lambda x: date_str in x, mask_files))[0]
mask = tifffile.imread(mask_file)
focus_area_mask = mask[400:1100, 600:1350]
vegetation_mask = np.isin(focus_area_mask, [4]).astype(np.uint8) # vegetation has a class index of 4
water_mask = np.isin(focus_area_mask, [6]).astype(np.uint8) # water has a class index of 6
water_mask[water_mask > 0] = 2
additive_mask = np.add(vegetation_mask, water_mask).astype(np.uint8)
return (focus_area_mask, vegetation_mask, additive_mask)
masks_20210603 = extract_masks("20210603")
masks_20210926 = extract_masks("20210926")
b. 您现在将使用预处理后的掩码数据实现提取类别的可视化。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
fig = plt.figure(figsize=(14,7))
fig.add_subplot(1, 2, 1)
plt.imshow(masks_20210603[2], cmap=matplotlib.colors.ListedColormap(list(landcover_simple_colors.values()), N=None))
plt.title("Pre-wildfire")
plt.axis('off')
ax = fig.add_subplot(1, 2, 2)
hs = plt.imshow(masks_20210926[2], cmap=matplotlib.colors.ListedColormap(list(landcover_simple_colors.values()), N=None))
plt.title("Post-wildfire")
plt.axis('off')
patches = [ mpatches.Patch(color=i[1], label=i[0]) for i in landcover_simple_colors.items()]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0. )
plt.show()
c. 最后,计算得出野火前后掩码的差异,并将其可视化。
- 这显示了野火对观测区域植被的影响。超过 60% 的植被直接在火灾中烧毁。
- 复制以下代码并将其粘贴到新的代码单元格中。然后选择 Run(运行)。
vegetation_loss = round((1 - (masks_20210926[1].sum() / masks_20210603[1].sum())) * 100, 2)
diff_mask = np.add(masks_20210603[1], masks_20210926[1])
plt.figure(figsize=(6, 6))
plt.title("Loss in vegetation ({}%)".format(vegetation_loss))
plt.imshow(diff_mask, cmap=matplotlib.colors.ListedColormap(["black","crimson", "silver"], N=None))
plt.axis('off')
patches = [mpatches.Patch(color="crimson", label="vegetation lost")]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0. )
plt.show()
步骤 7:清除 AWS 资源
对于您不再需要的资源,最佳做法是及时删除,以避免产生意外费用。
a. 完成以下步骤可删除 S3 存储桶:
- 打开 Amazon S3 控制台。在导航栏中选择 Buckets(存储桶),选择 sagemaker-<您的区域>-<您的账户 ID>,然后勾选 eoj_dixie_wildfire_landcover 旁边的复选框。接着点击 Delete(删除)。
- 在 Delete objects(删除对象)对话框中,确认您选择的删除对象正确无误,并在 Permanently delete objects(永久删除对象)确认框中输入 permanently delete(永久删除)。
- 完成上述操作并清空存储桶后,您可以再次按照相同的步骤删除 sagemaker-<您的区域>-<您的账户 ID> 存储桶。
若您不停止内核或执行下列步骤删除应用程序,那么本教程中用于运行笔记本镜像的地理空间内核将一直计费。更多信息请参阅 Amazon SageMaker 开发人员指南中的关闭资源。
- 执行下列步骤可删除 SageMaker Studio 应用程序:
- 在 SageMaker 控制台上,选择 Domains(域),然后选择 StudioDomain。
- 从用户配置文件列表中选择 studio-user,然后点击 Delete app(删除应用程序),删除 Apps(应用程序)下列出的所有应用程序。
- 若要删除 JupyterServer,请选择 Action(操作)下拉菜单中的 Delete(删除)。
- 请耐心等待,直到 Status(状态)变为 Deleted(已删除)为止。
注意:
- 如果在步骤 1 中使用了已有的 SageMaker Studio 域,则可以跳过其余步骤,直接进入结论部分。
- 如果您在步骤 1 运行 CloudFormation 模板创建了一个新的 SageMaker Studio 域,请继续执行以下步骤来删除域、用户和 CloudFormation 模板创建的资源。
c. 导航到 CloudFormation 控制台。
- 在 CloudFormation 窗格中,选择 Stacks(堆栈)。从状态下拉菜单中,选择 Active(运行中)。在 Stack name(堆栈名)下,选择 CFN-SM-Geospatial 以打开堆栈详情页面。
- 在 CFN-SM-Geospatial 堆栈详情页面上,点击 Delete 删除此堆栈和它在步骤 1 中创建的资源。
结果
恭喜您!您已完成有关使用 Amazon SageMaker 地理空间功能评估野火造成损失的教程。
在本教程中,您使用 Amazon SageMaker 地理空间功能创建了一个地球观测作业并将其可视化,还将其数据导出到 S3 并对数据进行了进一步计算。
后续步骤
您可以按照下面的后续步骤继续您的 Amazon SageMaker 机器学习之旅。