AlexNet
卷积神经网络,掀起CNN浪潮在深度学习中具有里程碑意义
特点
AlexNet共有8层结构,前5层为卷积层,后3层为全连接层
-
AlexNet使用ReLU激活函数
-
饱和与非饱和函数:当x趋向于正无穷与负无穷时,函数的导数都是趋近于0,称为饱和函数,例如:Sigmoid和tanh,否则为非饱和函数如ReLU
补充:
右饱和:当x趋于正无穷的时候,函数的导数趋向于0,此时称为右饱和
左饱和:当x趋于负无穷的时候,函数的导数趋于0,此时称为左饱和
饱和函数和非饱和函数:既满足右饱和又满足左饱和的函数称为饱和函数,否则为非饱和函数
常用的饱和激活函数和非饱和激活函数:饱和激活函数有Sigmoid和tanh,非饱和激活函数有ReLU,相对于饱和激活函数,非饱和激活函数可以解决梯度消失的问题,加快收敛速度
Sigmoid函数:
s i g m o i d ( x ) = 1 1 + e − x sigmoid(x)=\frac{1}{1+e^{-x}} sigmoid(x)=1+e−x1
sigmoid求导后:
s i g m o i d ( x ) ˙ = e − x ( 1 + e − x ) 2 \dot{sigmoid(x)}=\frac{e^{-x}}{(1+e^{-x})^{2}} sigmoid(x)˙=(1+e−x)2e−x
通过图像可以发现,sigmoid函数的最大导数为0.25,在进行反向传播的时候,各层的梯度相乘很容易造成梯度为0,也就是“梯度消失”
tanh函数:
t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^{x}-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+e−xex−e−x
tanh导函数:
t a n h ( x ) ˙ = 4 e 2 x ( e 2 x + 1 ) 2 \dot{tanh(x)}=\frac{4e^{2x}}{(e^{2x}+1)^2} tanh(x)˙=(e2x+1)24e2x
通过图像可以发现相交于sigmoid函数有所改善,但是整体导数都好事小于1,仍然会出现梯度消失的现象,不能避免
上面两种激活函数都会造成梯度消失,梯度消失将会使得权重无法得到有效更新,甚至神经网络无法继续训练
ReLU函数及其导函数的图像:
R e L U ( x ) = m a x ( 0 , x ) ReLU(x)=max(0,x) ReLU(x)=max(0,x)
可以看出ReLu的导函数在正数部分为1,不会造成梯度消失和梯度爆炸。但反向传播时一旦学习率没有设置好,使得某个神经元的ReLu 输入为负数,则会导致该神经元不再更新,这就是神经元死亡的现象
2.非饱和函数:可以解决梯度消失,加快收敛速度
-
-
LRN(局部响应归一化)与BN
-
LPN
归一化:不同评价指标特征向量中的不同特征就是所述的不同评价指标,为了消除不同评价指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性,原始数据经过处理之后,各指标处于同一数量级,适合进行综合对比评价。归一化使得数据被限定在[0,1]或者[-1,1]范围内。归一化加快梯度下降最优解的速度,也加快训练网络的收敛性,不进行归一化,那么特征向量中不同特征的取值相差较大,导致目标函数变扁,进行梯度下降的时候梯度下降就会偏离最小值方向,走很多弯路
LRN叫做侧抑制,指被激活的神经元会抑制其周围的神经元,作用是对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强模型的泛化能力,LRN一般是在激活、池化后进行的一种处理方法。
LRN通过在相邻卷积核生成的feature map之间引入竞争,从而有些本来在feature map中显著的特征在A中更显著,而在相邻的其他feature map中被抑制,这样让不同卷积核产生的feature map之间的相关性变小。增强模型的泛化能力。
i表示第i个核在位置(x,y)运用激活函数ReLU后的输出,n是同一位置上临近的kernal map的数目,N是kernal的总数。
参数K,n,alpha,belta都是超参数AlexNet的架构与LeNet相似,但使用了更多的卷积层和更多的参数来拟合大规模的ImageNet数据集
补充:
-
填充后的输出的形状的计算公式
p h p_h ph指行填充的总数, p w p_w pw指列填充的总数(两边相加总和), n w , n h n_w,n_h nw,nh指输入的大小n*n, k h , k w k_h,k_w kh,kw指卷积核的大小
import torch from torch import nn def comp_conv2d(conv2d, x): X = X.reshape((1,1) + X.shape) Y = conv2d(X) return Y.reshape(Y.shape[2:]) conv2d = nn.Conv2d(1, 1, kernal_size = 3, padding = 1) X = torch.rand(size=(8,8)) comp_conv2d(conv2d, X).shape # 输出结果 torch.Size([8, 8])
-
步幅stride
垂直步幅为 s h s_h sh、水平步幅为 s w s_w sw时,输出形状为
-
-
BN
BN(Batch Normalization):针对每一批数据,在网络的每一层输入之前增加归一化处理。BN是针对通道进行规范化,并引入两个可学习参数λ与β以保有数据原有的表达能力,减少信息丢失。
-
-
Dropout
是指在训练网络时按照一定概率将神经元暂时丢弃,即其权重不参与计算与更新,这样每次的网络结构都存在一定不确定性,对于多个神经元来说减弱相互之间的联系,相互依赖关系减少,但每个新的网络结构所具有的信息表达能力增强了。
同时起到抑制过拟合的作用,随机选取一部分神经元停止训练,本来属于其的任务被迫分给保留的神经元,这样剩下的神经元的能力就被迫得到提升,这样团体中的个体也就学到了比原来特征更加鲁棒的特征。==Dropout一般设置失活概率p=0.5,因为此时所有神经元的排列组合数取得最大。==如下图:
-
池化方式采用overlapping pooling,池化的窗口大于步长,使得每次池化都有重合部分,避免过拟合现象发生。
网络结构
import torch
from torch import nn
net = nn.Sequential(
# 这里使用一个11*11的更大窗口来捕捉对象。
# 同时,步幅为4,以减少输出的高度和宽度。
# 另外,输出通道的数目远大于LeNet
nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),nn.LocalResponseNorm(96),
# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),nn.LocalResponseNorm(256),
# 使用三个连续的卷积层和较小的卷积窗口。
# 除了最后的卷积层,输出通道的数量进一步增加。
# 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Flatten(),
# 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
nn.Linear(6400, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
# 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
nn.Linear(4096, 10))
X = torch.randn(1, 1, 224, 224)
for layer in net:
X=layer(X)
print(layer.__class__.__name__,'output shape:\t',X.shape)
在RCNN中出现的227*227的问题
网络的输入图片的尺寸是224*224
,但是使用11*11
的卷积核,stride=4进行卷积后,所输出的feature map应该是54*54
,但从结构图可以看到输出的尺寸是55*55
。根据此输出尺寸反向计算可以得到输入为227*227
,在很多其他的AlexNet实现也可以看到是采用的227*227
,应该是在第一层卷积时进行了padding=2,
55
=
224
+
2
∗
2
−
11
4
+
1
55=\frac{224+2*2-11}{4} +1
55=4224+2∗2−11+1