深度学习算法之AlexNet和VGGNet

来源:互联网 发布:天府立交数据 编辑:程序博客网 时间:2024/06/05 11:02

AlexNet:
1 模型特性

该模型主要的特性如下:
1.1 激活函数——ReLU

(1)激活函数使用ReLU,解决了梯度弥散问题;

什么是梯度弥散?同样还有一个概念叫做梯度爆炸?

直观的解释:
这里写图片描述

可以看出sigmod函数在靠近0的附近的时候梯度变化比较明显,到靠近1的地方梯度逐渐趋近与0,根据梯度下降算法,此时权值等参数变化不明显,函数很难收敛。

本质的解释:

假设一个简单的结构,输入层节点表示为h1,其后节点分别为h2h3h4,输出为C,各节点间权值为w2,w3,w4

根据前向计算:
假设第一层输入为z1,那么其输出为a1=σ(z1),其余各层依次类推。

根据反向计算:

Lz0=La4a4z4z4a3a3z3z3a2a2z1z1a1a1z0
其中aizi1=wi

当h1有小变化时,
Lz0ΔLΔz0

有:
Δa1Δz0=a1z0
故:
Δa1=a1z0Δz0
以此类推:
ΔL=La4a4z4z4a3a3z3z3a2a2z1z1a1a1z0Δz0

因为wi<1,sigmod函数导数最大值为1/4。

所以梯度后向传播,层数越多,传递回来的梯度值越小。

相反,对于正向传播,如果初始化的参数过大,有可能在最后数值出现overflow,也就是梯度爆炸NAN。

所以本质上仍然是由于链式规则导致多项乘积,导致网络越深乘积结果偏离理想情况。

ReLU为什么可以避免梯度消失
这里写图片描述

从图中看出ReLU函数梯度不会随着x的增大而减小。

(2)ReLU本质上是分段线性模型,前向计算非常简单,无需指数之类操作,其偏导求解更简单,无需指数或者除法运算。

(3)ReLU在x<0的情况下,输出都是0,也就是隐藏层输出为0,表明网络结构变得稀疏了,减少了模型的复杂性。

1.2 dropout

使用Dropout随机忽略部分神经元,避免过拟合。

  1. 每次进行权值更新时,dropout保证了隐含节点是以一定概率随机出现,因此2个隐含节点每次不一定同时出现,这样权值的更新不再依赖于有固定关系隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况。

  2. dropout可以看做是一种bagging的情况,也就是对于每个样本,其所对应的网络结构不一样,相当于对应不同的模型。

1.3 最大池化
使用重叠的最大池化,一方面是保留最显著的特征,一方面重叠可以提升特征的丰富性。

1.4 LRN层。
LRN对于网络的效果不明显,同时还会降低收敛速度,得不偿失。

1.5 CUDA加速计算。
该模型使用两块GPU进行训练,每个GPU存储一般的学习参数,GPU之间的通信高效方便。

1.6 数据增强
随机的对原始图像进行翻转,裁剪。等价于增大数据量。
常用的方法有:

水平翻转
随机裁剪、平移变换
颜色、光照变换

2 模型结构
2.1 论文所述结构
这里写图片描述

由图看出前五层为卷积层,有的卷积层后跟最大池化层,而最后三层为全连接层,分类用softmax。

2.2 AlexNet的caffe实现

2.2.1数据层

数据增强:AlexNet首次在输入之前对数据进行镜像,翻转,随机剪裁等预处理,主要是为了增加数据量。训练时随机从256*256的原始图像中随机截取224*224的区域,可以得到(256-224)^2*2=2048倍的数据量,极大地减轻了模型的过拟合。

测试的时候裁剪则是固定的。

裁剪出多个图片,对他们进行预测最后对结果求均值。

batch_size:训练时256,测试时50

name: "AlexNet"layer {  name: "data"  type: "Data"  top: "data"  top: "label"  include {    phase: TRAIN  }  transform_param {    mirror: true//镜像    crop_size: 227//裁剪尺寸    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"  }  data_param {    source: "examples/imagenet/ilsvrc12_train_lmdb"    batch_size: 256    backend: LMDB  }}layer {  name: "data"  type: "Data"  top: "data"  top: "label"  include {    phase: TEST  }  transform_param {    mirror: false    crop_size: 227    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"  }  data_param {    source: "examples/imagenet/ilsvrc12_val_lmdb"    batch_size: 50    backend: LMDB  }}

2.2.2 卷积部分

卷积部分包含:卷积核层,LNR层,激活函数,池化三部分。

第一个使用的是较大的11*11,步长为4,总数为96的卷积核;后跟LNR层和一个3*3的池化层,步长为2。

第二个使用的则是5*5,步长为1的卷积核,步长为1表面扫描输入图片的所有像素点。池化仍然是3*3,步长为2.

第三个则是三个3*3的卷积核串联,后跟最大池化3*3,步长不变。

layer {  name: "conv1"  type: "Convolution"  bottom: "data"  top: "conv1"  param {    lr_mult: 1//学习率,但是最终的学习率需要乘以 solver.prototxt 配置文件中的 base_lr .//如果有两个 lr_mult, 则第一个表示 weight 的学习率,第二个表示 bias 的学习率 //一般 bias 的学习率是 weight 学习率的2倍    decay_mult: 1//权值衰减,为了避免模型的over-fitting,需要对cost function加入规范项  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 96 //卷积核个数,也是feature map个数    kernel_size: 11 //卷积核尺寸    stride: 4       //步长    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0    }  }}layer {//激活函数ReLU  name: "relu1"  type: "ReLU"  bottom: "conv1"  top: "conv1"}layer {//LRN  name: "norm1"  type: "LRN"  bottom: "conv1"  top: "norm1"  lrn_param {    local_size: 5    alpha: 0.0001    beta: 0.75  }}layer {  name: "pool1"  type: "Pooling"  bottom: "norm1"  top: "pool1"  pooling_param {    pool: MAX    //池化类型:最大池化    kernel_size: 3//池化核的大小    stride: 2     //步长  }}layer {  name: "conv2"  type: "Convolution"  bottom: "pool1"  top: "conv2"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 256    pad: 2    kernel_size: 5    group: 2    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0.1    }  }}layer {  name: "relu2"  type: "ReLU"  bottom: "conv2"  top: "conv2"}layer {  name: "norm2"  type: "LRN"  bottom: "conv2"  top: "norm2"  lrn_param {    local_size: 5    alpha: 0.0001    beta: 0.75  }}layer {  name: "pool2"  type: "Pooling"  bottom: "norm2"  top: "pool2"  pooling_param {    pool: MAX    kernel_size: 3    stride: 2  }}layer {  name: "conv3"  type: "Convolution"  bottom: "pool2"  top: "conv3"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 384    pad: 1    kernel_size: 3    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "relu3"  type: "ReLU"  bottom: "conv3"  top: "conv3"}layer {  name: "conv4"  type: "Convolution"  bottom: "conv3"  top: "conv4"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 384    pad: 1    kernel_size: 3    group: 2    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0.1    }  }}layer {  name: "relu4"  type: "ReLU"  bottom: "conv4"  top: "conv4"}layer {  name: "conv5"  type: "Convolution"  bottom: "conv4"  top: "conv5"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 256    pad: 1    kernel_size: 3    group: 2    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0.1    }  }}layer {  name: "relu5"  type: "ReLU"  bottom: "conv5"  top: "conv5"}layer {  name: "pool5"  type: "Pooling"  bottom: "conv5"  top: "pool5"  pooling_param {    pool: MAX    kernel_size: 3    stride: 2  }}

2.2.3 全连接层
一个完整的全连接层的第一层为内积层:就是计算两个矩阵的内积,属于全连接神经网络。第二层就是ReLU激活函数,第三层则是Dropout层。

整个全连接部分有两个上述部分。

layer {  name: "fc6"  type: "InnerProduct"  bottom: "pool5"  top: "fc6"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 4096    weight_filler {      type: "gaussian"      std: 0.005    }    bias_filler {      type: "constant"      value: 0.1    }  }}layer {  name: "relu6"  type: "ReLU"  bottom: "fc6"  top: "fc6"}layer {  name: "drop6"  type: "Dropout"  bottom: "fc6"  top: "fc6"  dropout_param {    dropout_ratio: 0.5  }}layer {  name: "fc7"  type: "InnerProduct"  bottom: "fc6"  top: "fc7"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 4096    weight_filler {      type: "gaussian"      std: 0.005    }    bias_filler {      type: "constant"      value: 0.1    }  }}layer {  name: "relu7"  type: "ReLU"  bottom: "fc7"  top: "fc7"}layer {  name: "drop7"  type: "Dropout"  bottom: "fc7"  top: "fc7"  dropout_param {    dropout_ratio: 0.5  }}}

2.2.4 分类层
分类使用softmax

layer {  name: "fc8"  type: "InnerProduct"  bottom: "fc7"  top: "fc8"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1000    weight_filler {      type: "gaussian"      std: 0.01    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "accuracy"  type: "Accuracy"  bottom: "fc8"  bottom: "label"  top: "accuracy"  include {    phase: TEST  }}layer {  name: "loss"  type: "SoftmaxWithLoss"  bottom: "fc8"  bottom: "label"  top: "loss"}

VGGNet

看下面19层的VGGNet可以很容易看出,其实VGGNet就是AlexNet的加深版本。

这里写图片描述
1 模型特性
VGGNet探索了神经网络的深度与性能之间的关系,表明在结构相似的情况下,网络越深性能越好。
这里写图片描述

* 卷积核*
该模型中大量使用3*3的卷积核的串联,构造出16到19层的网络。

2个3*3的卷积核的串联相当于5*5的卷积核。
3个3*3的卷积核的串联相当于7*7的卷积核。

其意义在于7*7所需要的参数为49,3个3*3的卷积核参数为27个,几乎减少了一半。

在C中还是用了1*1的卷积核,而且输出通道和输入通道数并没有发生改变,只是起到了线性变换的作用,其意义在VGG中其实意义不大。

0 0
原创粉丝点击