卷积神经网络(CNN)一般由卷积层(Convolution 层)、池化层(Pooling 层)和全连接层构成
在全连接层中,相邻层的神经元全部连接在一起,输出的额数量可以任意决定。但是在全连接层中,数据的形状被忽视了,所有的数据都是由1维向量构成。例如图像通常是通道、高、长三方面的数据,如(1, 28, 28),在全全连接层中却被排1列,以12828个数据的形式保存。
因为全连接层会忽视形状,进全部的输入数据作为相同的额神经元(同一维度的神经元)进行处理,所以无法利用与形状相关的信息。
而卷积层可以保持形状不变。
另外在CNN中,在卷积层中输入输出的数据成为特征图(feature map),输入数据称为输入特征图(input feature map),输出数据称为输出特征图(output feature map)
卷积运算相当于图像处理中的“滤波器运算”,在有的地方也用“核(kernel)”来表示滤波器(filter)。
卷积运算即是讲各个位置上的滤波器元素和输入的对应元素相乘,然后再求和(有时称为乘积累加运算)
滤波器中的元素即对应权重,有时还会在后面加上偏置(1*1)
即在进行卷积层的处理之前,想输入数据的周围填入固定的额数据(例如0等)
填充是在数据的四周填充,例如对(4, 4)的输入数据应用幅度为1的填充,则填充后的数据大小为(6, 6)。
使用填充主要是为了调整输出的大小
即应用滤波器的位置间隔。
例:将步幅设为2,即是每间隔两个元素应用一次滤波器。
增大步幅后,输出大小会变小。而增大填充后,输出大小会变大
假设输入大小(H,W),滤波器大小(FH,FW),输出大小(OH,OW),填充为P,步幅为S。则**输出大小计算公式如下:
OH=(H+2P-FH)/S+1
OW=(W+2P-FW)/S+1
注**:所设定的值必须使上式分别可以除尽。当输出大小无法除尽时,需要采取报错等对策。根据深度学习框架的不同,当值无法除尽时,有时会进行四舍五入,不进行报错。
对于三维数据,除了高和长之外,还有通道(channel)方向。通道方向上有多个特征图时,会按通道进行输入数据和滤波器的卷积运算,并将结果相加,从而得到输出
滤波器的权重数据书写顺序(output_channel,input_channel,height,width)
批处理即是将N次的处理汇总成1次进行
保存顺序(batch_num,channel,height,width)
池化是缩小高、长方向上的空间运算。
例如:按步幅2进行22的Max池化时,“Max池化”是获取目标区域的最大值,“22”表示目标区域的大小
例:(4,4)的数据按2*2进行池化得到的是(2,2)的数据
一般来说,催化的窗口大小和步幅设定成相同的值。
Average池化:计算目标区域的平均值
池化层的特征
im2col函数:im2col为 image to column 的缩写,即“从图像到矩阵”。在Caffe、Chainer等深度学习框架中有名为im2col函数,并且在卷积层中实现,都使用了im2col。
im2col函数 会把输入数据展开以色和滤波器,即看情况把数据转换为二维或者一维
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
"""
Parameters
----------
input_data : 由(数据量, 通道, 高, 长)的4维数组构成的输入数据
filter_h : 滤波器的高
filter_w : 滤波器的长
stride : 步幅
pad : 填充
Returns
-------
col : 2维数组
"""
N, C, H, W = input_data.shape
out_h = (H + 2*pad - filter_h)//stride + 1
out_w = (W + 2*pad - filter_w)//stride + 1
img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
return col
reshape(FN, -1):当指定为-1时,reshape函数会自动计算-1维度上的元素个数,以使多维数组的元素个数前后一致。
col2im函数:将数据转换为图片
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
"""
Parameters
----------
col :
input_shape : 输入数据的形状(例:(10, 1, 28, 28))
filter_h :
filter_w
stride
pad
Returns
-------
"""
N, C, H, W = input_shape
out_h = (H + 2*pad - filter_h)//stride + 1
out_w = (W + 2*pad - filter_w)//stride + 1
col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)
img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))
for y in range(filter_h):
y_max = y + stride*out_h
for x in range(filter_w):
x_max = x + stride*out_w
img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]
return img[:, :, pad:H + pad, pad:W + pad]