Numpy массив: как отменить нулевое заполнение без копирования массива? - PullRequest
0 голосов
/ 03 апреля 2020

Я работаю над сегментацией трехмерных изображений с глубоким обучением. По сути, мне нужно 1 / заполнить массив numpy, 2 / обработать массив, 3 / распаковать массив.

dataArray = np.pad(dataArray, 25, mode='constant', constant_values=0) # pad
processedArray = my_process(dataArray) # process
processedArray = processedArray[25:-25, 25:-25, 25:-25, :] # unpad

Проблема в том, что processingArray очень большой (464 928 928 928,10), и я запускаю в нехватку памяти при выполнении распаковки. Я представляю, что unpadding выделяет новую память? Я прав? Как я могу продолжить, чтобы не было выделено новой памяти? Другими словами, чтобы индекс указывал на не дополняемые элементы, не копируя элементы?

Информация, которая может помочь: вышеуказанные строки выполняются в функции, а обработанный массив возвращается

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Возможное решение проблемы с памятью - использование типа данных short вместо float в качестве numpy. Вы можете попробовать это.

dataArray = np.pad(dataArray, 25, mode='constant', constant_values=0) # pad
processedArray = my_process(dataArray).astype(np.short) # process
processedArray = processedArray[25:-25, 25:-25, 25:-25, :] # unpad
processedArray = processedArray.astype(np.float32) #Converting to float type again

Кроме того, вы можете удалить dataArray, чтобы создать место для processedArray.

dataArray = np.pad(dataArray, 25, mode='constant', constant_values=0) # pad
del dataArray #deleting dataArray to claim memory
processedArray = my_process(dataArray) # process
processedArray = processedArray[25:-25, 25:-25, 25:-25, :] # unpad
0 голосов
/ 03 апреля 2020

Возможно, вам не хватает памяти, потому что как только вы вызываете функцию с этим массивом, внутри функции создается копия, которая удваивает вашу память. Поэтому не создавайте лишних массивов.

Вы можете сохранить глобальную копию массива. Просто примените операции к глобальному массиву без создания дополнительной копии.

import gc

global processedArray # before all your assignment starts

внутри my_process ()

def my_process():
   global processedArray
   # do all operations on processedArray
global processedArray
processedArray = np.pad(dataArray, 25, mode='constant', constant_values=0) # pad
my_process()

del dataArray() # delete not needed arrays to make more space
gc.collect()

global processedArray
processedArray = processedArray[25:-25, 25:-25, 25:-25, :] # unpad

Но, тем не менее, вам не хватит памяти, если ваш my_process вызывает больше библиотечных функций, которые копируют обработанный массив. Попробуйте применить все операции к глобальному массиву, не создавая никаких копий.

...