Функция Pytorch Argrelmax (или C ++) - PullRequest
       7

Функция Pytorch Argrelmax (или C ++)

0 голосов
/ 03 февраля 2019

Я пытаюсь найти эквивалентный pytorch (или C ++) для scipy.signal.argrelmax (), который находит пики в одномерном массиве с некоторыми отступами.https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.argrelmax.html

Вот то, что я придумал, и это быстрее, чем scipy.signal.argrelmax - но я упускаю быстрое решение для последнего шага, которое удаляет пики в каком-то окне.

import torch

# initalize an array (not the one in plot below)
gpu_max = torch.rand(100000)

# find peaks and troughs by subtracting shifted versions
gpu_temp1 = gpu_max[1:-1]-gpu_max[:-2]
gpu_temp2 = gpu_max[1:-1]-gpu_max[2:]

# and checking where both shifts are positive;
out1 = torch.where(gpu_temp1>0, gpu_temp1*0+1, gpu_temp1*0)
out2 = torch.where(gpu_temp2>0, out1, gpu_temp2*0)

# argrelmax containing all peaks
argrelmax_gpu = torch.nonzero(out2, out=None)+1

Таким образом, верхний график, который отмечает каждый relmaxpeak, довольно быстрый.Но нужен нижний - он исходит из scipy.signal.argrelmax () и использует временное окно 30-секундной выборки (т. Е. Он возвращает максимумы только в 60-минутном временном окне).

РЕДАКТИРОВАТЬ: я обновил код доотражает обновленный поиск torch.nonzero ().Но все же нужно выяснить, как сделать последний шаг (на рисунке ниже).enter image description here

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Хорошо, значит, у кого-то на форумах по pytorch действительно есть хорошее решение: https://discuss.pytorch.org/t/pytorch-argrelmax-or-c-function/36404

Вот полный ответ на случай, если оно будет удалено:

    a = #1D Array of  your choice
    window_maxima = torch.nn.functional.max_pool1d_with_indices(a.view(1,1,-1), width, 1, padding=width//2)[1].squeeze()
    candidates = window_maxima.unique()
    nice_peaks = candidates[(window_maxima[candidates]==candidates).nonzero()]
0 голосов
/ 03 февраля 2019

В PyTorch такого нет, и я не могу придумать простого способа эффективно реализовать его с точки зрения готовых функций, извините.Кодировать это в C ++ просто для работы довольно просто, сделать его параллельно с большим количеством зерна (думаю, CPU) также довольно просто, сделать этот запуск на GPU с 1000 ядрами сложнее, потому что вы должны найти правильный баланс между параллелизмоми повторное использование данных между вычислениями для последующих индексов.Тем не менее, если вы решите пойти по этому пути, учебник по пользовательским собственным расширениям довольно хорош.

Что касается проблемы torch.where, эта функциональность предоставляется через torch.nonzero.

РЕДАКТИРОВАТЬ: Пожалуйста, обратите внимание, что ваш подход выше может быть расширен до любого размера заполнения путем итерации в цикле for, и он не будет менее производительным алгоритмически, чем вещь scipy,который также делает довольно наивное оконное приложение argmax, вместо того, чтобы повторять с каким-нибудь умным списком приоритетов.Поэтому с поддержкой графического процессора вы все равно можете видеть приемлемую производительность (в зависимости от вашего варианта использования).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...