AlexNet
AlexNet模型解读
AlexNet共有八层,有60M以上的参数量。
前五层为卷积层:convolutional layer;
后三层为全连接层,fully connected layer。
最后一个全连接层输出具有1000个输出的softmax。(这个不懂什么意思的参考机器学习理论中的softmax regression,就是一个多类的logistic regression)
大致的分层结构如下:
●第一层:
①输入图片为224x 224 x3, 表示长宽是224个像素,RGB彩色图通道为3通道,所以还要乘以3.(学界普遍认为论文中说的224不太合适,讲道理应该是227的大小才对,这也成为一个悬案),
②然后采用了96个11 x 11 x 3 的filter。在stride为4的设置下,对输入图像进行了卷积操作。所以经过这一卷积后的操作,输出就变成了55 x 55 x96 的data map。这三个数字的由来:(227-11)/ 4 + 1 = 55,96就是滤波器的个数。
③然后经过**函数ReLu,再进行池化操作-pooling:滤波器的大小为3 x 3,步长stride为2. 所以池化后的输出为27x 27 x 96,(55-3)/ 2 + 1 =27. 96仍为原来的深度。
④LRN,局部响应归一化。后来大家都认为这个操作没有什么太大的作用,所以后面的网络几乎都没有这个操作,我也就不提了。
●其他第2、3、4、5层的计算过程类似。
●第六层:本层的输入为6 x 6 x 256,全连接层其实就是一个矩阵运算,它完成一个空间上的映射。所以把输入看成一个列向量X,维度为9216(6 x 6 x 256),也就是你可以把输入看成一个9216 x 1的矩阵。然后和参数矩阵W相乘,参数矩阵W你此时设置为4096 x 9216,所以最后本全连接层的输出就是 矩阵相乘Y = W·X得 4096 x 1的矩阵
●第八层:第八层的输出就为1000 x 1的矩阵,即1000维度的一个列向量,对应softmax regression的1000个标签
关于AlexNet框架更详细的解释,可以参考:
https://blog.****.net/sunbaigui/article/details/39938097#reply
创新点
Data augmentation
有一种观点认为神经网络是靠数据喂出来的,若增加训练数据,则能够提升算法的准确率,因为这样可以避免过拟合,而避免了过拟合你就可以增大你的网络结构了。当训练数据有限的时候,可以通过一些变换来从已有的训练数据集中生成一些新的数据,来扩大训练数据的size。
水平翻转flip
随机裁剪、平移变换crop
从原始图像(256,256)中,随机的crop出一些图像(224,224)
颜色、光照变换
我们在遍及整个ImageNet训练集的RGB像素值集合中执行PCA。对于每个训练图像,我们成倍增加已有主成分,比例大小为对应特征值乘以一个从均值为0,标准差为0.1的高斯分布中提取的随机变量。这样一来,对于每个RGB图像像素,我们增加下面这项:
其中平pi和λi分别是RGB像素值的3×3协方差矩阵的第i个特征向量与特征值,αi是前面提到的随机变量。每个αi对于特定训练图像的全部像素只提取一次,直到那个图像再次被用于训练,在那时它被重新提取。这个方案大致抓住了自然图像的一个重要属性,即,光照强度与颜色是变化的,而对象识别是不变的。在top1错误率上贡献1%。
AlexNet 训练的时候,在data augmentation上处理的很好:
- 随机crop。训练时候,对于256*256的图片进行随机crop到224*224,然后允许水平翻转,那么相当与将样本倍增到((256-224)^2)*2=2048。
- 测试时候,对左上、右上、左下、右下、中间做了5次crop,然后翻转,共10个crop,之后对结果求平均。作者说,不做随机crop,大网络基本都过拟合(under
substantial overfitting)。 - 对RGB空间做PCA,然后对主成分做一个(0, 0.1)的高斯扰动。结果让错误率又下降了1%。
ReLU **函数
Sigmoid 是常用的非线性的**函数,它能够把输入的连续实值“压缩”到0和1之间。特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.
但是它有一些致命的 缺点:
- Sigmoids saturate and kill gradients. sigmoid有一个非常致命的缺点,当输入非常大或者非常小的时候,会有饱和现象,这些神经元的梯度是接近于0的。如果你的初始值很大的话,梯度在反向传播的时候因为需要乘上一个sigmoid的导数,所以会使得梯度越来越小,这会导致网络变的很难学习。
-
Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0 elementwise in f=wTx+b),那么 w计算出的梯度也会始终都是正的。
当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
ReLU 的数学表达式如下:
f(x)=max(0,x)
很显然,从图左可以看出,输入信号<0时,输出都是0,>0 的情况下,输出等于输入。w 是二维的情况下,使用ReLU之后的效果如下:
Alex用ReLU代替了Sigmoid,发现使用 ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多。
主要是因为它是linear,而且 non-saturating(因为ReLU的导数始终是1),相比于 sigmoid/tanh,ReLU
只需要一个阈值就可以得到**值,而不用去算一大堆复杂的运算。
当然,ReLU也是有缺点的,比如左边全部关了很容易导致某些隐藏节点永无翻身之日,所以后来又出现pReLU、random ReLU等改进,而且ReLU会很容易改变数据的分布,因此ReLU后加Batch Normalization也是常用的改进的方法。
Dropout
结合预先训练好的许多不同模型,来进行预测是一种非常成功的减少测试误差的方式(Ensemble)。但因为每个模型的训练都需要花了好几天时间,因此这种做法对于大型神经网络来说太过昂贵。
然而,AlexNet 提出了一个非常有效的模型组合版本,它在训练中只需要花费两倍于单模型的时间。这种技术叫做Dropout,它做的就是以0.5的概率,将每个隐层神经元的输出设置为零。以这种方式“dropped out”的神经元既不参与前向传播,也不参与反向传播。
所以每次输入一个样本,就相当于该神经网络就尝试了一个新的结构,但是所有这些结构之间共享权重。因为神经元不能依赖于其他特定神经元而存在,所以这种技术降低了神经元复杂的互适应关系。
正因如此,网络需要被迫学习更为鲁棒的特征,这些特征在结合其他神经元的一些不同随机子集时有用。在测试时,我们将所有神经元的输出都仅仅只乘以0.5,对于获取指数级dropout网络产生的预测分布的几何平均值,这是一个合理的近似方法。
前两个全连接层使用dropout。如果没有dropout,我们的网络会表现出大量的过拟合。dropout使收敛所需的迭代次数大致增加了一倍。Dropout方法和数据增强一样,都是防止过拟合的。
Overlapping Pooling
一个pooling层,s表示移动步长,z表示pooling Kernel边长,若设s=z,我们得到传统的局部pooling,正如常用于CNN中的那样。若设s
Local Responce Normalization
一句话概括:本质上,这个层也是为了防止**函数的饱和的。
个人理解原理是通过正则化让**函数的输入靠近“碗”的中间(避免饱和),从而获得比较大的导数值。
所以从功能上说,跟ReLU是重复的。
不过作者说,从试验结果看,LRN操作可以提高网络的泛化能力,将错误率降低了大约1个百分点。
后来加入到DL研究工作中的大佬们说这个LRN设计用处其实不大。
多GPU训练
单个GTX 580 GPU只有3GB内存,这限制了在其上训练的网络的最大规模。因此他们将网络分布在两个GPU上。
目前的GPU特别适合跨GPU并行化,因为它们能够直接从另一个GPU的内存中读出和写入,不需要通过主机内存。
他们采用的并行方案是:在每个GPU中放置一半核(或神经元),还有一个额外的技巧:GPU间的通讯只在某些层进行。
例如,第3层的核需要从第2层中所有核映射输入。然而,第4层的核只需要从第3层中位于同一GPU的那些核映射输入。
参考:
https://blog.****.net/cyh_24/article/details/51440344
https://blog.****.net/teeyohuang/article/details/75069166
https://zhuanlan.zhihu.com/p/22094600