Оптимизация использования памяти в numpy

Следующие загрузки программы два изображения с PyGame, преобразовывает их в массивы Numpy и затем выполняет некоторые другие операции Numpy (такие как FFT) для испускания конечного результата (нескольких чисел). Исходные данные могут быть большими, но в любой момент только один или два больших объекта должны быть живыми.

Тестовое изображение о 10M пиксели, который переводит в 10 МБ, после того как это - greyscaled. Это преобразовывается в массив Numpy dtype uint8, который после некоторой обработки (применение окон Хэмминга), массив dtype float64. Два изображения загружаются в массивы этот путь; позже FFT ступает результат в массив dtype complex128. До добавления чрезмерного gc.collect вызовы, размер памяти программ имел тенденцию увеличиваться с каждым шагом. Кроме того, кажется, что большинство операций Numpy даст результат в самой высокой доступной точности.

Запущение теста (без gc.collect вызовы) на моих результатах машины Linux на 1 ГБ в длительной перегрузке, которой я не ожидал. У меня еще нет подробной статистики использования памяти - я попробовал некоторые модули Python и time команда напрасно; теперь я изучаю valgrind. Наблюдение PS (и контакт с безразличностью машины на более поздних этапах теста) предлагают максимальное использование памяти приблизительно 800 МБ.

10 миллионов массивов ячеек complex128 должны занять 160 МБ. Наличие (идеально) самое большее двух из них живет когда-то, плюс не - иллюзорные библиотеки Python и Numpy и другие принадлежности, вероятно, средства допускать 500 МБ.

Я могу думать о двух углах, от которых можно приняться за решение проблемы:

  • Отбрасывание промежуточного звена выстраивает как можно скорее. Это что gc.collect вызовы для - они, кажется, улучшили ситуацию, поскольку она теперь завершается только с несколькими минутами перегрузки ;-). Я думаю, что можно ожидать, что интенсивно использующее память программирование на языке как Python потребует некоторого ручного вмешательства.

  • Используя менее - точный Numpy выстраивает на каждом шаге. К сожалению, операции это возвращаемые массивы, как fft2, кажись, не позволить типу быть указанным.

Таким образом, мой основной вопрос: существует ли способ указать выходную точность в операциях над массивом Numpy?

В более общем плане есть ли другие сохраняющие общую память методы при использовании Numpy?

Кроме того, Numpy имеет более идиоматический способ освободить матрицу элементов памяти? (Я предполагаю, что это оставило бы объект массива живым в Python, но в неприменимом состоянии.) Явное удаление, сопровождаемое непосредственным GC, чувствует hacky.

import sys
import numpy
import pygame
import gc


def get_image_data(filename):
    im = pygame.image.load(filename)
    im2 = im.convert(8)
    a = pygame.surfarray.array2d(im2)
    hw1 = numpy.hamming(a.shape[0])
    hw2 = numpy.hamming(a.shape[1])
    a = a.transpose()
    a = a*hw1
    a = a.transpose()
    a = a*hw2
    return a


def check():
    gc.collect()
    print 'check'


def main(args):
    pygame.init()

    pygame.sndarray.use_arraytype('numpy')

    filename1 = args[1]
    filename2 = args[2]
    im1 = get_image_data(filename1)
    im2 = get_image_data(filename2)
    check()
    out1 = numpy.fft.fft2(im1)
    del im1
    check()
    out2 = numpy.fft.fft2(im2)
    del im2
    check()
    out3 = out1.conjugate() * out2
    del out1, out2
    check()
    correl = numpy.fft.ifft2(out3)
    del out3
    check()
    maxs = correl.argmax()
    maxpt = maxs % correl.shape[0], maxs / correl.shape[0]
    print correl[maxpt], maxpt, (correl.shape[0] - maxpt[0], correl.shape[1] - maxpt[1])


if __name__ == '__main__':
    args = sys.argv
    exit(main(args))
8
задан Edmund 30 June 2010 в 03:20
поделиться

2 ответа

Это на SO говорит: «Scipy 0.8 будет поддерживать одинарную точность почти для всего кода fft», и SciPy 0.8.0 beta 1 только что вышла.
(Сам не пробовал, трусливый.)

1
ответ дан 6 December 2019 в 01:39
поделиться

Если я правильно понимаю, вы вычисляете свертку между двумя изображениями. Пакет Scipy содержит специальный модуль для этого ( ndimage ), который может быть более эффективным с точки зрения памяти, чем "ручной" подход с помощью преобразований Фурье. Было бы хорошо попробовать использовать его вместо того, чтобы проходить через Numpy.

1
ответ дан 6 December 2019 в 01:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: