2017-08-07 122 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