GoogLeNet的特点是提升了计算资源的利用率,可以在保持网络计算资源不变的前提下,通过工艺上的设计来增加网络的宽度和深度,基于Hebbian法则和多尺度处理来优化性能。 在深度学习中, 提升网络性能最直接的办法就是增加网络深度和宽度, 这也就意味着巨量的参数。但是, 巨量参数容易产生过拟合
也会大大增加计算量
。
对于大规模稀疏的神经网络,可以通过分析激活值的统计特性和对高度相关的输出进行聚类来逐层构建出一个最优网络, 这点表明臃肿的稀疏网络可能被不失性能地简化
。解决过拟合
和计算成本
的根本方法是将全连接甚至一般的卷积都转化为稀疏连接, 早在AlexNet中使用的Dropout就是将网络之间的连接转变为稀疏连接
从而减少参数的数据以防止模型过拟合, 但是,计算机软硬件对非均匀稀疏数据的计算效率很差,所以在AlexNet中又重新启用了全连接层,目的是为了更好地优化并行运算。
GoogLeNet
而非GoogleNet
是为了向早期的LeNet致敬!
Inception模块
那么如何既能保持网络结构的稀疏性,又能利用密集矩阵的高计算性能
呢? 在GoogLeNet中提出了Inception
结构来实现的, 采用将多个稀疏矩阵合并成相关的稠密子矩阵的方法来解决:
- 采用不同大小的卷积核意味着不同大小的感受野,最后的
Filter concatenation
意味着不同尺度特征的融合 - 卷积核大小采用1、3和5,主要是为了方便对齐。设定卷积步长stride=1之后,只要分别设定pad=0、1、2,那么卷积之后便可以得到相同维度的特征,然后这些特征就可以直接拼接在一起了
- 网络越到后面(滤波器变大),特征越抽象,而且每个特征所涉及的感受野也更大
特征聚合过程:
- 如上图所示, 我们在相同的一块区域中, 使用不同大小的滤波器进行特征提取, 然后将通过聚类算法将高相关性的区域聚集到一起, filter越来越大, 聚类的数目越来越少
- 在pooling层添加一个额外的并行pooling路径用于提高效率
采用上面的模块有一个大问题是: 在卷积层顶端由于滤波器太多,即使是5x5的卷积都会让计算成本太高, 于是有了改进的版本:
采用1x1卷积核来进行降维:
上一层的输出为100x100x128,经过具有256个输出的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256。其中,卷积层的参数为128x5x5x256。假如上一层输出先经过具有32个输出的1x1卷积层,再经过具有256个输出的5x5卷积层,那么最终的输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256,大约减少了4倍。
网络结构
- GoogLeNet采用了模块化的结构,方便增添和修改
- 网络最后采用了average pooling来代替全连接层, 实际在最后还是加了一个全连接层,主要是为了方便以后大家finetune
- 虽然移除了全连接,但是网络中依然使用了Dropout
- 为了避免梯度消失,网络额外增加了2个辅助的softmax用于向前传导梯度。文章中说这两个辅助的分类器的loss应该加一个衰减系数,但看caffe中的model也没有加任何衰减。此外,实际测试的时候,这两个额外的softmax会被去掉。
- 线性层将softmax损失作为分类器
- 所有的reduction/projection层都利用了修正线性激活
训练策略
- 利用分布式机器学习系统和数据并行来训练网络,虽然实现时只用了CPU,但是是可以用个别高端的GPU一周达到收敛的。采用异步随机梯度下降,动量为0.9,学习率每8个epoch下降4%。用Polyak平均来创建最后的模型。
- 图像采样的patch大小从图像的8%到100%,选取的长宽比在3/4到4/3之间,光度扭曲也有利于减少过拟合,还使用随机插值方法结合其他超参数的改变来调整图像大小。