im2col函数
实现原理
https://blog.csdn.net/dwyane12138/article/details/78449898
im2col(input_data, filiter_h, filter_w, stride=1, pad=0)
input_data 由(数据量,通道,高,长)的4维数组构成的输入数据
filter_h 滤波器的高
filter_w 滤波器的长
stride 步幅
pad 填充
卷积层的实现:
将卷积层命为Convolution的类
from util import im2col
import numpy as np
class Convolution:
def __init__(self, W, b, stride=1, pad=0):
self.W = W
self.b = b
self.stride = stride
self.pad = pad
def forward(self, x):
FN, C, FH, FW = self.W.shape #滤波器
N, C, H, W = x.shape #数据
#先计算输出矩阵的height和width
out_h = int(1 + (H + 2*self.pad - FH) / self.stride)
out_w = int(1 + (W + 2*self.pad - FW) / self.stride)
col = im2col(x, FH, FW,self.stride, self.pad) #展开输入数据
col_W = self.W.reshape(FN, -1).T #reshape将滤波器展开为2维数组,-1是自动计算-1维度上的元素个数,即将滤波器一个个按列展开(FH*FW*C,FN)
out = np.dot(col, col_W) + self.b #计算展开后的矩阵的乘积
out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)
#tranpose会更改多维数组的轴的顺序(0,1,2,3)改成(0,3,1,2)
return out
(N条数据,C个通道,OH高,OW宽)
输出大小:
其中填充为P,步幅为S
OH=(H+2P-FH)/S +1 输出矩阵的高
OW=(W+2P-FW)/S +1 输出矩阵的宽
除不尽的时候需要采取报错等对策
过程:
池化层的实现:
from util import im2col
import numpy as np
class Pooling:
def __init__(self, pool_h, pool_w, stride=1, pad=0):
self.pool_h = pool_h
self.pool_w = pool_w
self.stride = stride
self.pad = pad
def forward(self, x):
N, C, H, W = x.shape
out_h = int(1 + (H - self.pool_h) / self.stride)
out_w = int(1 + (W - self.pool_w) / self.stride)
#展开
col = im2col(x, self.pool_h, self.pool_w, self.stride,self.pad)
col = col.reshape(-1, self.pool_h*self.pool_w)
#求各行的最大值
out = np.max(col, axis = 1)
#转换
out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)
return out
CNN的实现:
网络构成是Convolution - ReLU - Pooling - Affine - ReLU - Affine - Softmax,将其命为SimpleConvNet的类