LeNet-5

LeNet-5由LeCun于1998年提出,是最早的卷积神经网络之一
LeNet-5虽然结构十分简单,论文阐述的理论在现在看来也大都很基础
但在当时他第一次展示出了依赖自动学习的模式识别系统的潜力,可以说是打开深度学习大门的人之一

LeNet5

网络总共只有五层(不包括无参数的池化层),依次为
conv1——filter: 6, kernel_size: 5x5
averagePooling——size:2
conv2——filter: 16, kernel_size: 5x5
averagePooling——size:2
FC3——120
FC4——84
OUT5——10

其中除最后一层外,激活函数均为tanh
最后一层不是普通全连接层,而是径向基函数(RBF)

下面用keras写一个稍微化简的Lenet-5,最后一层就用普通的全连接+softmax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def buildNet():
# LeNet-5
model = Sequential()

model.add(Conv2D(
input_shape=(28, 28, 1),
filters=6, kernel_size=5,
activation='tanh'
))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))

model.add(Conv2D(filters=16, kernel_size=5, activation='tanh'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))

model.add(Flatten())

model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(10, activation='softmax'))

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
return model

AlexNet

论文链接:ImageNet Classification with Deep Convolutional Neural Networks

LeNet在图像分类上虽然十分成功,但受限于当时的硬件条件,这个成果并没有受到太大关注
直到AlexNet在2012年ImageNet竞赛中以远超第二名的成绩夺冠,深度学习才开始有了广泛影响

AlexNet的训练(受限于显存)使用了两张GPU,所以论文中的结构图看起来比较复杂

Alexnet0

其实可以等价为下图

Alexnet

Alexnet的基本结构和LeNet是相同的
即不断增加滤波器数量并缩小特征图尺寸,最后一维展开经过多个全连接层并softmax输出

但AlexNet也用到了许多新技术,例如

  • 使用ReLU替代了Tanh和Sigmoid激活,解决了深度网络的梯度消失问题提高了训练效率
  • 使用最大池化代替了此前CNN常用的平均池化,并提出了重叠池化(overlapping pooling),即池化步长小于池化窗口尺寸
  • 数据增强以提高模型泛化能力,主要是将原始256x256图像随机地裁剪至224x224,并随机应用水平翻转,其次还有PCA处理和添加随机噪声等
  • 训练中使用了DropOut,随机丢弃一部分神经元以避免过拟合
  • 提出了局部响应归一化LRN

(注意LRN现已被证明并没有作用,因而大多深度学习框架都没有这个层,BatchNormalization会是较好的选择)

AlexNet凭借加深地网络和这些新技术获得了top-1、top-5 error rates分别37.5%和17%的好成绩

VGG

论文链接:Very Deep Convolutional Networks For Large-Scale Image Recognition

收到AlexNet的影响,此后CNN分类问题中产生了大量十分有价值的模型
最具代表性的就是ImageNet 2014中获得第二名的VGG和第一名的GoogLeNet

论文中作者列出了包含不同层数的VGG结构表,现在比较常用的是VGG16和VGG19
VGG16的结构如下图所示

VGG16

VGG相较于AlexNet的改进主要体现在小卷积核的应用上

整个VGG中作者只使用了3x3和1x1卷积核
作者认为使用两层3x3卷积能获得5x5的感受野,而三层3x3卷积能获得7x7的感受野
若使用两层3x3卷积替代5x5卷积,网络的参数学习量将大大减少

得益于参数量减少,网络就可以在深度和宽度上增加更多
VGG也因此验证了更深的神经网络带来的性能提升

VGG虽然是当年ImageNet的第二名
但它比第一名GoogLeNet迁移学习能力更强,结构也更简单,因此比GoogLeNet更常见

keras中已内置了VGG16和VGG19的预训练模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def BuildNet():
VGGmodel = VGG16(
weights='imagenet', # 'imagenet'为加载imagenet上预训练的权值,None为随机初始化
include_top=False, # 是否包括顶层的全连接层
input_shape=(224,224,3)
# class=1000 # 图片分类的类别数,仅当include_top=True且不加载预训练权值时可用
)

TopModel = Sequential()
TopModel.add(Flatten(input_shape=VGGmodel.output_shape[1:]))

TopModel.add(Dense(4096, activation='relu'))
TopModel.add(Dropout(0.5))

TopModel.add(Dense(4096, activation='relu'))
TopModel.add(Dropout(0.5))

TopModel.add(Dense(1000, activation='relu'))
TopModel.add(Dropout(0.5))

TopModel.add(Dense(1000, activation='softmax'))

model = Sequential()
model.add(VGGmodel)
model.add(TopModel)

model.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])

model.summary()

return model

GoogLeNet

Going Deeper with Convolutions

ImageNet 2014中的冠军模型,它的特点体现在Inception结构
(GoogLeNet名字里前一个L也是大写,是为了致敬LeNet)

inception

Inception和之前的模型相比最大的不同是使用多个不同尺寸的卷积核提取特征,它的作用有

  • 直观上从不同尺度提取的特征更加丰富
  • 将稀疏矩阵分解成密集矩阵进行计算加速收敛

将稀疏矩阵密集化是论文中着重说明的一点,可以这样理解:
传统的CNN在某个block的输出特征图中,所有输出特征均匀的分布在3×3尺度上
但Inception结构使得输出特征不再均匀分布,而是不同尺度上相关性强的特征聚集在一起

Inception结构还有一个特点即1×1卷积核的使用,它的作用有

  • 在相同感受野下加深网络深度(原理来自Network in Network)
  • Inception块中先降维,减少3×3和5×5卷积的计算量

原始GoogLeNet之后又有多篇讨论Inception的论文,提出了Inception V2 / V3等