Google Earth Engine(GEE)——缩放错误指南(聚合过多、超出内存、超出最大像素和超出内存限制)!

2024-05-24 08:51:33 浏览数 (1)

缩放错误

虽然脚本可能是有效的 JavaScript,没有逻辑错误,并代表服务器的一组有效指令,但在并行化和执行计算时,结果对象可能太大、太多或计算时间太长。在这种情况下,您将收到一个错误,指出该算法无法缩放。这些错误通常是最难诊断和解决的。此类错误的示例包括:

  • Computation timed out
  • Too many concurrent aggregations
  • User memory limit exceeded
  • An internal error has occurred
  • 计算超时
  • 并发聚合过多
  • 超出用户内存限制
  • 发生内部错误

警告:存在配额限制以确保整个地球引擎社区的计算资源的可用性。试图通过使用多个 Google 帐户来规避配额限制是违反 地球引擎服务条款的。

改进代码的可伸缩性将使您更快地获得结果,并提高所有用户的计算资源的可用性。下面将讨论每种类型的错误,然后简要介绍reduceRegion(),这是一个因能够导致每种类型的缩放错误而臭名昭著的常用函数。

reduceRegion()

虽然reduceRegion()贪婪地消耗足够的像素来触发各种令人兴奋的错误,但也有用于控制计算的参数,因此您可以克服错误。例如,考虑以下不可取的减少:

错误— 此代码不起作用!

代码语言:javascript复制
var absurdComputation = ee.Image(1).reduceRegion({
  reducer: 'count',
  geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false),
  scale: 100,
});

// Error: Image.reduceRegion: 太多像素用于计算了,所以超出了像素,建议缩小scale,也就是分辨率你得调大
//        Found 80300348117, but only 10000000 allowed.
print(absurdComputation);

这个例子只是为了演示。此错误的目的是询问您是否真的要减少 80300348117(即 800亿)像素。如果没有,相应地增加scale(以米为单位的像素大小),或设置bestEffort为 true,以自动重新计算更大的比例。这样可以最大限度的获取你想要的图像,在不超出计算范围的前提下!!!

计算超时

假设您在计算中需要所有这些像素。如果是这样,您可以增加 maxPixels参数以允许计算成功。但是,Earth Engine 需要一些时间来完成计算。因此,可能会抛出“计算超时”错误:

不好——不要这样做!

代码语言:javascript复制
var ridiculousComputation = ee.Image(1).reduceRegion({
  reducer: 'count',
  geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false),
  scale: 100,
  maxPixels: 1e11
});

// Error: 计算超时
print(ridiculousComputation);

这个错误意味着地球引擎在停止计算之前等待了大约五分钟。导出允许 Earth Engine 在具有更长允许运行时间(但不能有更多内存)的环境中执行计算。由于返回值reduceRegion()是字典,因此您可以使用字典来设置具有空几何的特征的属性:

- 使用Export

代码语言:javascript复制
Export.table.toDrive({
  collection: ee.FeatureCollection([
    ee.Feature(null, ridiculousComputation)
  ]),
  description: 'ridiculousComputation',
  fileFormat: 'CSV'
});
并发聚合过多(通过导出的方式来避免在线计算过多)

此错误的“聚合”部分指的是分布在多台机器上的操作(例如跨越多个瓦片的减少)。Earth Engine 有限制,以防止同时运行太多这样的聚合。在此示例中,“并发聚合过多”错误是由映射内的减少触发的:

不好——不要这样做!

代码语言:javascript复制
var collection = ee.ImageCollection('LANDSAT/LT05/C01/T1')
    .filterBounds(ee.Geometry.Point([-123, 43]));

var terribleAggregations = collection.map(function(image) {
  return image.set(image.reduceRegion({
    reducer: 'mean',
    geometry: image.geometry(),
    scale: 30,
    maxPixels: 1e9
  }));
});

// Error: Quota exceeded: 并发聚合过多。
print(terribleAggregations);

假设这段代码的目的是获取每个图像的图像统计信息,一个可能的解决方案是Export结果。例如,使用ImageCollectionFeatureCollection可以将与图像关联的元数据导出为表格:

- 使用Export

代码语言:javascript复制
Export.table.toDrive({
  collection: terribleAggregations,
  description: 'terribleAggregations',
  fileFormat: 'CSV'
});
超出用户内存限制

您的算法在 Earth Engine 中并行化的一种方法是将输入拆分为瓦片,在每个瓦片上单独运行相同的计算,然后组合结果。因此,计算输出图块所需的所有输入都必须适合内存。例如,当输入是具有许多波段的图像时,如果所有波段都用于计算,则最终可能会占用大量内存。为了演示,这个例子通过强制(不必要地)整个图像集合到一个图块中使用了太多内存:

不好——不要这样做!

代码语言:javascript复制
var memoryHog = ee.ImageCollection('LANDSAT/LT05/C01/T1')
  .toArray()
  .arrayReduce(ee.Reducer.mean(), [0])
  .arrayProject([1])
  .arrayFlatten([['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'QA']])
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,
    bestEffort: true,
  });

// Error: 用户内从超出
print(memoryHog);

这段非常糟糕的代码展示了一个不使用数组的原因,除非您确实需要(另请参阅“避免不必要地转换类型”部分)。当该集合转换为一个巨大的数组时,该数组必须一次全部加载到内存中。因为它是一个很长的时间序列图像,所以数组很大并且主机不适合计算如此巨大的内存。

一种可能的解决方案是tileScale参数设置为更高的值。较高的 tileScale 值会导致图块缩小 1 倍 tileScale^2。例如,以下允许计算成功:

代码语言:javascript复制
var smallerHog = ee.ImageCollection('LANDSAT/LT05/C01/T1')
  .toArray()
  .arrayReduce(ee.Reducer.mean(), [0])
  .arrayProject([1])
  .arrayFlatten([['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'QA']])
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,//这个像素点也可以扩大
    bestEffort: true,//这个参数默认就是最好的
    tileScale: 16//添加这个可以导致图块缩小一倍所以效率极大提升
  });

print(smallerHog);

但是,更受欢迎的解决方案是不要不必要地使用数组,因此您根本不需要摆弄tileScale

——避免数组!从一开始就减少.toArray()

代码语言:javascript复制
var okMemory = ee.ImageCollection('LANDSAT/LT05/C01/T1')
  .mean()
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,
    bestEffort: true,
  });

print(okMemory);

除非有必要解决内存错误,否则不应将tileScale 较小的切片设置为也会导致较大的并行化内存消耗。

内部错误

您可能会遇到类似于以下内容的错误:

发生内部错误。

如果您收到此错误,请单击控制台中显示的“报告错误”链接。您还可以通过“帮助” 按钮发送反馈。此错误可能是由于脚本中的逻辑错误导致的,这些错误只会在运行时变得明显,或者是 Earth Engine 的内部工作问题。在任何一种情况下,错误都是无意义的,应该报告以便修复。

内部错误包括一个requestID,如下所示:

(request: 4b14e62b-f73f-49cc-9cf7-901cad12058b)

这些字符串充当唯一标识符,帮助地球引擎团队识别特定问题。请在错误报告中包含此字符串。

0 人点赞