AlexNet是2012年ImageNet竞赛第一名,由Hinton和他的学生Alex Krizhevsky设计,包含了几个比较新的技术点,也首次在CNN中成功应用了ReLU、Dropout和LRN等Trick。同时AlexNet也使用了GPU进行运算加速。top-5 test error rate 为 15.3%.
1.使用线性整流单元ReLU ( Rectified Linear Units):
f ( x ) = m a x ( 0 , x ) f(x)=max(0,x) f(x)=max(0,x)
2.是非饱和的非线性激活函数
3.一定程度上解决梯度消失和梯度爆炸的问题
4.加快训练速度
(现在还有很多ReLU的变种,像Leaky ReLU, PReLU 等)
ReLU激活函数不会饱和,所以不要求对输入做归一化处理,然而对ReLU的输出做局部响应归一化能够增加模型的泛化能力。
1.局部响应归一化公式:
b x , y i = a x , y i / ⟮ k + α ∑ j = m a x ( 0 , 1 − n / 2 ) m i n ( N − 1 , i + n , 2 ) ( a x , y j ) 2 ⟯ β b^{i}_{x,y} = a^{i}_{x,y}/ \lgroup k+\alpha \sum^{min(N-1,i+n,2)}_{j=max(0,1-n/2)} (a^{j}_{x,y})^{2} \rgroup^{\beta} bx,yi=ax,yi/⟮k+αj=max(0,1−n/2)∑min(N−1,i+n,2)(ax,yj)2⟯β
2.归一化同一空间(即不同核的相同位置)的n个近邻核映射值
3.是一种横向抑制,使不同核产生的值之间进行竞争
4.论文中的超参数选择为: k = 2 k=2 k=2, n = 5 n=5 n=5, α = 1 0 − 4 \alpha=10^{-4} α=10−4, β = 0.75 \beta=0.75 β=0.75
5.和局部对比度归一化有一些相似性,而LRN更正确的术语为“brightness normalization”,因为没有用均值计算
使用重叠池化操作,稍微减轻过拟合问题
由五层卷积层和三层全连接层组成
Conv1
input->conv op->ReLU->LRN->max_pooling->output
输入为 227*227*3的图像,卷积核的数量为96,论文中两片GPU分别计算48个核; 卷积核的大小为 11*11*3,stride=4,padding=0.
卷积操作后的图形大小为:
wide = (227 + 2 * padding - kernel_size) / stride + 1 = 55
height = (227 + 2 * padding - kernel_size) / stride + 1 = 55
dimention = 96
ReLU之后进行 (Local Response Normalized), 接着池化pool_size = (3, 3), stride = 2, pad = 0 获得第一层卷积的feature map,27*27*96
conv2
imput->conv op->ReLU->LRN->max_pooling->output
input_size: 27*27*96
kernel_size :5*5*96, 128 个,padding=2,stride=1.
卷积的输出:27*27*256
ReLU,LRN,max_pooling_size=(3,3),stride = 2
output_size: 13*13*256
conv3
input->cons op->ReLU->output
input_size: 13*13*256
kernel_size: 3*3*256, 384个,padding=1, stride=1
ReLU
output_size: 13*13*384
conv4
同conv3
conv5
input->conv op->ReLU->max_pooling->output
input_size : 13*13*384
kernel_size: 3*3*384 ,256个, padding=1, stride=1
conv_output_size: 13*13*256
ReLU
max_pooling_size : (3,3),stride = 2
outptu_size: 6*6*256
FC1
input->Full Connect->ReLU->Dropout->output
(6,6,256)->(1,1,4096)->(1,4096)
FC2
input->FC(1*1卷积)->ReLU->Dropout->output
(1,4096)->(1,4096)
FC3 : output layer
input->softmax->output(1,1000)
first form: 随机裁剪,对256*256的图片进行随机裁剪到227*227,然后进行水平翻转。
测试的时候,对左上、右上、左下、右下、中间分别做了5次裁剪,然后翻转,共10个裁剪,之后对结果求平均。
second form: 对RGB空间做PCA(主成分分析),然后对主成分做一个(0, 0.1)的高斯扰动,也就是对颜色、光照作变换,结果使错误率又下降了1%。
# coding:utf8
from torch import nn
class AlexNet(nn.Module):
def __init__(self, num_classes=2):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), 256 * 6 * 6)
x = self.classifier(x)
return x