综述:
这些模型基本都是从ILSVR比赛中出来的,而这个比赛是基于李飞飞的ImageNet项目,厉害!
ILSVR比赛:ImageNet Large Scale Visual Recognition Competition

ILSVRS Winners
从下图直观就可以看出:从10年到15年,Top5错误率一直在降低,很明显的是层数在升高,在15年的ResNet中,使用到了152层的神经网络。“越深越好”

详细解析:VGGNet
帅哥讲师说这个模型是他训练模型时的默认模型,所以拿来具体看看。其他模型,可点击 我爱机器学习的这篇文章,看过,觉得写的不错。
背景知识:
VGGNet,2014年ILSVRC的亚军是Simonyan and Andrew Zisserman发明的。VGGNet向我们证明了深度对于卷积网络的重要性。最终性能最优的网络是16层CONV/POOL,从输入到输出层结构相同,都是3x3卷积核2x2池化。预训练模型可以在caffe上直接使用。VGGNet缺点是非常耗计算资源和内存,它有140M参数。大部分参数在第一个全连接层,后来发现它可以移去,且性能几乎不会有影响,因此减少了参数个数。

基本结构
下图第一行,从A--> E 表示层数的增加。C和D行都是13层的CONV层 + 3层的FC层层,也就是VGG-16。E行是VGG-19. 卷积层与卷积层之间有非线性激活函数(ReLU)。
conv3- X,X代表的是卷积核的个数,它从64,增大到128,256, 512。与之相伴的,一共使用了5个maxpool,下下一张有详细代码的图可以看到,feature map在不断减小,从224 * 224,最后减小为了7*7

VGG-16全部都用的是3*3的卷积核
为什么选择的是3*3的卷积核呢?不是5*5或者7*7呢?
简单说:因为3x3是可以表示「左右」、「上下」、「中心」这些模式的最小单元。
可点击连接访问:知乎 - 留德华叫兽 关于这个问题的解释。(那个图画的真的很好,强烈推荐)
以下是个人解释:
假设输入55*55,那么使用7*7的滤波器,stride 1,输出为(55-7)/1 + 1 = 49, 49*49
- 如果使用1个3*3的滤波器,stride 1,输出为 (55 - 3)/1 +1 = 53, 53*53
- 如果使用2个连续的3*3的滤波器,stride 1,在上一个的基础上,输出,51*51
- 如果使用3个连续的3*3的滤波器,stride 1,在上两步的基础上,输出为:49*49
最后的有效感受野(effective receptive field)其实是一样的,都是49*49.
但是训练层数更多(更深),可以加入更多的非线性元素。
假设卷积的输入和输出都有C个通道,那么单独的7x7卷积层将会包含7*7*C^2=49C^2个参数
而3个3x3的卷积层的组合仅有个3*(3*3*C*C)=27C^2个参数
因为C是常数,所以3个3*3的卷积核包含的参数更少,计算复杂度就相应降低了
缺点:在进行反向传播时,中间的卷积层可能会导致占用更多的内存。
注:参数数量 = 卷积核的长 * 卷积核的宽 * 卷积核的深度(上一层的Channel-深度)* 卷积核的个数(决定下一层的channel)
详细内容
1. 最前面几个卷积层占用了大部分内存
2. 第一个全连接层占用了大部分参数。第一个FC层包含约100M参数,参数总个数才140M。后续研究发现这个全连接层可以移去,且性能几乎不会有影响,因此减少了参数个数。


注:可能会看到有人说,从图片中提取一些FC层特征,其实是借鉴AlexNet的,AlexNet对于每一层都有特定的命名,FC7是指在分类器之前的最后一层。之后的不同的神经网络,架构不同,但是大家一般说FC7 feature,都是指在分类器之前的最后一件事。
以下转载自:CSDN
计算资源
卷积网络最大限制在于内存,GPU内存一般为3 /4 /6G,当前最好的GPU大概有12G。有三种主要占用内存的来源:
1. 中间数据
每个卷积层都有激活的原始数据和梯度(它们大小相同),大部分的激活数据在前面几个卷积层中;要记录它们是因为在反向传播时需要使用。但在测试时就可以释放前面激活层数据占用的内存。
2. 参数
网络中有大量参数,反向传播时它们的梯度,如果使用momentum, Adagrad, RMSProp还要记录一步缓存,所以参数存储空间要在最原始基础上乘以3甚至更多。
3. 卷积网络实现
实现还要占用各种混杂(miscellaneous)内存,例如图像批数据,它们的扩展数据(Data Augmentation)等。
转化为GB单位
对参数(激活、梯度、混杂)个数有了大概估计后,应该转换为GB单位,如果是数值是单精度(float),那么占4个字节,双精度(double)占8个字节单。所以单精度* 4 byte,双精度 * 8 byte,得到占用字节数,最终换算成GB。如果占用内存过多,最简单办法是减小batch size;因为大部分内存是被激活数据占用。
网友评论