Я выполняю операцию, которая включает в себя различные операции (вычитание, возведение в квадрат, широковещание) на массиве больших размеров. Мой код даёт Memory Error
при выполнении таких операций.
Мой код ниже -
from skimage.segmentation import find_boundaries
w0 = 10
sigma = 5
def make_weight_map(masks):
"""
Generate the weight maps as specified in the UNet paper
for a set of binary masks.
Parameters
----------
masks: array-like
A 3D array of shape (n_masks, image_height, image_width),
where each slice of the matrix along the 0th axis represents one binary mask.
Returns
-------
array-like
A 2D array of shape (image_height, image_width)
"""
masks = masks.numpy()
nrows, ncols = masks.shape[1:]
masks = (masks > 0).astype(int)
distMap = np.zeros((nrows * ncols, masks.shape[0]))
X1, Y1 = np.meshgrid(np.arange(nrows), np.arange(ncols))
X1, Y1 = np.c_[X1.ravel(), Y1.ravel()].T
#In the below for loop, I am getting the Memory Error
for i, mask in enumerate(masks):
# find the boundary of each mask,
# compute the distance of each pixel from this boundary
bounds = find_boundaries(mask, mode='inner')
X2, Y2 = np.nonzero(bounds)
xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
ix = np.arange(distMap.shape[0])
if distMap.shape[1] == 1:
d1 = distMap.ravel()
border_loss_map = w0 * np.exp((-1 * (d1) ** 2) / (2 * (sigma ** 2)))
else:
if distMap.shape[1] == 2:
d1_ix, d2_ix = np.argpartition(distMap, 1, axis=1)[:, :2].T
else:
d1_ix, d2_ix = np.argpartition(distMap, 2, axis=1)[:, :2].T
d1 = distMap[ix, d1_ix]
d2 = distMap[ix, d2_ix]
border_loss_map = w0 * np.exp((-1 * (d1 + d2) ** 2) / (2 * (sigma ** 2)))
xBLoss = np.zeros((nrows, ncols))
xBLoss[X1, Y1] = border_loss_map
# class weight map
loss = np.zeros((nrows, ncols))
w_1 = 1 - masks.sum() / loss.size
w_0 = 1 - w_1
loss[masks.sum(0) == 1] = w_1
loss[masks.sum(0) == 0] = w_0
ZZ = xBLoss + loss
return ZZ
Чтобы воспроизвести проблему, массив значений 4,584, 565
может воссоздать проблему.
Трассировка ошибки -
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
<ipython-input-32-0f30ef7dc24d> in <module>
----> 1 img = make_weight_map(img)
<ipython-input-31-e75a6281476f> in make_weight_map(masks)
34 xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
35 ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
---> 36 distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
37 ix = np.arange(distMap.shape[0])
38 if distMap.shape[1] == 1:
MemoryError:
При использовании входа 4,584, 565
форма -
X1.shape
(329960,)
X2.shape,Y2.shape# for first iteration
(15239,) (15239,)
Основная проблема возникает в этой строке (X2.reshape(-1, 1) - X1.reshape(1, -1))
потому что форма X2 (15239,1)
, а X1 IS (1,329960)
, поэтому сначала нужно было выполнить огромную операцию широковещания.
distmap, я не могу рассчитать, потому что мой код останавливается до этого.
Кроме того, если я попытаюсь выполнить следующую операцию вычитания с указанным выше размером, код также остановится.
X2.reshape(-1, 1) - X1.reshape(1, -1)
Я использую систему 32 ГБ ОЗУ, я также пытался работать в облаке64 ГБ ОЗУ. Я проверил нижеприведенные вопросы, и они либо не дают решения моей проблемы, либо я не могу применить к своему случаю использования.
Python / Numpy MemoryError
Работа с большими данными в Python и NumPy, не хватает оперативной памяти, как сохранить частичные результаты на диске?
Увеличение памяти с широковещательными операциями в NumPy