提高纯Numpy / Scipy卷积神经网络实现的速度

时间:2015-08-12 18:41:03

标签: python algorithm numpy neural-network

背景

我已经训练了一个卷积神经网络,我希望其他人能够使用而不需要很难安装像Theano这样的库(我发现在Linux上安装很简单,但在Windows上很难安装)。 / p>

我使用Numpy / Scipy编写了一个几乎足够快的实现,但如果速度提高两到三倍会更好。

我尝试了什么

90%的时间花在以下一行:

1: In `[.data.table`(DT, , `:=`(2:ncol(DF), mat[, 2:ncol(DF)]), with = FALSE) :
  2 column matrix RHS of := will be treated as one vector

此行被调用32次(每个要素图一次),num_in为16(前一层中的要素数)。总的来说,这一行很慢,因为它导致对convolve2d例程的32 * 16 = 512次调用。

x [i]仅为25 * 25,W [f] [i]为2 * 2.

问题

有没有更好的方法在Numpy / Scipy中表达这种类型的卷积层会更快执行?

(我只使用此代码来应用学习型网络,因此我没有很多图像可以并行完成。)

代码

进行计时实验的完整代码是:

conv_out = np.sum([scipy.signal.convolve2d(x[i],W[f][i],mode='valid') for i in range(num_in)], axis=0)

此刻打印0.084秒。

更新

使用mplf的建议:

import numpy as np
import scipy.signal
from time import time

def max_pool(x):
    """Return maximum in groups of 2x2 for a N,h,w image"""
    N,h,w = x.shape
    return np.amax([x[:,(i>>1)&1::2,i&1::2] for i in range(4)],axis=0)

def conv_layer(params,x):
    """Applies a convolutional layer (W,b) followed by 2*2 pool followed by RelU on x"""
    W,biases = params
    num_in = W.shape[1]
    A = []
    for f,bias in enumerate(biases):
        conv_out = np.sum([scipy.signal.convolve2d(x[i],W[f][i],mode='valid') for i in range(num_in)], axis=0)
        A.append(conv_out + bias)
    x = np.array(A)
    x = max_pool(x)
    return np.maximum(x,0)

W = np.random.randn(32,16,2,2).astype(np.float32)
b = np.random.randn(32).astype(np.float32)
I = np.random.randn(16,25,25).astype(np.float32)

t0 = time()
O = conv_layer((W,b),I)
print time()-t0

我得到0.075秒,稍快一点。

2 个答案:

答案 0 :(得分:7)

加速卷积

基于mplf的建议我发现可以删除for循环和对convolve2d的调用:

d = x[:,:-1,:-1].swapaxes(0,1)
c = x[:,:-1,1:].swapaxes(0,1)
b = x[:,1:,:-1].swapaxes(0,1)
a = x[:,1:,1:].swapaxes(0,1)
x = W[:,:,0,0].dot(a) + W[:,:,0,1].dot(b) + W[:,:,1,0].dot(c) + W[:,:,1,1].dot(d) + biases.reshape(-1,1,1)

这比原始代码快10倍。

加速最大游泳池

使用这个新代码,最大池阶段现在需要50%的时间。这也可以通过使用:

来加速
def max_pool(x):
    """Return maximum in groups of 2x2 for a N,h,w image"""
    N,h,w = x.shape
    x = x.reshape(N,h/2,2,w/2,2).swapaxes(2,3).reshape(N,h/2,w/2,4)
    return np.amax(x,axis=3)

这会将max_pool步骤加速10倍,因此整个程序的速度再次提高一倍。

答案 1 :(得分:5)

环顾四周,似乎scipy convolve2d函数未经优化且效率低下。从2014年1月开始就有一个未解决的问题(https://github.com/scipy/scipy/issues/3184),这个问题似乎与Improving Numpy Performance有关。

我建议您尝试the solution发布Theran,看看这是否会产生更好的效果。