使用numpy / scipy将矩阵堆栈中的每一层卷积

时间:2019-02-01 22:06:52

标签: python numpy convolution

假设我有一堆形状为<div class="container"> <div class="scaled"></div> </div>的矩阵A和一个形状为N*H*W的过滤器B。我想计算以下内容:

h*w

最快的方法是什么?

1 个答案:

答案 0 :(得分:0)

这是矢量化的代码:

C = scipy.signal.convolve(
    A,
    B[np.newaxis, ...],
    mode='same'
)

但是,令人惊讶的是,np.stack的速度比N慢,从10到10000,(H, W) = (84, 84)(h, w) = (13, 13)(这些是我对特定问题感兴趣的值)。

comparison of stacked and vectorized

基准测试代码(将在IPython中运行):

import numpy as np
import scipy.signal

import pandas as pd
import seaborn as sns

H, W = 84, 84
h, w = 13, 13

def benchmark(N):
    A = np.random.normal(size=(N, H, W))
    B = np.random.normal(size=(h, w))

    t1 = %timeit -qo np.stack([scipy.signal.convolve(A[i, :, :], B, mode='same') for i in range(N)])
    t2 = %timeit -qo scipy.signal.convolve(A, B[np.newaxis, ...], mode='same')

    return t1.timings, t2.timings

Ns = (10**np.linspace(1, 4, 16)).round().astype(int)

results = [benchmark(N) for N in Ns]

ns = []
timings = []
run_type = []

for N, (t1_timings, t2_timings) in zip(Ns, results):
    cnt = len(t1_timings)
    ns.extend([N] * cnt)
    timings.extend(t1_timings)
    run_type.extend(['stack'] * cnt)

    cnt = len(t2_timings)
    ns.extend([N] * cnt)
    timings.extend(t2_timings)
    run_type.extend(['vectorized'] * cnt)

df = pd.DataFrame({'N': ns, 'timings': timings, 'type': run_type})
sns.lineplot(x='N', y='timings', hue='type', data=df)