【转】深度学习AlexNet模型详细分析

原文链接:https://blog.csdn.net/zyqdragon/article/details/72353420

 

Alex在2012年提出的alexnet网络结构模型引爆了神经网络的应用热潮,并赢得了2012届图像识别大赛的冠军,使得CNN成为在图像分类上的核心算法模型。

接下来本文对该网络配置结构中各个层进行详细的解读(训练阶段):

注:下述关于卷积核的尺寸来自于Alex在2012年发表的经典论文。

 

1. conv1阶段DFD(data flow diagram):

 

第一层输入数据为原始的227*227*3的图像,这个图像被11*11*3的卷积核进行卷积运算,卷积核对原始图像的每次卷积都生成一个新的像素。卷积核沿原始图像的x轴方向和y轴方向两个方向移动,移动的步长是4个像素。因此,卷积核在移动的过程中会生成(227-11)/4+1=55个像素(227个像素减去11,正好是54,即生成54个像素,再加上被减去的11也对应生成一个像素),行和列的55*55个像素形成对原始图像卷积之后的像素层。共有96个卷积核,会生成55*55*96个卷积后的像素层。96个卷积核分成2组,每组48个卷积核。对应生成2组55*55*48的卷积后的像素层数据。这些像素层经过relu1单元的处理,生成激活像素层,尺寸仍为2组55*55*48的像素层数据。

这些像素层经过pool运算(池化运算)的处理,池化运算的尺度为3*3,运算的步长为2,则池化后图像的尺寸为(55-3)/2+1=27。 即池化后像素的规模为27*27*96;然后经过归一化处理,归一化运算的尺度为5*5;第一卷积层运算结束后形成的像素层的规模为27*27*96。分别对应96个卷积核所运算形成。这96层像素层分为2组,每组48个像素层,每组在一个独立的GPU上进行运算。

反向传播时,每个卷积核对应一个偏差值。即第一层的96个卷积核对应上层输入的96个偏差值。

2. conv2阶段DFD(data flow diagram):

 

第二层输入数据为第一层输出的27*27*96的像素层,为便于后续处理,每幅像素层的左右两边和上下两边都要填充2个像素;27*27*96的像素数据分成27*27*48的两组像素数据,两组数据分别再两个不同的GPU中进行运算。每组像素数据被5*5*48的卷积核进行卷积运算,卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿原始图像的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,卷积核在移动的过程中会生成(27-5+2*2)/1+1=27个像素。(27个像素减去5,正好是22,在加上上下、左右各填充的2个像素,即生成26个像素,再加上被减去的5也对应生成一个像素),行和列的27*27个像素形成对原始图像卷积之后的像素层。共有256个5*5*48卷积核;这256个卷积核分成两组,每组针对一个GPU中的27*27*48的像素进行卷积运算。会生成两组27*27*128个卷积后的像素层。这些像素层经过relu2单元的处理,生成激活像素层,尺寸仍为两组27*27*128的像素层。

这些像素层经过pool运算(池化运算)的处理,池化运算的尺度为3*3,运算的步长为2,则池化后图像的尺寸为(57-3)/2+1=13。 即池化后像素的规模为2组13*13*128的像素层;然后经过归一化处理,归一化运算的尺度为5*5;第二卷积层运算结束后形成的像素层的规模为2组13*13*128的像素层。分别对应2组128个卷积核所运算形成。每组在一个GPU上进行运算。即共256个卷积核,共2个GPU进行运算。

反向传播时,每个卷积核对应一个偏差值。即第一层的96个卷积核对应上层输入的256个偏差值。

 

3. conv3阶段DFD(data flow diagram):

 

第三层输入数据为第二层输出的2组13*13*128的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有192个卷积核,每个卷积核的尺寸是3*3*256。因此,每个GPU中的卷积核都能对2组13*13*128的像素层的所有数据进行卷积运算。卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿像素层数据的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,运算后的卷积核的尺寸为(13-3+1*2)/1+1=13(13个像素减去3,正好是10,在加上上下、左右各填充的1个像素,即生成12个像素,再加上被减去的3也对应生成一个像素),每个GPU中共13*13*192个卷积核。2个GPU中共13*13*384个卷积后的像素层。这些像素层经过relu3单元的处理,生成激活像素层,尺寸仍为2组13*13*192像素层,共13*13*384个像素层。

 

4. conv4阶段DFD(data flow diagram):

第四层输入数据为第三层输出的2组13*13*192的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有192个卷积核,每个卷积核的尺寸是3*3*192。因此,每个GPU中的卷积核能对1组13*13*192的像素层的数据进行卷积运算。卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿像素层数据的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,运算后的卷积核的尺寸为(13-3+1*2)/1+1=13(13个像素减去3,正好是10,在加上上下、左右各填充的1个像素,即生成12个像素,再加上被减去的3也对应生成一个像素),每个GPU中共13*13*192个卷积核。2个GPU中共13*13*384个卷积后的像素层。这些像素层经过relu4单元的处理,生成激活像素层,尺寸仍为2组13*13*192像素层,共13*13*384个像素层。

 

5. conv5阶段DFD(data flow diagram):

 

第五层输入数据为第四层输出的2组13*13*192的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有128个卷积核,每个卷积核的尺寸是3*3*192。因此,每个GPU中的卷积核能对1组13*13*192的像素层的数据进行卷积运算。卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿像素层数据的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,运算后的卷积核的尺寸为(13-3+1*2)/1+1=13(13个像素减去3,正好是10,在加上上下、左右各填充的1个像素,即生成12个像素,再加上被减去的3也对应生成一个像素),每个GPU中共13*13*128个卷积核。2个GPU中共13*13*256个卷积后的像素层。这些像素层经过relu5单元的处理,生成激活像素层,尺寸仍为2组13*13*128像素层,共13*13*256个像素层。

2组13*13*128像素层分别在2个不同GPU中进行池化(pool)运算处理。池化运算的尺度为3*3,运算的步长为2,则池化后图像的尺寸为(13-3)/2+1=6。 即池化后像素的规模为两组6*6*128的像素层数据,共6*6*256规模的像素层数据。

 

6. fc6阶段DFD(data flow diagram):

 

第六层输入数据的尺寸是6*6*256,采用6*6*256尺寸的滤波器对第六层的输入数据进行卷积运算;每个6*6*256尺寸的滤波器对第六层的输入数据进行卷积运算生成一个运算结果,通过一个神经元输出这个运算结果;共有4096个6*6*256尺寸的滤波器对输入数据进行卷积运算,通过4096个神经元输出运算结果;这4096个运算结果通过relu激活函数生成4096个值;并通过drop运算后输出4096个本层的输出结果值。

     由于第六层的运算过程中,采用的滤波器的尺寸(6*6*256)与待处理的feature map的尺寸(6*6*256)相同,即滤波器中的每个系数只与feature map中的一个像素值相乘;而其它卷积层中,每个滤波器的系数都会与多个feature map中像素值相乘;因此,将第六层称为全连接层。

第五层输出的6*6*256规模的像素层数据与第六层的4096个神经元进行全连接,然后经由relu6进行处理后生成4096个数据,再经过dropout6处理后输出4096个数据。

 

7. fc7阶段DFD(data flow diagram):

 

第六层输出的4096个数据与第七层的4096个神经元进行全连接,然后经由relu7进行处理后生成4096个数据,再经过dropout7处理后输出4096个数据。

 

8. fc8阶段DFD(data flow diagram):

 

第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出被训练的数值。

 

Alexnet网络中各个层发挥的作用如下表所述:

 

在学习过程中,我们使用随机梯度下降法和一批大小为128、动力为0.9、权重衰减为0.0005的样例来训练我们的网络。我们发现,这少量的权重衰减对于模型学习是重要的。换句话说,这里的权重衰减不仅仅是一个正则化矩阵:它减少了模型的训练误差。对于权重w的更新规则为:

其中i是迭代指数,v是动力变量,ε是学习率,是目标关于w、对求值的导数在第i批样例上的平均值。我们用一个均值为0、标准差为0.01的高斯分布初始化了每一层的权重。我们用常数1初始化了第二、第四和第五个卷积层以及全连接隐层的神经元偏差。该初始化通过提供带正输入的ReLU来加速学习的初级阶段。我们在其余层用常数0初始化神经元偏差。
    对于所有层都使用了相等的学习率,这是在整个训练过程中手动调整的。我们遵循的启发式是,当验证误差率在当前学习率下不再提高时,就将学习率除以10。学习率初始化为0.01,在终止前降低三次。作者训练该网络时大致将这120万张图像的训练集循环了90次,在两个NVIDIA GTX 580 3GB GPU上花了五到六天。

 

各种layer的operation更多解释可以参考http://caffe.berkeleyvision.org/tutorial/layers.html

从计算该模型的数据流过程中,该模型参数大概5kw+。

在caffe开源的model样例中,它也给出了alexnet的复现,具体网络配置文件如下https://github.com/BVLC/caffe/blob/master/models/bvlc_reference_caffenet/train_val.prototxt

 

caffe的输出中也有包含这块的内容日志,详情如下:

1. I0721 10:38:15.326920  4692 net.cpp:125] Top shape: 256 3 227 227 (39574272) :output data of layer 0

2. I0721 10:38:15.326971  4692 net.cpp:125] Top shape: 256 1 1 1 (256)  

3. I0721 10:38:15.326982  4692 net.cpp:156] data does not need backward computation.  

4. I0721 10:38:15.327003  4692 net.cpp:74] Creating Layer conv1  

5. I0721 10:38:15.327011  4692 net.cpp:84] conv1 <- data  

6. I0721 10:38:15.327033  4692 net.cpp:110] conv1 -> conv1  

7. I0721 10:38:16.721956  4692 net.cpp:125] Top shape: 256 96 55 55 (74342400)  

8. I0721 10:38:16.722030  4692 net.cpp:151] conv1 needs backward computation.  

9. I0721 10:38:16.722059  4692 net.cpp:74] Creating Layer relu1  

10. I0721 10:38:16.722070  4692 net.cpp:84] relu1 <- conv1  

11. I0721 10:38:16.722082  4692 net.cpp:98] relu1 -> conv1 (in-place)  

12. I0721 10:38:16.722096  4692 net.cpp:125] Top shape: 256 96 55 55 (74342400)  

13. I0721 10:38:16.722105  4692 net.cpp:151] relu1 needs backward computation.  

14. I0721 10:38:16.722116  4692 net.cpp:74] Creating Layer pool1  

15. I0721 10:38:16.722125  4692 net.cpp:84] pool1 <- conv1  

16. I0721 10:38:16.722133  4692 net.cpp:110] pool1 -> pool1  

17. I0721 10:38:16.722167  4692 net.cpp:125] Top shape: 256 96 27 27 (17915904)  

18. I0721 10:38:16.722187  4692 net.cpp:151] pool1 needs backward computation.  

19. I0721 10:38:16.722205  4692 net.cpp:74] Creating Layer norm1  

20. I0721 10:38:16.722221  4692 net.cpp:84] norm1 <- pool1  

21. I0721 10:38:16.722234  4692 net.cpp:110] norm1 -> norm1  

22. I0721 10:38:16.722251  4692 net.cpp:125] Top shape: 256 96 27 27 (17915904): output data of layer 1

23. I0721 10:38:16.722260  4692 net.cpp:151] norm1 needs backward computation.  

24. I0721 10:38:16.722272  4692 net.cpp:74] Creating Layer conv2  

25. I0721 10:38:16.722280  4692 net.cpp:84] conv2 <- norm1  

26. I0721 10:38:16.722290  4692 net.cpp:110] conv2 -> conv2  

27. I0721 10:38:16.725225  4692 net.cpp:125] Top shape: 256 256 27 27 (47775744)  

28. I0721 10:38:16.725242  4692 net.cpp:151] conv2 needs backward computation.  

29. I0721 10:38:16.725253  4692 net.cpp:74] Creating Layer relu2  

30. I0721 10:38:16.725261  4692 net.cpp:84] relu2 <- conv2  

31. I0721 10:38:16.725270  4692 net.cpp:98] relu2 -> conv2 (in-place)  

32. I0721 10:38:16.725280  4692 net.cpp:125] Top shape: 256 256 27 27 (47775744)  

33. I0721 10:38:16.725288  4692 net.cpp:151] relu2 needs backward computation.  

34. I0721 10:38:16.725298  4692 net.cpp:74] Creating Layer pool2  

35. I0721 10:38:16.725307  4692 net.cpp:84] pool2 <- conv2  

36. I0721 10:38:16.725317  4692 net.cpp:110] pool2 -> pool2  

37. I0721 10:38:16.725329  4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)  

38. I0721 10:38:16.725338  4692 net.cpp:151] pool2 needs backward computation.  

39. I0721 10:38:16.725358  4692 net.cpp:74] Creating Layer norm2  

40. I0721 10:38:16.725368  4692 net.cpp:84] norm2 <- pool2  

41. I0721 10:38:16.725378  4692 net.cpp:110] norm2 -> norm2  

42. I0721 10:38:16.725389  4692 net.cpp:125] Top shape: 256 256 13 13 (11075584): output data of layer 2

43. I0721 10:38:16.725399  4692 net.cpp:151] norm2 needs backward computation.  

44. I0721 10:38:16.725409  4692 net.cpp:74] Creating Layer conv3  

45. I0721 10:38:16.725419  4692 net.cpp:84] conv3 <- norm2  

46. I0721 10:38:16.725427  4692 net.cpp:110] conv3 -> conv3  

47. I0721 10:38:16.735193  4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)  

48. I0721 10:38:16.735213  4692 net.cpp:151] conv3 needs backward computation.  

49. I0721 10:38:16.735224  4692 net.cpp:74] Creating Layer relu3  

50. I0721 10:38:16.735234  4692 net.cpp:84] relu3 <- conv3  

51. I0721 10:38:16.735242  4692 net.cpp:98] relu3 -> conv3 (in-place)  

52. I0721 10:38:16.735250  4692 net.cpp:125] Top shape: 256 384 13 13 (16613376): output data of layer 3

53. I0721 10:38:16.735258  4692 net.cpp:151] relu3 needs backward computation.  

54. I0721 10:38:16.735302  4692 net.cpp:74] Creating Layer conv4  

55. I0721 10:38:16.735312  4692 net.cpp:84] conv4 <- conv3  

56. I0721 10:38:16.735321  4692 net.cpp:110] conv4 -> conv4  

57. I0721 10:38:16.743952  4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)  

58. I0721 10:38:16.743988  4692 net.cpp:151] conv4 needs backward computation.  

59. I0721 10:38:16.744000  4692 net.cpp:74] Creating Layer relu4  

60. I0721 10:38:16.744010  4692 net.cpp:84] relu4 <- conv4  

61. I0721 10:38:16.744020  4692 net.cpp:98] relu4 -> conv4 (in-place)  

62. I0721 10:38:16.744030  4692 net.cpp:125] Top shape: 256 384 13 13 (16613376): output data of layer 4

63. I0721 10:38:16.744038  4692 net.cpp:151] relu4 needs backward computation.  

64. I0721 10:38:16.744050  4692 net.cpp:74] Creating Layer conv5  

65. I0721 10:38:16.744057  4692 net.cpp:84] conv5 <- conv4  

66. I0721 10:38:16.744067  4692 net.cpp:110] conv5 -> conv5  

67. I0721 10:38:16.748935  4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)  

68. I0721 10:38:16.748955  4692 net.cpp:151] conv5 needs backward computation.  

69. I0721 10:38:16.748965  4692 net.cpp:74] Creating Layer relu5  

70. I0721 10:38:16.748975  4692 net.cpp:84] relu5 <- conv5  

71. I0721 10:38:16.748983  4692 net.cpp:98] relu5 -> conv5 (in-place)  

72. I0721 10:38:16.748998  4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)  

73. I0721 10:38:16.749011  4692 net.cpp:151] relu5 needs backward computation.  

74. I0721 10:38:16.749022  4692 net.cpp:74] Creating Layer pool5  

75. I0721 10:38:16.749030  4692 net.cpp:84] pool5 <- conv5  

76. I0721 10:38:16.749039  4692 net.cpp:110] pool5 -> pool5  

77. I0721 10:38:16.749050  4692 net.cpp:125] Top shape: 256 256 6 6 (2359296): output data of layer 5

78. I0721 10:38:16.749058  4692 net.cpp:151] pool5 needs backward computation.  

79. I0721 10:38:16.749074  4692 net.cpp:74] Creating Layer fc6  

80. I0721 10:38:16.749083  4692 net.cpp:84] fc6 <- pool5  

81. I0721 10:38:16.749091  4692 net.cpp:110] fc6 -> fc6  

82. I0721 10:38:17.160079  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)  

83. I0721 10:38:17.160148  4692 net.cpp:151] fc6 needs backward computation.  

84. I0721 10:38:17.160166  4692 net.cpp:74] Creating Layer relu6  

85. I0721 10:38:17.160177  4692 net.cpp:84] relu6 <- fc6  

86. I0721 10:38:17.160190  4692 net.cpp:98] relu6 -> fc6 (in-place)  

87. I0721 10:38:17.160202  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)  

88. I0721 10:38:17.160212  4692 net.cpp:151] relu6 needs backward computation.  

89. I0721 10:38:17.160222  4692 net.cpp:74] Creating Layer drop6  

90. I0721 10:38:17.160230  4692 net.cpp:84] drop6 <- fc6  

91. I0721 10:38:17.160238  4692 net.cpp:98] drop6 -> fc6 (in-place)  

92. I0721 10:38:17.160258  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576):output data of layer 6

93. I0721 10:38:17.160265  4692 net.cpp:151] drop6 needs backward computation.  

94. I0721 10:38:17.160277  4692 net.cpp:74] Creating Layer fc7  

95. I0721 10:38:17.160286  4692 net.cpp:84] fc7 <- fc6  

96. I0721 10:38:17.160295  4692 net.cpp:110] fc7 -> fc7  

97. I0721 10:38:17.342094  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)  

98. I0721 10:38:17.342157  4692 net.cpp:151] fc7 needs backward computation.  

99. I0721 10:38:17.342175  4692 net.cpp:74] Creating Layer relu7  

100. I0721 10:38:17.342185  4692 net.cpp:84] relu7 <- fc7  

101. I0721 10:38:17.342198  4692 net.cpp:98] relu7 -> fc7 (in-place)  

102. I0721 10:38:17.342208  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)  

103. I0721 10:38:17.342217  4692 net.cpp:151] relu7 needs backward computation.  

104. I0721 10:38:17.342228  4692 net.cpp:74] Creating Layer drop7  

105. I0721 10:38:17.342236  4692 net.cpp:84] drop7 <- fc7  

106. I0721 10:38:17.342245  4692 net.cpp:98] drop7 -> fc7 (in-place)  

107. I0721 10:38:17.342254  4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576):output data of layer 7

108. I0721 10:38:17.342262  4692 net.cpp:151] drop7 needs backward computation.  

109. I0721 10:38:17.342274  4692 net.cpp:74] Creating Layer fc8  

110. I0721 10:38:17.342283  4692 net.cpp:84] fc8 <- fc7  

111. I0721 10:38:17.342291  4692 net.cpp:110] fc8 -> fc8  

112. I0721 10:38:17.343199  4692 net.cpp:125] Top shape: 256 22 1 1 (5632)  

113. I0721 10:38:17.343214  4692 net.cpp:151] fc8 needs backward computation.  

114. I0721 10:38:17.343231  4692 net.cpp:74] Creating Layer loss  

115. I0721 10:38:17.343240  4692 net.cpp:84] loss <- fc8  

116. I0721 10:38:17.343250  4692 net.cpp:84] loss <- label  

117. I0721 10:38:17.343264  4692 net.cpp:151] loss needs backward computation.  

118. I0721 10:38:17.343305  4692 net.cpp:173] Collecting Learning Rate and Weight Decay.  

119. I0721 10:38:17.343327  4692 net.cpp:166] Network initialization done.  

120. I0721 10:38:17.343335  4692 net.cpp:167] Memory required for Data 1073760256 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值