一、簡單介紹
vgg和googlenet是2014年imagenet競賽的雙雄,這兩類模型結構有一個共同特點是go deeper。跟googlenet不同的是。vgg繼承了lenet以及alexnet的一些框架。尤其是跟alexnet框架很像。vgg也是5個group的卷積、2層fc圖像特征、一層fc分類特征,能夠看做和alexnet一樣總共8個part。依據前5個卷積group。每一個group中的不同配置,vgg論文中給出了A~E這五種配置。卷積層數從8到16遞增。
從論文中能夠看到從8到16隨着卷積層的一步步加深,貌似通過加深卷積層數也已經到達准確率提升的瓶頸了。后面的有一些論文針對卷積層輸入的前處理(比如batch normalization)和輸出的后處理(比如prelu)做了研究。再進一步的提升方向會是什么呢?這個值得大家去深入思考。
二、網絡分析
我依據http://cs.stanford.edu/people/karpathy/vgg_train_val.prototxt配置文件以及vgg論文指導改動得到了vgg_A網絡結構。
在改動的過程中你會發現vgg為了做不同深度網絡之間的對照,然后又不至於太多的改動網絡。vgg中給全部的卷積層以及pool層都設置了一樣的層操作參數,確保了每一個group出來的shape都是一致的。無論你在卷積group中加多少層的卷積。
三、網絡日志
下面是詳細的shape log:
i0701 17:01:10.548092 26739 data_layer.cpp:85] output data size: 100,3,224,224 i0701 17:01:10.736845 26739 net.cpp:206] top shape: 100 3 224 224 (15052800) i0701 17:01:10.736912 26739 net.cpp:206] top shape: 100 (100) i0701 17:01:10.736929 26739 layer_factory.hpp:75] creating layer conv1_1 i0701 17:01:10.736968 26739 net.cpp:166] creating layer conv1_1 i0701 17:01:10.736979 26739 net.cpp:496] conv1_1 <- data i0701 17:01:10.737004 26739 net.cpp:452] conv1_1 -> conv1_1 i0701 17:01:10.737030 26739 net.cpp:197] setting up conv1_1 i0701 17:01:10.738733 26739 net.cpp:206] top shape: 100 64 224 224 (321126400) i0701 17:01:10.738770 26739 layer_factory.hpp:75] creating layer relu1_1 i0701 17:01:10.738786 26739 net.cpp:166] creating layer relu1_1 i0701 17:01:10.738824 26739 net.cpp:496] relu1_1 <- conv1_1 i0701 17:01:10.738838 26739 net.cpp:439] relu1_1 -> conv1_1 (in-place) i0701 17:01:10.738853 26739 net.cpp:197] setting up relu1_1 i0701 17:01:10.738867 26739 net.cpp:206] top shape: 100 64 224 224 (321126400) i0701 17:01:10.738878 26739 layer_factory.hpp:75] creating layer pool1 i0701 17:01:10.738890 26739 net.cpp:166] creating layer pool1 i0701 17:01:10.738900 26739 net.cpp:496] pool1 <- conv1_1 i0701 17:01:10.738914 26739 net.cpp:452] pool1 -> pool1 i0701 17:01:10.738930 26739 net.cpp:197] setting up pool1 i0701 17:01:10.738963 26739 net.cpp:206] top shape: 100 64 112 112 (80281600) i0701 17:01:10.738975 26739 layer_factory.hpp:75] creating layer conv2_1 i0701 17:01:10.738992 26739 net.cpp:166] creating layer conv2_1 i0701 17:01:10.739001 26739 net.cpp:496] conv2_1 <- pool1 i0701 17:01:10.739017 26739 net.cpp:452] conv2_1 -> conv2_1 i0701 17:01:10.739030 26739 net.cpp:197] setting up conv2_1 i0701 17:01:10.746640 26739 net.cpp:206] top shape: 100 128 112 112 (160563200) i0701 17:01:10.746669 26739 layer_factory.hpp:75] creating layer relu2_1 i0701 17:01:10.746682 26739 net.cpp:166] creating layer relu2_1 i0701 17:01:10.746691 26739 net.cpp:496] relu2_1 <- conv2_1 i0701 17:01:10.746702 26739 net.cpp:439] relu2_1 -> conv2_1 (in-place) i0701 17:01:10.746714 26739 net.cpp:197] setting up relu2_1 i0701 17:01:10.746726 26739 net.cpp:206] top shape: 100 128 112 112 (160563200) i0701 17:01:10.746734 26739 layer_factory.hpp:75] creating layer pool2 i0701 17:01:10.746749 26739 net.cpp:166] creating layer pool2 i0701 17:01:10.746759 26739 net.cpp:496] pool2 <- conv2_1 i0701 17:01:10.746770 26739 net.cpp:452] pool2 -> pool2 i0701 17:01:10.746783 26739 net.cpp:197] setting up pool2 i0701 17:01:10.746798 26739 net.cpp:206] top shape: 100 128 56 56 (40140800) i0701 17:01:10.746809 26739 layer_factory.hpp:75] creating layer conv3_1 i0701 17:01:10.746809 26739 layer_factory.hpp:75] creating layer conv3_1 i0701 17:01:10.746825 26739 net.cpp:166] creating layer conv3_1 i0701 17:01:10.746835 26739 net.cpp:496] conv3_1 <- pool2 i0701 17:01:10.746846 26739 net.cpp:452] conv3_1 -> conv3_1 i0701 17:01:10.746860 26739 net.cpp:197] setting up conv3_1 i0701 17:01:10.747910 26739 net.cpp:206] top shape: 100 256 56 56 (80281600) i0701 17:01:10.747939 26739 layer_factory.hpp:75] creating layer relu3_1 i0701 17:01:10.747954 26739 net.cpp:166] creating layer relu3_1 i0701 17:01:10.747963 26739 net.cpp:496] relu3_1 <- conv3_1 i0701 17:01:10.747974 26739 net.cpp:439] relu3_1 -> conv3_1 (in-place) i0701 17:01:10.747985 26739 net.cpp:197] setting up relu3_1 i0701 17:01:10.747997 26739 net.cpp:206] top shape: 100 256 56 56 (80281600) i0701 17:01:10.748009 26739 layer_factory.hpp:75] creating layer conv3_2 i0701 17:01:10.748021 26739 net.cpp:166] creating layer conv3_2 i0701 17:01:10.748030 26739 net.cpp:496] conv3_2 <- conv3_1 i0701 17:01:10.748045 26739 net.cpp:452] conv3_2 -> conv3_2 i0701 17:01:10.748060 26739 net.cpp:197] setting up conv3_2 i0701 17:01:10.750586 26739 net.cpp:206] top shape: 100 256 56 56 (80281600) i0701 17:01:10.750610 26739 layer_factory.hpp:75] creating layer relu3_2 i0701 17:01:10.750624 26739 net.cpp:166] creating layer relu3_2 i0701 17:01:10.750635 26739 net.cpp:496] relu3_2 <- conv3_2 i0701 17:01:10.750648 26739 net.cpp:439] relu3_2 -> conv3_2 (in-place) i0701 17:01:10.750669 26739 net.cpp:197] setting up relu3_2 i0701 17:01:10.750681 26739 net.cpp:206] top shape: 100 256 56 56 (80281600) i0701 17:01:10.750690 26739 layer_factory.hpp:75] creating layer pool3 i0701 17:01:10.750702 26739 net.cpp:166] creating layer pool3 i0701 17:01:10.750710 26739 net.cpp:496] pool3 <- conv3_2 i0701 17:01:10.750725 26739 net.cpp:452] pool3 -> pool3 i0701 17:01:10.750740 26739 net.cpp:197] setting up pool3 i0701 17:01:10.750756 26739 net.cpp:206] top shape: 100 256 28 28 (20070400) i0701 17:01:10.750764 26739 layer_factory.hpp:75] creating layer conv4_1 i0701 17:01:10.750779 26739 net.cpp:166] creating layer conv4_1 i0701 17:01:10.750788 26739 net.cpp:496] conv4_1 <- pool3 i0701 17:01:10.750800 26739 net.cpp:452] conv4_1 -> conv4_1 i0701 17:01:10.750825 26739 net.cpp:197] setting up conv4_1 i0701 17:01:10.756436 26739 net.cpp:206] top shape: 100 512 28 28 (40140800) i0701 17:01:10.756474 26739 layer_factory.hpp:75] creating layer relu4_1 i0701 17:01:10.756489 26739 net.cpp:166] creating layer relu4_1 i0701 17:01:10.756499 26739 net.cpp:496] relu4_1 <- conv4_1 i0701 17:01:10.756510 26739 net.cpp:439] relu4_1 -> conv4_1 (in-place) i0701 17:01:10.756523 26739 net.cpp:197] setting up relu4_1 i0701 17:01:10.756536 26739 net.cpp:206] top shape: 100 512 28 28 (40140800) i0701 17:01:10.756546 26739 layer_factory.hpp:75] creating layer conv4_2 i0701 17:01:10.756559 26739 net.cpp:166] creating layer conv4_2 i0701 17:01:10.756568 26739 net.cpp:496] conv4_2 <- conv4_1 i0701 17:01:10.756583 26739 net.cpp:452] conv4_2 -> conv4_2 i0701 17:01:10.756597 26739 net.cpp:197] setting up conv4_2 i0701 17:01:10.766434 26739 net.cpp:206] top shape: 100 512 28 28 (40140800) i0701 17:01:10.766474 26739 layer_factory.hpp:75] creating layer relu4_2 i0701 17:01:10.766490 26739 net.cpp:166] creating layer relu4_2 i0701 17:01:10.766500 26739 net.cpp:496] relu4_2 <- conv4_2 i0701 17:01:10.766513 26739 net.cpp:439] relu4_2 -> conv4_2 (in-place) i0701 17:01:10.766531 26739 net.cpp:197] setting up relu4_2 i0701 17:01:10.766543 26739 net.cpp:206] top shape: 100 512 28 28 (40140800) i0701 17:01:10.766552 26739 layer_factory.hpp:75] creating layer pool4 i0701 17:01:10.766573 26739 net.cpp:166] creating layer pool4 i0701 17:01:10.766582 26739 net.cpp:496] pool4 <- conv4_2 i0701 17:01:10.766595 26739 net.cpp:452] pool4 -> pool4 i0701 17:01:10.766608 26739 net.cpp:197] setting up pool4 i0701 17:01:10.766624 26739 net.cpp:206] top shape: 100 512 14 14 (10035200) I0701 17:18:56.158187 29940 layer_factory.hpp:75] Creating layer conv5_1 I0701 17:18:56.158201 29940 net.cpp:166] Creating Layer conv5_1 I0701 17:18:56.158210 29940 net.cpp:496] conv5_1 <- pool4 I0701 17:18:56.158222 29940 net.cpp:452] conv5_1 -> conv5_1 I0701 17:18:56.158234 29940 net.cpp:197] Setting up conv5_1 I0701 17:18:56.168265 29940 net.cpp:206] Top shape: 100 512 14 14 (10035200) I0701 17:18:56.168303 29940 layer_factory.hpp:75] Creating layer relu5_1 I0701 17:18:56.168320 29940 net.cpp:166] Creating Layer relu5_1 I0701 17:18:56.168329 29940 net.cpp:496] relu5_1 <- conv5_1 I0701 17:18:56.168341 29940 net.cpp:439] relu5_1 -> conv5_1 (in-place) I0701 17:18:56.168355 29940 net.cpp:197] Setting up relu5_1 I0701 17:18:56.168368 29940 net.cpp:206] Top shape: 100 512 14 14 (10035200) I0701 17:18:56.168378 29940 layer_factory.hpp:75] Creating layer conv5_2 I0701 17:18:56.168395 29940 net.cpp:166] Creating Layer conv5_2 I0701 17:18:56.168406 29940 net.cpp:496] conv5_2 <- conv5_1 I0701 17:18:56.168417 29940 net.cpp:452] conv5_2 -> conv5_2 I0701 17:18:56.168431 29940 net.cpp:197] Setting up conv5_2 I0701 17:18:56.178441 29940 net.cpp:206] Top shape: 100 512 14 14 (10035200) I0701 17:18:56.178478 29940 layer_factory.hpp:75] Creating layer relu5_2 I0701 17:18:56.178493 29940 net.cpp:166] Creating Layer relu5_2 I0701 17:18:56.178501 29940 net.cpp:496] relu5_2 <- conv5_2 I0701 17:18:56.178514 29940 net.cpp:439] relu5_2 -> conv5_2 (in-place) I0701 17:18:56.178527 29940 net.cpp:197] Setting up relu5_2 I0701 17:18:56.178539 29940 net.cpp:206] Top shape: 100 512 14 14 (10035200) I0701 17:18:56.178547 29940 layer_factory.hpp:75] Creating layer pool5 I0701 17:18:56.178561 29940 net.cpp:166] Creating Layer pool5 I0701 17:18:56.178570 29940 net.cpp:496] pool5 <- conv5_2 I0701 17:18:56.178581 29940 net.cpp:452] pool5 -> pool5 I0701 17:18:56.178596 29940 net.cpp:197] Setting up pool5 I0701 17:18:56.178611 29940 net.cpp:206] Top shape: 100 512 7 7 (2508800) I0701 17:18:56.178621 29940 layer_factory.hpp:75] Creating layer fc6 i0701 17:01:10.796613 26739 net.cpp:166] creating layer fc6 i0701 17:01:10.796622 26739 net.cpp:496] fc6 <- pool5 i0701 17:01:10.796634 26739 net.cpp:452] fc6 -> fc6 i0701 17:01:10.796650 26739 net.cpp:197] setting up fc6 i0701 17:01:11.236284 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.236351 26739 layer_factory.hpp:75] creating layer relu6 i0701 17:01:11.236373 26739 net.cpp:166] creating layer relu6 i0701 17:01:11.236384 26739 net.cpp:496] relu6 <- fc6 i0701 17:01:11.236404 26739 net.cpp:439] relu6 -> fc6 (in-place) i0701 17:01:11.236423 26739 net.cpp:197] setting up relu6 i0701 17:01:11.236435 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.236444 26739 layer_factory.hpp:75] creating layer drop6 i0701 17:01:11.236464 26739 net.cpp:166] creating layer drop6 i0701 17:01:11.236472 26739 net.cpp:496] drop6 <- fc6 i0701 17:01:11.236486 26739 net.cpp:439] drop6 -> fc6 (in-place) i0701 17:01:11.236500 26739 net.cpp:197] setting up drop6 i0701 17:01:11.236524 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.236534 26739 layer_factory.hpp:75] creating layer fc7 i0701 17:01:11.236549 26739 net.cpp:166] creating layer fc7 i0701 17:01:11.236557 26739 net.cpp:496] fc7 <- fc6 i0701 17:01:11.236569 26739 net.cpp:452] fc7 -> fc7 i0701 17:01:11.236585 26739 net.cpp:197] setting up fc7 i0701 17:01:11.301771 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.301842 26739 layer_factory.hpp:75] creating layer relu7 i0701 17:01:11.301864 26739 net.cpp:166] creating layer relu7 i0701 17:01:11.301877 26739 net.cpp:496] relu7 <- fc7 i0701 17:01:11.301898 26739 net.cpp:439] relu7 -> fc7 (in-place) i0701 17:01:11.301916 26739 net.cpp:197] setting up relu7 i0701 17:01:11.301929 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.301939 26739 layer_factory.hpp:75] creating layer drop7 i0701 17:01:11.301954 26739 net.cpp:166] creating layer drop7 i0701 17:01:11.301962 26739 net.cpp:496] drop7 <- fc7 i0701 17:01:11.301972 26739 net.cpp:439] drop7 -> fc7 (in-place) i0701 17:01:11.301985 26739 net.cpp:197] setting up drop7 i0701 17:01:11.302000 26739 net.cpp:206] top shape: 100 4096 (409600) i0701 17:01:11.302008 26739 layer_factory.hpp:75] creating layer fc8 i0701 17:01:11.302023 26739 net.cpp:166] creating layer fc8 i0701 17:01:11.302032 26739 net.cpp:496] fc8 <- fc7 i0701 17:01:11.302044 26739 net.cpp:452] fc8 -> fc8 i0701 17:01:11.302058 26739 net.cpp:197] setting up fc8 i0701 17:01:11.464764 26739 net.cpp:206] top shape: 100 10000 (1000000)
shape的計算方式能夠參考[caffe]深度學習之圖像分類模型AlexNet解讀。