Я пытаюсь обучить модель семантической сегментации глубокого обучения для спутниковых изображений. При этом я без каких-либо проблем провел тестовый прогон данных на небольшом AOI с patchify и rasterio. Однако сейчас я пытаюсь расширить это, включив в него гораздо больше патчей для обучения модели, и для этого увеличил свой угол обзора. Для контекста: раньше у меня был ndarray примерно 41848x14555x9 (x, y, n_bands). Теперь я хочу увеличить это значение до 84632x37000x9 (x, y, n_bands).
К сожалению, numpy не удается даже попытаться загрузить массив в память с помощью rasterio из-за того, что большой размер невозможен при имеющейся у меня памяти, размер массива составляет 128 ГБ, а моя ОЗУ — 32 ГБ. Сообщение об ошибке ниже:
numpy.core._exceptions._ArrayMemoryError: Unable to allocate 120. GiB for an array with shape (9, 42170, 84632) and data type float32
Я попытался использовать комбинацию rioxarray/ xarray и np.memmap из-за доступных ленивых массивов, однако заполнение карты памяти происходит невероятно медленно, поскольку мне приходится перебирать полосы и ось, чтобы значения вписывались в объем памяти, который у меня есть, т.е.:
image_io = rioxarray.open_rasterio(/path/to/image_stack.tif)
raster = np.memmap(memmap_name, dtype=np.float32, mode='w+', shape=(image_io.shape[0], image_io.shape[1], image_io.shape[2]))
for i in range(len(image_io.band) + 1):
for j in range(len(image_io.x) + 1):
raster[j, :, i] = image_io[j, :, i].values
Я думаю, что самое важное, что я должен спросить, это вообще возможно ли это с имеющимися у меня аппаратными ресурсами?
Если да, то есть ли лучший способ сделать это, чем подход, который я перечислил выше?
Я не собираюсь использовать patchify, но, похоже, это библиотека перехода, используемая для создания фрагментов изображений меньшего размера. Заранее благодарю за любой совет!






Использование Xarray + Dask + Xbatcher может оказаться здесь продуктивной альтернативой. Псевдокод ниже:
# open tiff as a xarray.DataArray backed by a lazy dask array
# you can tune the chunk size to the size of your patch
chunks= {'x': xc, 'y': yc, 'n_bands': bc}
da = rioxarray.open_rasterio('/path/to/image_stack.tif', chunks=chunks)
# create the xbatcher.BatchGenerator, this will let you iterate through your
# DataArray in smaller-than-memory batches.
bgen = xbatcher.BatchGenerator(da, {'x': xc, 'y': yc, 'n_bands': bc})
for patch in bgen:
# handle patch
Xbatcher работает отлично — спасибо!