在图像处理和分类网络中,一个常见的任务是输入图像与一些固定滤波器的卷积或互相关。例如,在卷积神经网络(CNN)中,这是一种极其常见的操作。我已将通用版本任务减少为:
Given:一批 N 个图像 [N,H,W,D,...] 和一组 K 个滤镜 [K,H,W,D,...]
Return:一个 ndarray,表示 N 中的每个 N_i 和 K 中的 K_j 的图像 N_i 与滤波器 K_j 的 m 维互相关 (xcorr)
现在,我在自定义函数上使用 scipy.spatial.cdist,该函数表示两个 m-dim 图像的 xcorr 的最大值,即 scipy.signal.correlate。代码看起来像这样:
from scipy.spatial.distance import cdist
from scipy.signal import correlate
def xcorr(u,v):
'''unfortunately, cdist only takes 2D arrays, so need to do this'''
u = np.reshape(u, [96,96,3])
v = np.reshape(v, [96,96,3])
return np.max(correlate(u,v,mode='same',method='fft'))
batch_images = np.random.random([500,96,96,3])
my_filters = np.random.random([1000,96,96,3])
# unfortunately, cdist only takes 2D arrays, so need to do this
batch_vec = np.reshape(batch_images, [-1,np.prod(batch_images.shape[1:])])
filt_vec = np.reshape(my_filters, [-1,np.prod(my_filters.shape[1:])])
answer = cdist(batch_vec, filt_vec, xcorr)
该方法有效,而且 cdist 可以自动跨线程并行化,这很好,但实际上速度很慢。我猜测这是由于多种原因造成的,包括线程之间缓存的非最佳使用(例如,在过滤所有图像时将一个过滤器固定在缓存中,反之亦然)、xcorr 内部的重塑操作等。
社区有什么想法可以加快速度吗?我意识到在我的示例中 xcorr 取两个图像之间的互相关性的最大值,但这只是一个适合与 cdist 一起使用的示例。理想情况下,您可以执行此批处理操作并使用其他一些函数(或不使用)来获得您想要的输出。理想的解决方案可以处理(R、G、B、D……)数据。
尽管首选 Python/numpy 解决方案,但任何/所有帮助都值得赞赏,包括但不限于包装 C。我看到了一些与 einsum 表示法相关的帖子,但我对此不太熟悉,所以任何帮助将不胜感激。我欢迎张量流解决方案,如果它们能够获得与相应的慢速 numpy 版本相同的答案(在合理的精度内)。