将tensorflow conv2d转换为numpy/scipy操作



这是tf.nn.conv2d的文档:给定形状为[批处理,in_height,in_width,in_channels]的输入张量和形状为[滤波器_height、滤波器_width、in_channel,out_channels]的滤波器/核张量,此操作执行以下

  1. 将滤波器展平为形状为[filter_height的二维矩阵*滤波器_宽度*in_
  2. 从输入张量中提取图像块,以形成形状为[批,out_height,out_width,filter_height*filter_width*in_channels]
  3. 对于每个面片,右乘滤波器矩阵和图像面片向量

换句话说,它接受n个图像的张量,并与out_channel滤波器进行卷积。

我正试图翻译成只使用numpy操作的代码,代码如下:

def my_conv2d(x, kernel):
nf = kernel.shape[-1]  # number of filters
rf = kernel.shape[0]  # filter size
w = kernel
s = 1 # stride
h_range = int((x.shape[2] - rf) / s) + 1  # (W - F + 2P) / S
w_range = int((x.shape[1] - rf) / s) + 1  # (W - F + 2P) / S
np_o = np.zeros((1, h_range, w_range, nf))
for i in range(x.shape[0]):
for z in range(nf):
for _h in range(h_range):
for _w in range(w_range):
np_o[0, _h, _w, z] = np.sum(x[i, _h * s:_h * s + rf, _w * s:_w * s 
+ rf, * w[:, :, :, z])                     
return np_o

问题是代码非常慢。有没有任何numpy或scipy函数可以复制tensorflow的conv2d正在做的具有类似效率的事情?我看过https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html它只做一次卷积,这意味着我必须在二维核的旁边传递一个二维张量(它不做多个滤波器(。之前的stackoverflow问题对这一点都没有多大帮助。

感谢

编辑:做了一些测试,我的代码比做tf.nn.conv2d慢了44000%!

由于使用的是循环,所以速度较慢。使用矢量运算实现会更快,但不如tf.nn.conv2d或tf.nn.卷积等高级API高效。这篇文章应该能够帮助您在numpy中实现相同的矢量化:https://wiseodd.github.io/techblog/2016/07/16/convnet-conv-layer/

最新更新