用numpy库手写算子一:Conv2d
前言
我们经常可以调用pytorch,tensorflow库等来实现我们的神经网络,但是有的时候需要开发自己的框架,这个时候就得了解每一个算子的计算规则,了解这些计算规则也有助于我们了解他们的计算特性,然后就可以在底层优化上面有一定的针对性。
Conv2d
def conv_forward_naive(x, w, stride, pad, b = None):
x = np.pad(x, ((0, 0),(0 ,0),(pad, pad),(pad, pad)),'constant')
n, ic, ih, iw = x.shape
oc, _, kh, kw = w.shape
H_new = int(1 + (ih - kh) / stride)
W_new = int(1 + (iw - kw) / stride)
out = np.zeros((n, oc, H_new, W_new))
for i in range(H_new):
for j in range(W_new):
x_windows = x[:, :, i * stride : i * stride + kh, j * stride : j * stride + kw]
for k in range(n):
for l in range(oc):
out[k, l, i, j] = np.sum(x_windows[k] * w[l])
if b != None:
out[k, l, i, j] += b
return out
对于conv2d的前向而言:
默认input数据布局为(N,C,H,W),N代表batch_size,C代表input_channel,H代表input_height,W代表input_width.
默认filter数据布局为(N,C,H,W),N代表filter_multiplier,C代表input_channel,H代表kernel_height,W代表kernel_width。
stride代表的是(stride__h,stride_w)。
pad代表的是(pad_h,pad_w)。
b代表的是bias,默认值是none.
上述代码所代表的意思是首先根据输入,计算输出的大小,然后遍历输出的点,对应输出的点(k,l,i,j),其对应的input的范围为是(k,:,i * stride : i * stride + kh, j * stride : j * stride + kw),其对应的filter的范围是filter的范围是(k,:,:,:)。相当于取出来两个立体方框,然后相乘,再累加。
版权声明:本文为free1993原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。