一、卷积神经网络的原理和结构
1、三个特性
- 局部性:特征是由局部区域决定。
- 相同性:对于不同图片,若有相同的特征,可能会出现在不同的位置。
- 不变性:对同一张图片进行下采样,图片的特性基本保持不变。
2、CNN的层次
卷积层
- 局部连接:
- 若在处理图像的时候,让每个神经元全连接,会使得空间十分庞大,由局部性原理可知,我们只需要通过局部就可以提取出相应的特征。
- 几个重要参数:
- 卷积层的深度:卷积层的输出深度与滤波器数量一致
- 步长:滤波器每次移动的像素点数量
- 边界填充
- 参数共享
- 原理:相同的滤波器能检测出不同位置上的特征。
- 输出体数据在深度切片上所有的权重都使用同一个权重向量。在前向传播过程中,每个切片都可以看成是神经元的权重对输入数据体的卷积。
池化层
- 在卷积层之间周期性插入一个池化层,作用:逐渐降低数据的空间尺寸。
- 实现:通过设置窗口大小,滑动步长来进行对数据的处理。
- 实例(提取窗口的最大值)
全连接层
- 在一般的神经网络结构中,每个神经元与前一层的神经元全部连接。
- 在CNN中,只和输入数据中的一个局部区域连接,并且输出的神经元每个深度切片共享参数。
- 同时,在一些CNN中的全连接层,为了防止过拟合,会引入Dropout(概率断开一些连接)。
二、Pytorch卷积模块
卷积层
nn.Conv2d(in_channels,out_channnels,kernel_size,stride,padding)
:卷积模块
-
in_channels,out_channels
:输入输出数据体的深度 -
kernel_size
:卷积核大小 -
stride
:滑动步长 -
padding
:零填充
池化层
-
nn.MaxPool2d(kernel_size,stride,padding)
:最大值池化 -
nn.AvgPool2d()
:均值池化
实现简单的CNN
import torch
from torch import nn
class CNN(nn.Module):
def __int__(self):
super(CNN, self).__int__()
# 1-3 是卷积层
# [b,3,32,32] => [b,32,32,32] => [b,32,16,16]
self.layer1 = nn.Sequential(
nn.Conv2d(3,32,kernel_size=3,stride=1,padding=1),
nn.ReLU(),
nn.MaxPool1d(2,2)
)
# [b,32,16,16] => [b,64,16,16] => [b,64,8,8]
self.layer2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool1d(2, 2)
)
# [b,64,8,8] => [b,128,8,8] => [b,128,4,4]
self.layer3 = nn.Sequential(
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool1d(2, 2)
)
# 第四层是全连接层
# [b,64,8,8] => [b,128,8,8] => [b,128,4,4]
self.layer4 = nn.Sequential(
nn.Linear(128*4*4,512),
nn.ReLU(),
nn.Linear(512,64),
nn.ReLU(),
nn.Linear(64,10),
nn.ReLU()
)
def forward(self,x):
conv1 = self.layer1(x)
conv2 = self.layer2(conv1)
conv3 = self.layer3(conv2)
fc_input = conv3.view(conv3.size(0),-1) # 打平处理
fc_out = self.layer4(fc_input)
return fc_out
if __name__ == '__main__':
cnn_model = CNN()