Улучшение производительности Numpy

Я хотел бы улучшить производительность свертки с помощью Python и надеялся на некоторое понимание о том, как лучше всего пойти об улучшении производительности.

Я в настоящее время использую scipy для выполнения свертки, с помощью кода несколько как отрывок ниже:

import numpy
import scipy
import scipy.signal
import timeit

a=numpy.array ( [ range(1000000) ] )
a.reshape(1000,1000)
filt=numpy.array( [ [ 1, 1, 1 ], [1, -8, 1], [1,1,1] ] )

def convolve():
  global a, filt
  scipy.signal.convolve2d ( a, filt, mode="same" )

t=timeit.Timer("convolve()", "from __main__ import convolve")
print "%.2f sec/pass" % (10 * t.timeit(number=10)/100)

Я обрабатываю данные изображения, с помощью шкалы полутонов (целочисленные значения между 0 и 255), и я в настоящее время получаю приблизительно четверть секунды на свертку. Мои взгляды должны были выполнить одно из следующих действий:

corepy использования, предпочтительно с некоторой оптимизацией Перекомпилировали numpy с ICC и ikml. Используйте python-cuda.

Я задавался вопросом, был ли у кого-либо опыт с каким-либо из этих подходов (какое усиление было бы типично, и если это стоит времени), или если любой знает о лучшей библиотеке для выполнения свертки с Numpy.

Спасибо!

Править:

Убыстритесь приблизительно 10x путем перезаписи цикла Python в C по использованию Numpy.

18
задан Bear 24 February 2010 в 22:08
поделиться

4 ответа

Код в Scipy для выполнения 2d сверток немного запутан и неоптимизирован. См. http://svn.scipy.org/svn/scipy/trunk/scipy/signal/firfilter.c, если вы хотите взглянуть на низкоуровневое функционирование scipy.

Если все, что вы хотите - это обработать с помощью небольшого, постоянного ядра, подобного тому, которое вы показали, такая функция может сработать:

def specialconvolve(a):
    # sorry, you must pad the input yourself
    rowconvol = a[1:-1,:] + a[:-2,:] + a[2:,:]
    colconvol = rowconvol[:,1:-1] + rowconvol[:,:-2] + rowconvol[:,2:] - 9*a[1:-1,1:-1]
    return colconvol

Эта функция использует преимущества разделяемости ядра, подобно DarenW, предложенному выше, а также использует более оптимизированные нумпеидальные арифметические процедуры. По моим измерениям она более чем в 1000 раз быстрее, чем функция convolve2d.

10
ответ дан 30 November 2019 в 09:25
поделиться

Типичной оптимизацией свертки является использование БПФ вашего сигнала. Причина в том, что свертка в реальном пространстве - это продукт в пространстве БПФ. Часто бывает быстрее вычислить БПФ, затем произведение и БПФ результата, чем выполнять свертку обычным способом.

0
ответ дан 30 November 2019 в 09:25
поделиться

Для конкретного примера ядра 3x3 я бы заметил, что

1  1  1
1 -8  1
1  1  1

  1  1  1     0  0  0
= 1  1  1  +  0 -9  0
  1  1  1     0  0  0

и что первый из них является факторизуемым - его можно свернуть с помощью свертки (1 1 1) для каждой строки, а затем снова для каждого столбца. Затем вычтите девять раз исходные данные. Это может быть или не быть быстрее, в зависимости от того, достаточно ли умны умные программисты, чтобы делать это автоматически. (Я давно не проверял.)

Вы, вероятно, захотите сделать более интересные свертки, где факторинг может быть, а может быть, невозможен.

2
ответ дан 30 November 2019 в 09:25
поделиться

Пытались ли вы передать параметр SqlBulkOptions.TaureLock в SqlBulkCopy? Этот параметр (цитата) означает, что будет:

Получить блокировку массового обновления для длительность операции массового копирования.

Таким образом, если существует другая обработка, блокирующая таблицу, это предотвратит получение блокировки и, теоретически, надежное тайм-аут.

Обновление:
Я настроил свой тестовый жгут и не могу воспроизвести. Чтобы заблокировать таблицу, я запустил транзакцию в SSMS, выполнив SELECT * FROM TargetTable WITH (HOLDLOCK) . Я использовал тот же метод BulkCopy, который вы включили в вопрос, используя внутренние транзакции, с тайм-аутом массовой загрузки 30 секунд. Каждая попытка выполнить массовое копирование тайм-аута, как ожидалось, через 30 секунд. После этого выполняется откат транзакции SSMS.

Я использовал SQL Server 2008 Express, .NET 3.5.

Это не то, что после первой попытки, тайм-аут массовой загрузки не передается правильно? то есть это как-то не устанавливается на «неопределенный».

Обновление 2:
Также включена поддержка нескольких активных результирующих наборов в последовательности подключения, по-прежнему постоянно тайм-аут для меня каждый раз.

-121--3723745-

Первое, что я должен сказать - «здесь нет правильного ответа».

Java может делать именно то, что вы хотите. Инструментарий GUI, после многих лет доработки, очень продвинутый. Существует также множество инструментов, рамок и расширений, которые можно использовать для того, чтобы графический интерфейс выглядел очень продвинутым.

Java также имеет отличную рамку подключения к БД. С помощью инструментов объектного реляционного отображения (ORM) (Hibernate и другие) довольно легко получить данные из БД, поместить их в Objects, манипулировать ими и поместить обратно в базу данных. Инструменты ORM также упрощают подключение объектов данных непосредственно к графическому интерфейсу пользователя и используют правила в этих объектах для защиты данных от повреждения.

Кроссплатформенная поддержка вам очень поможет. Единственным важным пунктом является наличие среды выполнения Java на машине для файлов. Есть способы обойти это (лучшее, чтобы установщик поставил его там).

-121--3049978-

Прежде чем говорить C с помощью ctypes, я бы предложил запустить автономный сверток в C, чтобы увидеть, где предел.
Аналогично для CUDA, cython, scipy.wave...

Добавленные 8-битовые данные 7feb: convolve33 с отсечкой занимают ~ 20 тактовых циклов на точку, 2 тактовых цикла на mem-доступ, на моем mac g4 pcc с gcc 4.2. Ваш пробег будет различаться.

Пара тонкостей:

  • вас волнует правильная вырезка к 0.. 255? np.clip () медленный, cython и т.д. не знают.
  • Numpy/scipy может потребоваться память для temps размером A (поэтому сохраните 2 * sizeof (A) < размер кэша).
    Однако, если ваш код C выполняет обновление на месте, это половина mem, но другой алгоритм.

По пути google theano convolve = > "Свертка, которая должна имитировать scipy.signal.convolve2d, но быстрее! В разработке "

1
ответ дан 30 November 2019 в 09:25
поделиться
Другие вопросы по тегам:

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