Chapter7_卷积神经网络
Posted suqinghang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Chapter7_卷积神经网络相关的知识,希望对你有一定的参考价值。
卷积神经网络
整体结构
- 全连接层:相邻层的所有神经元之间都有连接
- CNN的结构
- Convolution层
- ReLU层
- Pooling层
- 靠近输出的层中使用了"Affine-ReLU"组合
- 最后的输出层中使用了"Affine-Softmax"组合
卷积层
全连接层存在的问题
- 数据的形状被忽视:图像向全连接层输入时,将多维数据拉平为一维数据
- 卷积层可以保持形状不变
- 称卷积层的输入输出数据称为特征图(featuremap)
卷积运算
- 相当于滤波运算
- 将各个位置上滤波器的元素和输入的对应元素相乘,然后求和
填充
- 在进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据
- 调整输出的大小,保持空间大小不变
步幅
- 应用滤波器的位置间隔称为步幅(stride)
输出大小的计算
- 假设输入大小为((H,W)),滤波器大小为((FH,FW)),输出大小为((OH,OW)),填充为(P),步幅为(S),输出大小
[ OH=frac{H+2P-FH}{S}+1OW=frac{W+2P-FW}{S}+1 ]
三维数据的卷积计算
- 通道方向上有多个特征图时,会按照通道进行输入数据和滤波器的卷积运算,并将结果相加。
- 滤波器的权重数据要按照(output_channel,input_channel,height,width)的顺序书写
批处理
- 将在各层间传递的数据保存为4维数据。按照(batch_num,channel,height,width)的顺序保存数据
池化层
- 池化是缩小高、长方向上的空间的运算
- 池化的窗口大小和步幅设定成相同的值
- 特征
- 没有要学习的参数
- 通道数不发生变化
- 对微小的位置变化具有鲁棒性(输入数据发生微小偏差时,池化仍会返回相同的结果)
卷积层和池化层的实现
im2col函数
- 将输入数据展开以适合滤波器。
- 对3维的输入数据应用im2col后,数据转换为2维矩阵
- 输入数据:由im2col函数展开为2维数据,每一行为一个滤波区域
- 滤波器:纵向展开展开为1列
- 输入数据与滤波器相乘之后为2维数据,需转换为合适的大小
import sys,os
path = os.getcwd()+"sourcecode"
sys.path.append(path)
from common.util import im2col
import numpy as np
x1 = np.random.rand(1,3,7,7)#批大小为1,通道为3的7x7的数据
col1 = im2col(x1,5,5,stride=1,pad=0)#滤波器通道为3,大小为5x5
print(col1.shape)
x2 = np.random.rand(10,3,7,7)
col2 = im2col(x2,5,5,stride=1,pad=0)
print(col2.shape)
(9, 75)
(90, 75)
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
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
out = np.dot(col,col_W)+self.b
out = out.reshape(N,out_h,out_w,-1).tranpose(0,3,1,2)
return out
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).tranpose(0,3,1,2)
return out
具有代表性的CNN
LeNet
- 有连续的卷积层和池化层,最后经全连接层输出结果
- 激活函数用sigmoid函数
- 原始的LeNet中使用子采样(subsampling)缩小中间数据的大小,而不用池化
AlexNet
- 激活函数使用ReLU
- 使用进行局部正规化的LRN(Local Response Normalization)层。
- 使用Dropout
以上是关于Chapter7_卷积神经网络的主要内容,如果未能解决你的问题,请参考以下文章