caffe study之AlexNet

《ImageNet Classification with Deep Convolutional Neural Networks》

下面来看一下AlexNet的结构。在Alex的论文中,其基本结构为


1. 基本结构
a. 共有8层,其中前5层convolutional,后边3层full-connected ,最后的一个full-connected层的output是具有1000个输出的softmax,最后的优化目标是最大化平均的multinomial logistic regression
b. 在第一层conv1和conv2之后直接跟的是Response-nomalization layer,也就是norm1,norm2层。
c. 在每一个conv层以及full-connected层后紧跟的操作是ReLU操作。
d. Max pooling操作是紧跟在第一个norm1,norm2,以及第5个conv层,也就是conv5
e.Dropout操作是在最后两个full-connected层。


2. 操作流程

a. 在第一个conv层(conv1)中,AlexNet采用了96个11*11*3的kernel在stride为4的情况下对于224*224*3的图像进行了滤波。直白点就是采用了11*11的卷积模板在三个通道上,间隔为4个像素的采样频率上对于图像进行了卷积操作。4个像素是receptive field中心在kernel map上的距离,这是个经验数据。
最初的输入神经元的个数为224*224*3 = 150528个。对于每一个map来说,间隔为4,因此224/4 = 56,然后减去边缘的一个为55个,也就是本层的map大小为55*55,然后神经元数目为55*55*96 = 290400(得到基本的conv数据后,则进行一次ReLU(relu1)以及Norm(norm1)的变换后,然后进行pooling(pool1),作为输出传递到下一层。本层map数目为96.

b.第二个conv层(conv2)是第一个conv层(conv1)经过norm(norm1)以及pool(pool1)后,然后再apply 256个5*5的卷积模板卷积后的结果。pool1后,map的size减半int(55/2)= 27,得到的本层的神经元数目为27*27*256 = 186642个。本层map数目为256个。

c. 第三个conv层(conv3)的生成过程和第二层类似,不同的是这一层是apply 384个3*3的卷积模板得到的。
pool2后,map的size减半int(27/2) = 13,得到本层神经元数目为13*13*384 = 64896。本层map数目为384个。
d. 第四个conv层(conv4)是第三个conv层(conv3)进行一次ReLU(relu3)后,然后直接apply 384个3*3的卷积模板得到的。本层神经元的数目为13*13*384 = 64896。本层map数目为384个,size还是13*13.
e. 第五个conv层(conv5)与第四个生成类似,只是对上层进行了一个ReLU(relu4)后生成的,不同之处在于此处apply的卷积模板为256个3*3的。本层神经元的数目为13*13*256 = 43264。本层map数目为256个,size还是13*13。
f. 第一个full-connected层(fc6)是上一个conv层(conv5)进行pooling(pool5)后的全连接。pool5后,map的size减半int(13/2) = 6,上层基本连接为6*6*256,然后全连接后到4096个节点,本层最终节点为4096个。
g.第二个full-connected层(fc7)是上一个full-connected(fc6)进行ReLU(relu6)后,然后进行dropout(drop6)后再进行全连接的结果,本层节点数目为4096个。
h.最后一个full-connetcted层(fc8)则是上一个full-connected层(fc7)再次进行ReLU(relu7)以及dropout(drop7)后再进行全连接的结果。最后输出为融合label的softmax loss。

本层节点数目为1000个,对应着1000类对象。


其算法为

在一般的训练任务中,考虑的关键问题之一就是数据分布是否合理:首先是数据集的覆盖度,也就是数据集是否能够覆盖样本空间;其次还要尽可能的保证具有和真实数据一样的分布(注意数据分布是未知的,你只能根据一些先验来近似),这样的数据才是有效的。当然这些方式只是增大了得到正确解的概率,而并不能保证一定可以得到正确解。当你不知道你所取的训练集合是否和真实分布一致的时候,那么就要多取几次,每一个数据集都算算,对于分类器也是这样,单个分类器往往不能精确描述一个分界面,那么我们就组合一下,每个都算算。从方法论上讲,对于事物观察到的往往是局部,因此会犯以偏概全的错误,如果能够将所得到的“偏” ensambling 一下,那么就生成了相对的“全”,从而可以更大的概率逼近总体分布。这种思想在好多方面都体现出来,如交叉验证,经典的RANSAC,Random Tree(forest),Adaboost 等方法。


下面将从数据和模型两个方面来学习一下AlexNet中的一些技巧,主要参考的是Alex 2012 年的 NIPS论文ImageNet classification with deep convolutional neural networks.

1. 数据的处理:
到目前为止,还没有人看到数据集的大小对deeplearning算法理论上限造成的影响,也就是说数据集合还没有达到临界点,所以增加数据集只有好处,没有坏处。
在Alex的论文中,采用了两个方法对于图像进行了增强。
a. 增大训练样本:通过对于图像的变换实现了对于数据集合的enlarge。首先对于输入的图像(size 256*256)随机提取224*224的图像集合,并对他们做一个horizontal reflections。变换后图像和原图像相差了32个像素,因此主体部分应该都包含在训练集合中,相当于在位置这个维度上丰富了训练数据。对horizontal reflections来说,相当于相机在主轴方向做了镜像,丰富了反方向的图像。数据集合增大了2048倍,直接结果就是降低了overfitting同时降低了网络结构设计的复杂层度。
在测试阶段,取每一个测试样本四个角以及中间区域,一共5个patch然后再镜像后得到10个样本输入到网络中,最后将10个softmax输出平均后作为最后的输出。
b.使用PCA对于训练数据进行增强:对于每一个RGB图像进行一个PCA的变换,完成去噪功能,同时为了保证图像的多样性,在eigenvalue上加了一个随机的尺度因子,每一轮重新生成一个尺度因子,这样保证了同一副图像中在显著特征上有一定范围的变换,降低了overfitting的概率。
以上的策略是不是真的有必要,这个还是要打一个问号,因为对于a部分来说,样本少,可以在结构设计上下下功夫,可能达到相同的效果。对于b来说,deeplearning还需要对于图像加入增强处理吗?如果这样的话,自然也可以用一些传统人工特征先来一遍,再deeplearning了。我想关键的原因是deeplearning还没有真正的被证明的规则,所以你用什么策略都有点道理,但是谁敢保证不是“以偏概全”呢?

2. 模型结构:
在模型的设计上,AlexNet做了一个Local Response Normalization的处理,同时在节点的选择上采用了一个dropout策略。
a. Local Response Normalization.
公式如下,其中a是每一个神经元的激活,n是在同一个位置上临近的kernel map的数目,N是可kernel的总数目,k,alpha,beta都是预设的一些hyper-parameters,其中k=2,n=5,alpha = 1*e-4,beta = 0.75。


从这个公式中可以看出,原来的激活a被加一个归一化权重(分母部分)生成了新的激活b,相当于在同一个位置(x,y),不同的map上的激活进行了平滑,但是至于为什么k,alpha,beta这样来设置,没有想太清楚。
这个平滑大概可以将识别率提高1-2个百分点。
b. Dropout策略
使用多个model来共同进行预测是一个降低test errors的基本方法,但是单独的训练多个model组合会导致整个的训练成本增加,毕竟训练一个单一的网络需要很长的时间,即便计算资源足够,在不影响精度的情况下降低整个运算时间还是我们追求的目标。
由此Hinton提出了dropout策略,这个策略很简单,对于每一个隐层的output,以50%的概率将他们设置为0,不再对于forward或者backward的过程起任何作用。对于每一个input来说,使用的不同的网络结构,但是权重是共享的。这样求得的参数能够适应不同的情况下的网络结构,也就是提高了系统的泛化能力。
在AlexNet中最后的两个full-connected层中使用了这个策略。

3. 优化算法的参数
论文中使用SGD算法,基本参数设置在前面优化算法的总结中已经提到了。这里要说几个个人体会。
 a. 原文中输入的batch数目是256,应该Alex经过调节后的结果,我实际用到的机器性能比较低,内存8G,显存4G,所以不得不就将batch数目往下调到64,以免产生out of memory的错误。这样就需要调节其他的参数来保证数据的收敛。原因是batch比较小,导致本文开篇提到的样本覆盖面过低,产生了非常多的局部极小点,在步长和方向的共同作用下,导致数据产生了震荡,导致了不收敛。
b.在这种情况下,把learning rate调节到了0.02,相当于加大了步长,这样可以在一定程度上避免震荡,可以越过局部极小点往比较大的极值点行走。
c. 对于每一层的bias从1设置为了0.1,在一定程度上限制了激活的大小,这样就限制了某一过大的误差的影响,这样可以避免迭代方向出现过大的变化。
d. 经过b c后,系统终于收敛了,但带来的不良后果就是整个收敛速度变慢,因此还需要增加最大迭代次数,经过测试迭代次数成了从45w修改成了70w。
e. 在整个运行过程中,出现了几次平稳点,20w以及40w左右的时候,因此迭代的learning rate应该随着迭代的接近平稳点的时候有意的减小一些,目前是以每10w次减小为1/10,调参数用了5天,最后运行时间为15天。
f. 关于调参策略,上面只是按照一些简单的理解设置的,如果没有一个合理的解释,调参就变成了一个很low的工作。还好发现了好几篇关于调参的论文,主要是优化算法理论方面的,学习完再回来测试一下。

猜你喜欢

转载自blog.csdn.net/lemianli/article/details/53188130
今日推荐