CNN经典网络之AlexNet剖析

AlexNet VGG 》 Inception 》 ResNet 》 Inception-ResNet 》 ResNeXt 》 DenseNet 》DPN ( Dual Path Network )

基础

什么是卷积?什么是全连接?答案在属性函数中。

2、什么是神经元、连接?
在这里插入图片描述
什么是神经元?
上图中一个圈就是一个神经元。
单个神经元模型:
在这里插入图片描述
神经元就是一个函数,这个函数完成了神经元的功能。神经元=隐层的激活函数(如sigmoid、Relu等)=输出层函数(如softmax等)。这里激活函数或输出层函数都用 H ( x ) H(x) H(x)(Hypothesis function)来表示。也就是说神经元是 o u t p u t = H ( i n p u t ) output=H(input) output=H(input),其中 i n p u t = ( ∑ i = 0 n w i ∗ x i ) + b input=(\sum_{i=0}^nw_i*x_i)+b input=(i=0nwixi)+b(这是 n n n次连接)。 x i x_i xi可以是输入层的输入,也可以是隐层的输出。每一个神经元都有激活函数,有的层我们没有指定激活函数并不是没有而是激活函数 H ( x ) = x H(x)=x H(x)=x即输入等于输出。神经元的个数的本质就是进行多少次激活函数计算。

什么是连接?
直观来说图中一条带箭头的线就是一个连接,但这不是本质,连接的本质是一次计算 w i ∗ x i w_i*x_i wixi(而不是 w i ∗ x i + b w_i*x_i+b wixi+b)就是一次连接。

AlexNet各层分析

在这里插入图片描述
在这里插入图片描述
alexnet为了加快速度,采用两片GPU分别计算。
输入Input的图像规格: 224 ∗ 224 ∗ 3 224*224*3 2242243(RGB图像),实际上会经过预处理变为 227 ∗ 227 ∗ 3 227*227*3 2272273。其实,输入的是224还是227都没关系,因为第一层的padding=“VALID”。

为什么使用Sigmoid会梯度弥散,为什么Relu能解决Sigmoid的梯度弥散问题?

首先要明白什么是神经网络的一层?
  神经网络的一层就是神经元那一层。
神经网络一层的要素有哪些?
  输入、神经元功能(即激活函数)与输出。
神经网络层的命名?
  我们对神经网络一层的命名往往是用其输入的属性函数命名,比如属性函数是卷积,那么对应的就是卷积层,卷积结果就是卷积层的输入!

Block-1:
卷积层
  input=(N,227,227,3) (即tf中参数data_format=NHWC)
    kernal_shape=filter_shape=(11,11,3)
    kernals=filters=96个
    stride_shape=([4,4)
    padding=“VALID”
    激活函数=ReLu
    pad=(0,0)
  过程解释:
    1、根据padding判断图片是否需要用0填充,这里padding="VALID"所以不需要,所以pad=(0,0);
  为什么要进行padding操作?
  在卷积层中,处于中间位置的数值容易被进行多次的提取,但是边界数值的特征提取次数相对较少,为了能更好的把边界数值也利用上,而进行padding操作。要么把边界去掉,要么把原始数据矩阵的四周都补上一层0。

    2、将kernal按照stride滑过图片,将对应位置的元素相乘再求和;
    3、特征图大小:
    input_spatial_shape=[227,227];(input_spatial_shape是tf中的称呼)
    (input_spatial_shape[i]-kernal_shape[i])/stride_shape[i]+1=(227-11)/4+1=55
    所以单个特征图大小是 ( 55 , 55 ) (55,55) (55,55),一共有96个,为了计算的并行可以写成(55,55,96)
    4、对特征图中的元素作用激活函数;
  output=(N,55,55,96)
    权重参数: 11 ∗ 11 ∗ 3 ∗ 96 = 34848 11*11*3*96=34848 1111396=34848,偏置参数:96
    输出神经元个数(即output units): 55 ∗ 55 ∗ 96 = 290400 55*55*96= 290400 555596=290400,(由 227 ∗ 227 ∗ 3 = 154587 227*227*3=154587 2272273=154587变为290400)
    连接个数:总共有权重参数34848个,每个filter滑过图片进行多少次计算呢? ( 55 ∗ 55 ) ∗ 11 ∗ 11 ∗ 3 (55*55)*11*11*3 (5555)11113次,所以总共计算了 ( 55 ∗ 55 ) ∗ 11 ∗ 11 ∗ 3 ∗ 96 = 105415200 (55*55)*11*11*3*96=105415200 (5555)1111396=105415200次,所以总共有105415200个连接。

LRN层:
参考Local Response Normalization

MaxPooling层: 相当于降维操作
  input=(N,55,55,96)
    pool_shape=(3,3)
    stride_shape=(2,2)
    padding=‘VALID’
  过程解释:
    1、从一个3x3中选择最大的值
  output=(N,27,27,96)
    27是怎么计算的?
    input_spatial_shape=[27,27];
    (input_spatial_shape[i]-kernal_shape[i])/stride_shape[i]+1=(55-3)/2+1=27
    权重参数:0,偏置参数:0
    输出神经元个数(即output units): 27 ∗ 27 ∗ 96 = 69984 27*27*96= 69984 272796=69984,(由290400变为69984)
    连接个数:0
    可以看出pool层减少了神经元数量,没有新增参数,也不涉及连接,所以佐证pool不是神经网络的一层!

Block-2:
卷积层
  input=(N,27,27,96)
    kernal_shape=(5,5,96)
    kernals=256个
    stride=(1,1)
    padding=“SAME”
    pad=(2,2),(有的框架这个参数会自动计算)
    激活函数=ReLu
  过程解释:
    1、因为padding=“SAME”,需要判断是否填充,以及填充多少
    input_spatial_shape=[27,27]
    output_spatial_shape[0] = ceil(input_spatial_shape[0] / strides[0])=ceil(27/1)=27
    output_spatial_shape[1] = ceil(input_spatial_shape[1] / strides[1])=ceil(27/1)=27
    output_spatial_shape=(27,27)
    反推填充后的大小:
    padded_size[0]=output_spatial_shape[0]+kernal_size[0]-1=27+5-1=31
    padded_size[1]=output_spatial_shape[1]+kernal_size[1]-1=27+5-1=31
    padded_size=[31,31]
    也就是说:27+上面2行+下面2行=31,27+左面2列+右面2列=31,所以pad=(2,2),pad[0]=2表示上下各两行,pad[0]=2表示左右各两列
    2、对(N,31,31,96)用256个kernal_shape=(5,5,96)滑过,产生256个(27,27)的特征图
    3、对特征图中的元素作用激活函数;
  output=(N,27,27,256)
    权重参数: 5 ∗ 5 ∗ 96 ∗ 256 = 614400 5*5*96*256=614400 5596256=614400,偏置参数:256
    神经元个数: 27 ∗ 27 ∗ 256 = 186624 27*27*256= 186624 2727256=186624,(由69984变为186624)
    连接个数: ( 27 ∗ 27 ∗ 614400 ) / 2 = 447897600 / 2 = 223948800 (27*27*614400)/2=447897600/2=223948800 (2727614400)/2=447897600/2=223948800

LRN层:
参考Local Response Normalization

MaxPooling层:
  input=(N,27,27,256)
    pool_shape=(3,3),
    stride=(2,2),
    padding=‘VALID’
  过程解释:(27-3)/2+1=13
  output=(N,13,13,256)
    权重参数:0,偏置参数:0
    输出神经元个数: 13 ∗ 13 ∗ 256 = 43264 13*13*256= 43264 1313256=43264,(由186624变为43264)
    连接个数:0

Block-3:
卷积层
  input=(N,13,13,256)
    kernal_shape=(3,3,256),
    kernals=384个,
    stride=(1,1),
    padding=“SAME”,
    pad=(1,1)
    激活函数=ReLu
  过程解释:
    1、因为padding=“SAME”,需要判断是否填充,以及填充多少
    input_spatial_shape=[13,13]
    output_spatial_shape[0] = ceil(input_spatial_shape[0] / strides[0])=ceil(13/1)=13
    output_spatial_shape[1] = ceil(input_spatial_shape[1] / strides[1])=ceil(13/1)=13
    output_spatial_shape=(13,13)
    反推填充后的大小:
    padded_size[0]=output_spatial_shape[0]+kernal_size[0]-1=13+3-1=15
    padded_size[1]=output_spatial_shape[1]+kernal_size[1]-1=13+3-1=15
    padded_size=[15,15]
    也就是说上下各1行,左右各1列,都用0填充
    2、对(N,13,13,256)用384个shape=(3,3,256)的filter滑过,产生384个(13,13)的特征图
    3、对特征图中的元素作用激活函数;
  output=(N,13,13,384)
    权重参数: 3 ∗ 3 ∗ 256 ∗ 384 = 884736 3*3*256*384=884736 33256384=884736,偏置参数:384
    神经元个数: 13 ∗ 13 ∗ 384 = 64896 13*13*384= 64896 1313384=64896,(由43264变为64896)
    连接个数: 13 ∗ 13 ∗ 884736 = 149520384 13*13*884736=149520384 1313884736=149520384

Block-4:
卷积层
  input=(N,13,13,384)
    kernal_shape=(3,3,384),
    kernals=384个,
    stride=(1,1),
    padding=“SAME”,
    pad=(1,1)
    激活函数=ReLu
  过程解释:
    1、上下各1行,左右各1列,都用0填充
    2、对(N,13,13,384)用384个shape=(3,3,384)的filter滑过,产生384个(13,13)的特征图
    3、对特征图中的元素作用激活函数;
  output=(N,13,13,384)
    权重参数: 3 ∗ 3 ∗ 384 ∗ 384 = 1327104 3*3*384*384=1327104 33384384=1327104,偏置参数=384
    神经元个数: 13 ∗ 13 ∗ 384 = 64896 13*13*384= 64896 1313384=64896,(由64896变为64896)
    连接个数: ( 13 ∗ 13 ∗ 1327104 ) / 2 = 224280576 / 2 = 112140288 (13*13*1327104)/2= 224280576/2=112140288 (13131327104)/2=224280576/2=112140288

Block-5:
卷积层
  input=(N,13,13,384)
    kernal_shape=(3,3,384),
    kernals=256个,
    stride=(1,1),
    padding=“SAME”,
    pad=(1,1)
    激活函数=ReLu
  过程解释:
    1、上下各1行,左右各1列,都用0填充
    2、对(N,13,13,384)用256个shape=(3,3,384)的filter滑过,产生256个(13,13)的特征图
    3、对特征图中的元素作用激活函数;
  output=(N,13,13,256)
    权重参数: 3 ∗ 3 ∗ 384 ∗ 256 = 884736 3*3*384*256=884736 33384256=884736,偏置参数=256
    神经元个数: 13 ∗ 13 ∗ 256 = 43264 13*13*256= 43264 1313256=43264,(由64896变为43264)
    连接个数: ( 13 ∗ 13 ∗ 884736 ) / 2 = 149520384 / 2 = 74760192 (13*13*884736)/2 =149520384/2=74760192 (1313884736)/2=149520384/2=74760192

MaxPooling层:
  input=(N,13,13,256)
    pool_size=(3,3],
    stride=(2,2),
    padding=‘VALID’
  过程解释:(13-3)/2+1=6
  output=(N,6,6,256)
    权重参数:0,偏置参数:0
    输出神经元个数: 6 ∗ 6 ∗ 256 = 9216 6*6*256= 9216 66256=9216,(由 43264 变 为 9216 43264变为9216 432649216
    连接个数:0

第2、4、5层求连接个数的时候要减半的原因(有待理解)
在这里插入图片描述
从第6层开始就有两个实现版本,一个是alexnet原论文版本叫v1版,另一个是改造后版本叫v2版
在这里插入图片描述
v1版:
Block-6:
全连接层:
    进行flat操作input=(N,9216) (其中 9216 = 6 ∗ 6 ∗ 256 9216=6*6*256 9216=66256
    kernal_shape=(9216,),
    kernals=4096个,
    stride=(1,1),
    padding=“VALID”,
    pad=(0,0)
    激活函数=ReLu
  过程解释:
    1、对(N,9216)用4096个shape=(9216,)的filter滑过,产生4096个的特征值,此时就不再是特征图了,由最开始的输入(N,227,227,3)变成(N,4096),即一个图片变成4096个特征值。
    2、对特征图中的元素作用激活函数;
  output=(N,4096)
    权重参数: 6 ∗ 6 ∗ 256 ∗ 4096 = 37748736 6*6*256*4096=37748736 662564096=37748736,偏置参数=4096
    神经元个数:4096
    连接个数=输入神经元数*输出神经元数= ( 6 ∗ 6 ∗ 256 ) ∗ ( 4096 ) (6*6*256)*(4096) (66256)(4096)=权重参数个数=37748736

可以看出全连接层是以一种特殊的卷积层,即卷积核shape=输入shape且padding=“VALID”。

Block-7:
全连接层:
  input=(N,4096)
    kernal_shape=(4096,),
    kernals=4096个,
    stride=(1,1),
    padding=“VALID”,
    pad=(0,0)
    激活函数=ReLu
  过程解释:
  output=(N,4096)
    权重参数:4096*4096=16777216,偏置参数=4096
    神经元个数:4096
    连接个数=16777216

Block-8(输出层):
全连接层:
  input=(N,4096)
    kernal_shape=(4096,),
    kernals=1000个,
    stride=(1,1),
    padding=“VALID”,
    pad=(0,0)
    Softmax
  过程解释:
    1、这里的1000=总的分类数
    2、Softmax就是激活函数
  output=(N,4096)
    权重参数:4096*1000=4096000个(这里没有偏置参数,如果有就是4096个)
    神经元个数:1000
    连接个数=4096000

Block信息
1Convolution11x11x3x96; (Stride(4,4); Pad(0,0), ReLu, LRN=(k,α, β, n)=(2, 10^{−4}, 0.75,5)
MaxPooling3x3 - Stride(2,2)
2Convolution5x5x96x256 - Stride(1,1) - Pad(2,2), ReLu, LRN=(k,α, β, n)=(2, 10^{−4}, 0.75,5)
MaxPooling3x3 - Stride(2,2)
3Convolution3x3x256x384 - Stride(1,1) - Pad(1,1), ReLu
4Convolution3x3x384x384 - Stride(1,2) - Pad(1,1), ReLu
5Convolution3x3x384x256 - Stride(1,1) - Pad(1,1), ReLu
MaxPooling3x3 - Stride(2,2)
6Fully connected9216x4096 - Stride(1,1) - Pad(0,0), ReLu
7Fully connected9216x4096 - Stride(1,1) - Pad(0,0), ReLu
8Fully connected4096x1000 - Stride(1,1) - Pad(0,0),Softmax

这里的ReLU、Softmax都是假设函数,那么MaxPooling层没有假设函数吗?有的,其假设函数是线性的,即 H j = H ( A j ) = A j H_j=H(A_j)=A_j Hj=H(Aj)=Aj

v2版:
Block-6:
卷积层:
  input=(N,6,6,256)
    kernal_shape=(5,5,256),
    kernals=4096个,
    stride=(1,1),
    padding=“VALID”,
    pad=(0,0)
    激活函数=ReLu
  过程解释:
    1、对(N,6,6,256)用4096个shape=(5,5,256)的filter滑过,产生4096个的特征值
    2、对特征图中的元素作用激活函数;
  output=(N,4096)

Block-7:
Dropout层:
  input=(N,4096)
  output=(N,4096)

Block-8(输出层):
卷积层:
  input=(N,4096)
    kernal_shape=(4096,),
    kernals=1000个,
    stride=(1,1),
    padding=“VALID”,
    pad=(0,0)
    Softmax
  过程解释:
    1、这里的1000=总的分类数
    2、Softmax
  output=(N,4096)

v2版本的代码实现tf-slim的\research\slim\nets\alexnet.py

模型是什么?
比如线性回归中由 y ′ = ( ∑ i = 0 n w i ∗ x i ) + b y'=(\sum_{i=0}^nw_i*x_i)+b y=(i=0nwixi)+b,这里的 n n n w i w_i wi b b b就是我们要训练的参数,也就是我们的模型。那么alexnet中要训练的参数是什么?

Block神经元数权重参数个数连接数
129040034848105415200
2186624307200223948800
364896884736149520384
464896663552112140288
54326444236874760192
640963774873637748736
740961677721616777216
8100040960004096000
总计65927260954656724406816

alexnet的模型参数是6千万数量级。

模型是怎么训练的?这个问题等同于参数是如何更新的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值