2017-08-07 49 views
2

我有一批的存储在数组中xbm x n图像,和卷积滤波器尺寸p x q,我想应用到每个图像的f在批处理(然后使用总和池和存储在一个阵列y),即all(np.allclose(y[i][j][k], (x[i, j:j+p, k:k+q] * f).sum()) for i in range(b) for j in range(m-p+1) for k in range(n-q+1))为真。批量卷积2d在numpy没有scipy?

适应this answer,我可以写:

b, m, n, p, q = 6, 5, 4, 3, 2 
x = np.arange(b*m*n).reshape((b, m, n)) 
f = np.arange(p*q).reshape((p, q)) 
y = [] 
for i in range(b): 
    shape = f.shape + tuple(np.subtract(x[i].shape, f.shape) + 1) 
    strides = x[i].strides * 2 
    M = np.lib.stride_tricks.as_strided(x[i], shape=shape, strides=strides) 
    y.append(np.einsum('ij,ijkl->kl', f, M)) 
assert all(np.allclose(y[i][j][k], (x[i, j:j+p, k:k+q] * f).sum()) for i in range(b) for j in range(m-p+1) for k in range(n-q+1)) 

,但我觉得有一种方法,只用一个einsum做到这一点,因为b通常是100和1000

之间这将是对我有用的

如何使我的方法适应仅使用一个einsum?此外,对于我的目的,我不能带scipy或除numpy之外的任何其他依赖项。

回答

3

只需要将shape设为5d即可得到strides以匹配shape

shape = f.shape + (x.shape[0],) + tuple(np.subtract(x.shape[1:], f.shape) + 1) 
strides = (x.strides * 2)[1:] 
M = np.lib.stride_tricks.as_strided(x, shape=shape, strides=strides) 
y = np.einsum('pq,pqbmn->bmn', f, M) 

现在M可能会得到非常大的,如果b变得非常大,但它适用于你的玩具问题。

+0

另一个类似的问题,如果你有兴趣:https://stackoverflow.com/questions/45580013/pure-numpy-2d-mean-convolution-derivative-of-input-image – michaelsnowden