gpt4 book ai didi

python - 对残差平方的numpy数组进行快速迭代

转载 作者:行者123 更新时间:2023-12-01 08:46:37 28 4
gpt4 key购买 nike

我喜欢对具有许多已知信号形状的数据(一个 numpy float 组)进行最小二乘匹配。我的代码可以运行,但对于我计划进行的多次运行来说太慢了:

import numpy
import time

samples = 50000
width_signal = 100
data = numpy.random.normal(0, 1, samples)
signal = numpy.random.normal(0, 1, width_signal) # Placeholder

t0 = time.clock()
for i in range(samples - width_signal):
data_chunk = data[i:i + width_signal]
residuals = data_chunk - signal
squared_residuals = residuals**2
summed_residuals = numpy.sum(squared_residuals)
t1 = time.clock()
print('Time elapsed (sec)', t1-t0)

编辑:更正了一个错误:先将残差平方,然后将它们相加。

在我的机器上运行大约需要 0.2 秒。由于我有很多数据集和信号形状,这太慢了。我的具体问题不允许使用典型的 MCMC 方法,因为信号形状差异太大。它必须是蛮力。

典型的数据量为 50,000 个 float ,信号为 100 个 float 。这些值可能相差几倍。

我的测试表明:

  • 数据 numpy.sum(residuals) 的总和占用了 90% 的时间。我尝试了 Python 的 sum(residuals) ,它对于小数组(~<50 个元素)更快,而对于更大的数组则更慢。我应该插入 if 条件吗?
  • 我试过numpy.roll()而不是直接取数据,.roll()比较慢。

问题:

  • 对于加速有逻辑上的改进吗?
  • 有没有更快的方法来对数组求和?我不会 C,但如果它更快,我可以试试。
  • GPU 可以提供帮助吗?我有很多运行要做。如果是这样,我在哪里可以找到执行此操作的代码片段?

最佳答案

基于 Compute mean squared, absolute deviation and custom similarity measure - Python/NumPy 中提出的各种方法,我们希望在这里解决我们的问题。

方法#1

我们可以利用 np.lib.stride_tricks.as_strided基于scikit-image's view_as_windows获得滑动窗口,从而在这里获得我们的第一个解决方案,就像这样 -

from skimage.util import view_as_windows

d = view_as_windows(data,(width_signal))-signal # diffs
out = np.einsum('ij,ij->i',d,d)

More info on use of as_strided based view_as_windows.

方法 #2

再次基于该答案帖子中的矩阵乘法技巧,我们可以提高性能,就像这样 -

def MSD_strided(data, signal):
w = view_as_windows(data,(width_signal))
return (w**2).sum(1) + (signal**2).sum(0) - 2*w.dot(signal)

方法#3

我们将通过引入统一过滤和卷积来改进方法#2 -

from scipy.ndimage.filters import uniform_filter 

def MSD_uniffilt_conv(data, signal):
hW = width_signal//2
l = len(data)-len(signal)+1
parte1 = uniform_filter(data**2,width_signal)[hW:hW+l]*width_signal
parte3 = np.convolve(data, signal[::-1],'valid')
return parte1 + (signal**2).sum(0) - 2*parte3

基准测试

发布样本的时间 -

In [117]: %%timeit
...: for i in range(samples - width_signal + 1):
...: data_chunk = data[i:i + width_signal]
...: residuals = data_chunk - signal
...: squared_residuals = residuals**2
...: summed_residuals = numpy.sum(squared_residuals)
1 loop, best of 3: 239 ms per loop

In [118]: %%timeit
...: d = view_as_windows(data,(width_signal))-signal
...: np.einsum('ij,ij->i',d,d)
100 loops, best of 3: 11.1 ms per loop

In [209]: %timeit MSD_strided(data, signal)
10 loops, best of 3: 18.4 ms per loop

In [210]: %timeit MSD_uniffilt_conv(data, signal)
1000 loops, best of 3: 1.71 ms per loop

~140x 用第三个加速!

关于python - 对残差平方的numpy数组进行快速迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52001974/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com