前言
介绍神经网络CNN,各个模块和常见的网络,以及实现VGG16的分类
提示:以下是本篇文章正文内容,下面案例可供参考
一、BP神经网络
待补相关知识
二、CNN
1.全连接层(FC)
包含权重向量W和激活函数
流程:
1.将32*32*3的矩阵拉伸为3072*1向量作为隐藏层输入
2.3072*1和W进行点乘。
3.将点乘结果作为激活函数的输入(RELU,Sigmoid)
4.输出结果则为全连接层的输出
2.卷积层(CONV)
1.卷积核=卷积=滤波器:即特征提取算子,
注:每个通道都需要一个卷积核(K=D1),卷积核大小 一般和输入通道数一致。大小:
卷积核:里面数字随机初始化
2.计算公式:
输入:32*32*3 (W1,H1,D1)
卷积核大小:F*F,个数K
公式:
输出:(W2,H2,K)
3.概念
步长S:卷积在输入图片上移动时需要的移动的像素数;
填充P:减少边缘信息的丢失,原图周围,添加一圈值为“0”的像素点(zero padding),这样的话,使得输出维度就和输入维度一致。
一维卷积:输出是向量;二维卷积:输入是矩阵;三维卷积:输入为带通道的矩阵
感受野:卷积每次滑动覆盖的各格子范围在图像处理中
4.卷积示意图:
.
pytorch定义卷积函数参数
classtorch.nn.Cov2d(in_channels,out_channels,kernel_size,
stride=1,padding=0,dilation=1,groups=1,bias=True)
in_channels (int) :输入图片的channel
out_channels (int) :输出图片(特征层)的channel
kernel_size (int or tuple) :kernel的大小
stride (int or tuple, optional) :卷积的步长,默认为1
padding (int or tuple, optional) :四周pad的大小,默认为0
dilation (int or tuple, optional) :kernel元素间的距离,默认为1(dilation翻译为扩张,有时候也称为“空洞”,有专门的文章研究dilation convolution)
groups (int, optional) :将原始输入channel划分成的组数,默认为1(初级读者暂时可以不细究其用处)
bias (bool, optional) :如果是Ture,则输出的bias可学,默认为 True
3.池化层( MAX POOL)
池化:对图片进行压缩的一种(下采样)方法,
最大池化(Max Pooling取最大值)和平均池化(Average Pooling 和求平均值)。
输入(W1,H1,D1)池化kernel大小F*F,步长S 。
输出(W2,H2,D1)
最大池化层图解:
4.批规范化层(NORM)
目的:加快神经网络收敛过程以及提高训练过程中稳定性能
batch概念:往往是(32,64,128)张图片同时被输入网络中,一起前向计算,误差
也是所有图片的误差累加在一起。
BatchNorm对一个batch做归一化:
![]()
5.pytorch定义简单卷积神经网络代码
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self): #在这里定义卷积神经网络需要的元素
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5) #定义第一个卷积层
self.pool = nn.MaxPool2d(2, 2) #池化层
self.conv2 = nn.Conv2d(6, 16, 5) #定义第二个卷积层
self.fc1 = nn.Linear(16 * 5 * 5, 120) #全连接层
self.fc2 = nn.Linear(120, 84) #全连接层
self.fc3 = nn.Linear(84, 10) #最后一个全连接层用作10分类
def forward(self, x): #使用__init__中的定义,构建卷积神经网络结构
x = self.pool(F.relu(self.conv1(x))) #第一个卷积层首先要经过relu做激活,然后使用前面定义好的nn.MaxPool2d(2, 2)方法做池化
x = self.pool(F.relu(self.conv2(x))) #第二个卷积层也要经过relu做激活,然后使用前面定义好的nn.MaxPool2d(2, 2)方法做池化
x = x.view(-1, 16 * 5 * 5) #对特征层tensor维度进行变换
x = F.relu(self.fc1(x)) #卷积神经网络的特征层经过第一次全连接层操作,然后再通过relu层激活
x = F.relu(self.fc2(x)) #卷积神经网络的特征层经过第二次全连接层操作,然后再通过relu层激活
x = self.fc3(x) #卷积神经网络的特征层经过最后一次全连接层操作,得到最终要分类的结果(10类标签)
return x
net = Net()
三、经典卷积网络结构
3.1.AlexNet
3.1.1网络结构
5个卷积和3个全连接
3.1.2特点
1.使用Relu作为激活函数
优点:收敛速度更快
2.使用多种方法避免过拟合
1.数据增强:
第一种:图像数据上最简单常用的用来减少过拟合的方法是使用标签保留变换来人工增大数据集
- 对原始图片随机裁剪
- 对图片进行上下、左右、平移等操作
第二种:改变训练图像的RGB通道的强度。具体地,我们在整个ImageNet训练集上对RGB像素值集合执行PCA。对于每幅训练图像,我们加上多倍找到的主成分,大小成正比的对应特征值乘以一个随机变量,随机变量通过均值为0,标准差为0.1的高斯分布得到。因此对于每幅RGB图像像素
2.dropout:更有效的方式进行模型融合
以0.5的概率对每个隐层神经元的输出设为0,“失活的”的神经元不再进行前向传播并且不参与反向传播,但需要输出时乘以0.5
引用:Alexnet解读 ,基于pytorch的Alexnet猫狗分类
3.2 VGGNet
3个3*3的卷积核(stride=1)和1个7*7的卷积核产生相同的效果,但是前者更好:reason
- 网络更深能学习到更为复杂的非线性关系
- 参数的数量减少:c个kernel 7*7*c >3(3*3*c)
3.3 GoogleNet
网络架构:
注:主干网络中全部使用卷积网络只有最后的输出用到全连接层softmax
为了增加网络的复杂度两个角度:网络深度和网络宽度,但同样存在两个问题
- 复杂的网络参数过多,容易发生过拟合
- 带来更大的计算资源消耗
- 网络越深,梯度往后越容易消失
GoogleNet解决方案:
- 深度方面:采用了层数更深的22层网络,为了尽量避免上述的提到梯度消失的问题在不同深度处增加了两个loss来保证梯度回传消失的现象。
- 宽度方面:采用了inception结构(网中网),即原来的结点也是网络。来降低计算量
采用不同大小的卷积核的目的
用不同大小的卷积核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合;
之所以卷积核大小采用1、3和5,主要是为了方便对齐。设定卷积步长stride=1之后,只要分别设定pad=0、1、2,那么卷积之后便可以得到相同维度的特征,然后这些特征就可以直接拼接在一起了;
3*3和5*5d的卷积核参数任然过大
- 为了降维加入1*1的卷积层
引用:GoolgNet网络结构学习 GoolgNet详解+代码实现
3.4 ResNet
网络结构:
梯度消失问题:
,前层网络的梯度越来越小
如图所示:网络越深 ,效果不一定越好
训练和测试都不高,说明不是过拟合的问题
Resnet革命性的提出:残差结构
解决神经网络中因网络深度而导致的梯度消失的问题
将输出层
改为
所有梯度就变为了
3.5 其他网络结构
1.Wide ResNe
认为残差结构比深度更重要,设计更宽的残差,实现证明50层的加宽残差比原152层的更好
2.ResNeXT
在ResNet上通过加宽inception个数方式来扩展残差模块
3.DenseNet
使每一层都与其他层相关联,大大缓解了”梯度消失“问题
四、VGG16实现Cifar10分类
待续