CNN——架構上的一些數字git
前面說了不少關於CNN的數值上的事,下面咱們來看看網絡架構。網絡架構也是CNN的一個核心部分,因爲CNN的特色是它的深度,因此深度模型的網絡架構給了人們無數的想象,因而也有了無數的前輩創造了各類各樣的模型。咱們今天來看看那些經典的模型,不是從感性的角度上去觀看,而是從理性的角度——去嘗試計算一些具體的數字,讓咱們描繪出這些模型的一個簡單輪廓。github
咱們的目標問題是ImageNet分類問題,那麼咱們主要關注哪些問題呢?網絡
問題總結 架構
-
模型的深度,模型的核心層(卷積層、全鏈接層)的數量,這表明了模型的某種「能力」,基本上你們都有一個共識,那忽略優化問題的狀況下,就是越深的模型在函數擬合方面效果越好。這裏直接利用Caffe計算其中的layers_.size(),因爲其中還包括data layer和loss layer,因此統計數會比實際的層數要多。機器學習
-
每層模型的參數數量,參數的總量,這表明了模型的複雜度。從機器學習的理論上講,參數越多,模型的表達能力理論上也會「越強」。這裏經過Caffe計算全部learnable_params的count總和表示。ide
-
模型前向的所需的內存量。也就是Caffe中計算的memory_used_變量值。函數
AlexNet學習
本文不是負責介紹歷史的,因此不會花什麼篇幅去聊故事。模型的prototxt來自:優化
https://github.com/BVLC/caffe/blob/master/models/bvlc_alexnet/train_val.prototxtgoogle
VGGNet
VGGNet也是一個比較有表明性的網絡,關於這個網絡的「哲學」咱們後面再開新貼去聊。利用論文和各處獲得的信息,咱們能夠詳細給出VGG19層模型的具體結構,參考的prototxt來自:
https://gist.github.com/ksimonyan/3785162f95cd2d5fee77#file-readme-md
CS231n Convolutional Neural Networks for Visual Recognition對VGG模型的內存佔用量和參數數量作過一個計算,僅做參考:
INPUT: [224x224x3] memory: 224*224*3=150K weights: 0
CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*3)*64 = 1,728
CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*64)*64 = 36,864
POOL2: [112x112x64] memory: 112*112*64=800K weights: 0
CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*64)*128 = 73,728
CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*128)*128 = 147,456
POOL2: [56x56x128] memory: 56*56*128=400K weights: 0
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*128)*256 = 294,912
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
POOL2: [28x28x256] memory: 28*28*256=200K weights: 0
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*256)*512 = 1,179,648
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
POOL2: [14x14x512] memory: 14*14*512=100K weights: 0
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
POOL2: [7x7x512] memory: 7*7*512=25K weights: 0
FC: [1x1x4096] memory: 4096 weights: 7*7*512*4096 = 102,760,448
FC: [1x1x4096] memory: 4096 weights: 4096*4096 = 16,777,216
FC: [1x1x1000] memory: 1000 weights: 4096*1000 = 4,096,000
TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd)
TOTAL params: 138M parameters
可見在計算過程當中偏置項並無被計算在其中。咱們也要作一個詳細的計算。
GoogleNet
GoogleNet做爲Inception module的表明,一樣取得了不錯的成績,咱們的參考prototxt來自:https://github.com/BVLC/caffe/blob/master/models/bvlc_googlenet/train_val.prototxt
ResNet
ResNet做爲新一代的模型霸主,其對模型構建的思想可謂又上了一個臺階。這裏的ResNet咱們參考的prototxt是
https://github.com/KaimingHe/deep-residual-networks/blob/master/prototxt/ResNet-152-deploy.prototxt
最終結果
下面揭曉最終的實驗結果,並附上當年論文中或者網絡上給出的單模型的精度。若是數字有錯誤歡迎指出。
咱們一列一列來看,從模型層數來看,幾年間模型的層數已經獲得了爆炸式的增加,雖然GoogleNet的Inception Module和ResNet的Residual Module的網絡層數都存在水分(GoogleNet官方宣稱22層,ResNet官方宣稱152層),可是整體上的趨勢仍是很明顯的,那就是網絡結構向着複雜的方向演變,層數也向着變深的方向演變。
對於Memory來講,除了GoogleNet(GoogleNet通常也是幾個模型ensemble一塊兒用),其餘的模型的體量都比較大,在前向計算時所花費的存儲仍是很大的。
模型參數也是比較有意思的地方,實際上VGGNet的參數主要集中在全鏈接層上,而GoogleNet和ResNet在參數數量上並不算多,由於他們的層數實際上已經比較深,從層數的角度來看,模型的參數密度其實是在減小的。
關於精度……這裏就不細說了。
最後補充一句關於VGG的數據,上面的Memory計算的是1個batch所花費的內存,batch_size=256,想要對比上面的公式推演和代碼計算的數字,須要把Memory的值除以batch_size。
好了,展現了這麼多參數,實際上也是要說明CNN網絡發展的趨勢,那就是從Shallow and wide的模型轉型成deep but thin的模型。模型的複雜程度不斷增長,模型的擬合能力不斷加強,但參數總量控制得很好,152層的ResNet和5層conv+3層fc的模型參數數量相近,其實這裏面也說明了不少問題。
那麼這些模型到底是如何演化過來的呢?VGG的「模型哲學」,Inception Module的思想,ResNet對模型結構的顛覆都是如何影響咱們對模型結構的三觀呢?
下篇文章將會對此進行解答!