Передача массива CuPy через фильтр нижних частот scipy

#python #arrays #numpy #scipy #cupy

#python #массивы #numpy #scipy #cupy

Вопрос:

Я хочу отправить некоторые данные через встроенный фильтр нижних частот scipy. Я тестировал его с некоторыми массивами данных numpy, приведенными ниже. Он отлично работает и выводит отфильтрованные значения при использовании numpy. Затем я хотел посмотреть, смогу ли я использовать графический процессор и ускорить работу, и услышал о CuPy, который работает аналогично numpy. Однако, когда я заменяю массив numpy массивом cupy, я получаю следующую ошибку ValueError: could not convert b, a, and x to a common type

 from scipy.signal import butter, lfilter, freqz
import cupy as cp
import time
import numpy as np

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return b, a

def butter_lowpass_filter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs, order=order)
    y = lfilter(b, a, data)
    return y

order = 1
fs = 30.0       
cutoff = 0.3 

new_frame_np = np.ones(100)*3
new_frame_cp = cp.ones(100)*3

y = butter_lowpass_filter(new_frame_np, cutoff, fs, order) #WORKS
y = butter_lowpass_filter(new_frame_cp, cutoff, fs, order) #DOES NOT WORK
  

Как я могу заставить массивы cupy работать в приведенном выше примере?

Scipy, похоже, работает с задачами процессора, поэтому, возможно, он не может работать с массивами cupy графического процессора. Я не смог найти ни одной библиотеки, предоставляющей фильтр нижних частот или полосовой фильтр для массивов cupy.

Комментарии:

1. Вы не можете использовать массивы GPU с scipy.signal. Для обработки сигналов на основе GPU вам следует посмотреть на cuSignal или torch.audio (pytorch)

2. Я просмотрел cuSignal и просто для подтверждения, firwin() — это то, что может правильно выполнить фильтрацию? Не было ничего, что явно называлось фильтром нижних частот

Ответ №1:

Я создатель cuSignal. В прошлом мы потратили некоторое время на то, чтобы ускорить работу SciPy с помощью GPU lfilter , но для фильтров ARMA lfilter использует форму DF-II, которая зависит от данных, что затрудняет распараллеливание. Есть способы обойти это (например, распараллеливание с помощью нескольких сигналов, отфильтрованных одновременно), но в итоге мы назвали это «заблокированным».

Тем не менее, у нас есть поддержка фильтра FIR с помощью метода FFT. По сути, это то же самое, что и fftconvolve , но оно завернуто, как cusignal.firfilter в нашем выпуске nightly conda (или если вы создаете из исходного кода с переходом 0.16).

Вы можете сделать что-то вроде:

 >>> from scipy import signal
>>> import cupy as cp
>>> import cusignal
>>> [b, a] = signal.butter(3, 0.5)
>>> b = cp.asarray(b)
>>> x = cp.random.randn(2**8)
>>> y = cusignal.firfilter(b, x)
  

В качестве примечания, в настоящее время мы не поддерживаем дизайн фильтра Баттерворта и зависим от scipy для генерации коэффициентов перед их переносом в память GPU (с cupy.asarray ).

Комментарии:

1. Спасибо за ответ, есть какие-либо обновления по этому поводу?