經(jīng)典分類CNN模型系列其三:Inception v1

介紹

Inception 又叫Googlenet是Google于2014年為參加ILSVRC大賽而提出的CNN分類模型。它發(fā)表于2014年的CVPR上面。在深度學(xué)習(xí)領(lǐng)域Google出品幾乎必為精品,Inception也不例外。

它乍看上去像是蠻復(fù)雜的,但細(xì)看其結(jié)構(gòu)就會(huì)發(fā)現(xiàn)它其實(shí)就是用一個(gè)個(gè)Inception module給堆起來的。它的設(shè)計(jì)充滿了科學(xué)理論與工程實(shí)踐的結(jié)合,是一個(gè)典型的data scientist與軟件工程師結(jié)合搞出來的東東。

在此之前經(jīng)典的CNN模型像LeNet/Alexnet/VGG等無不是一個(gè)模子即使用Conv/Pool/Normalization/Activation等層來不斷累積而成。模型對(duì)數(shù)據(jù)集概率分布的表達(dá)能力則往往通過單純?cè)黾幽P偷纳疃龋▽訑?shù))或?qū)挾龋▽拥腸hannels數(shù))來提高(當(dāng)然這也亦是當(dāng)下深度學(xué)習(xí)領(lǐng)域的共識(shí))。但這樣進(jìn)行網(wǎng)絡(luò)設(shè)計(jì)一般會(huì)等來巨量的計(jì)算開銷,因?yàn)槊恳粚觕hannels數(shù)目的增加都會(huì)隨著層深而指數(shù)級(jí)增加,這大大地限制了模型的實(shí)際應(yīng)用。

GoogleNet團(tuán)隊(duì)在考慮網(wǎng)絡(luò)設(shè)計(jì)時(shí)不只注重增加模型的分類精度,同時(shí)也考慮了其可能的計(jì)算與內(nèi)存使用開銷。他們借鑒了諸多前人的觀點(diǎn)與經(jīng)驗(yàn)(尤其是Network in Network中使用1x1 conv及AvgPool的idea),想通過一種spared layer architecture來實(shí)現(xiàn)較優(yōu)的多維度特征表達(dá),然后通過對(duì)這種結(jié)構(gòu)進(jìn)行疊加,中間不時(shí)再插入一些MaxPool層以減少參數(shù)數(shù)目(從而節(jié)省內(nèi)存與計(jì)算開銷),最終就行成了Inception v1分類模型。它作為2014年ILSVRC圖像分類大賽中的最優(yōu)選手,取得了非常大的成功。后來GoogleNet團(tuán)隊(duì)再接再厲接連提出了融入更新思想,同時(shí)分類精度也更高的Inception v2/Inception v3/Inception v4及Inception-Resnet等模型,從而將Inception的思想推至了當(dāng)下的巔峰。此是后話,欲知Inception系列模型的淵源還是須從這個(gè)最早的Inception v1開始。

Inception模塊設(shè)計(jì)

傳統(tǒng)的CNN模型設(shè)計(jì),其能力增加往往通過增加層數(shù)及增寬層的通道數(shù)來實(shí)現(xiàn)。但這會(huì)帶來兩個(gè)問題,首先這兩種設(shè)計(jì)思路都是在高密度計(jì)算的單元上(如FC層/Conv層)實(shí)現(xiàn)的,它會(huì)帶來大量的訓(xùn)練參數(shù)增加,而過多的參數(shù)往往意味著容易出現(xiàn)過擬合;其次單純?cè)用芗?jì)算單元的層數(shù)或每層寬度都會(huì)招至后須擴(kuò)展的指數(shù)級(jí)的計(jì)算量增加。

顯然通過使用一種稀疏的層次結(jié)構(gòu)而非使用像FC/Conv這樣的全級(jí)聯(lián)式的結(jié)構(gòu)有助于計(jì)算開銷的降低。而且一旦這種稀疏的結(jié)構(gòu)設(shè)計(jì)良好可以有效地?cái)U(kuò)大表達(dá)特征的范圍,從而更有效地對(duì)圖片信息進(jìn)行表達(dá)??蛇^于稀疏的結(jié)構(gòu)計(jì)算一般都不大高效(當(dāng)下用于CPU/GPU上的一些高效加速庫(kù)多是在密集計(jì)算上進(jìn)行優(yōu)化的),同時(shí)也會(huì)帶來較多的cache miss及內(nèi)存地址非連續(xù)搜索的overhead。最終GoogleNet團(tuán)隊(duì)選擇了中間路線即使用由密集計(jì)算子結(jié)構(gòu)組合而成的稀疏模塊來用于特征提取及表達(dá),這就是用于構(gòu)建Inception v1的Inception module如下圖中a所示。

其中1x1/3x3/5x5這三種Conv kernels的選擇決定是基于方便(因?yàn)檫@幾種kernels用的多啊,而且比較容易對(duì)齊,padding)來定的(汗)。

圖a的這個(gè)基本module顯然在計(jì)算開銷上隱藏著重大問題即它的輸出將每個(gè)不同尺度的conv的輸出級(jí)連起來用于下一個(gè)module的輸入。這勢(shì)必會(huì)招至計(jì)算量的指數(shù)級(jí)增加。因此作者借鑒Network in Network中的idea,在每個(gè)子conv層里使用了1x1的conv來作上一層的輸入feature maps的channels數(shù)縮減、歸總。如此每個(gè)Inception module里的計(jì)算都由各自的1x1 conv來隔離,從而不會(huì)像傳統(tǒng)CNN深度模型那樣隨著深度增加其計(jì)算量也指數(shù)級(jí)增加。這就是最終用于構(gòu)建Inception 網(wǎng)絡(luò)的基礎(chǔ)模塊inception即圖b。

Inception模塊

GoogleNet

GoogleNet網(wǎng)絡(luò)結(jié)構(gòu)

上表即為GoogleNet的網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)概況。可以看出并非整個(gè)網(wǎng)絡(luò)都是由Inception module來組成。它的前面幾層采用了類似于經(jīng)典網(wǎng)絡(luò)的那種單尺度Conv/Pool/ReLu的設(shè)計(jì),這主要是出于用于進(jìn)行模型計(jì)算的系統(tǒng)架構(gòu)的實(shí)際考慮。

作者表明我們可以靈活地根據(jù)自己所有的硬件/軟件/系統(tǒng)等情況來選擇Inception網(wǎng)絡(luò)中各模塊的使用(modules數(shù)目及其上的conv的channels數(shù))。而上表所列的這個(gè)有著22個(gè)參數(shù)層的GoogleNet只是在作者他們實(shí)驗(yàn)所用的機(jī)器上得到的較優(yōu)網(wǎng)絡(luò)。因此我們不必過于拘泥于它的具體實(shí)現(xiàn)細(xì)節(jié),只需了解它的本質(zhì)設(shè)計(jì)思想即可。

模型的最后會(huì)選通過一個(gè)AvgPool層來處理最終的feature maps,然后再由FC層匯總生成1000個(gè)輸出,進(jìn)而由Softmax來得到1000類的概率分布。隨著CNN模型的加深,它最終表達(dá)的特征也愈加地抽象,只使用最后層次的特征可能會(huì)招至對(duì)小尺度目標(biāo)的忽略,因此作者分別在中間及較靠后層的地方插入了兩個(gè)獨(dú)立的分類層以在訓(xùn)練時(shí)協(xié)同發(fā)揮影響。下圖即為最終的GoogleNet模型。

GoogleNet模型

模型訓(xùn)練

這算是當(dāng)時(shí)最為復(fù)雜的模型了,多達(dá)22層。它的訓(xùn)練難度顯然也是空前的。作者使用他們內(nèi)部的DistBelief分布式系統(tǒng)對(duì)模型進(jìn)行訓(xùn)練,中間使用了模型并行與數(shù)據(jù)并行兩種多節(jié)點(diǎn)并行方式(這個(gè)難度其實(shí)還是蠻高的,玩過多節(jié)點(diǎn)訓(xùn)練的人都懂?。A硗馑麄冞€使用了Async sgd的方式進(jìn)行模型參數(shù)更新(這使得模型的訓(xùn)練難度更是增加了,沒辦法估計(jì)他們當(dāng)時(shí)也是覺著訓(xùn)練時(shí)間實(shí)在太久了,所以才會(huì)選擇使用Async sgd這種加速收斂的方式吧)。

此外作者使用了集成多個(gè)模型(6個(gè)結(jié)構(gòu)相同,1個(gè)略不同;相用相同的初始化,只是不同的shuffle過的數(shù)據(jù)集)來提高分類準(zhǔn)確率的做法。同時(shí)也使用了像resize/不同scales/鏡像及color distortation等多種數(shù)據(jù)增強(qiáng)的方式。

實(shí)驗(yàn)結(jié)果

下表中即為GoogleNet網(wǎng)絡(luò)與其它模型的結(jié)果對(duì)比。

GoogleNet與其它模型的分類結(jié)果對(duì)比

代碼分析

當(dāng)下大多數(shù)的經(jīng)典模型都已經(jīng)在Intel caffe里面有了良好實(shí)現(xiàn)。我們甚至不需要GPU,單單用自己家datacenter里面的CPUs也能玩轉(zhuǎn)下模型訓(xùn)練及推理。

下面為data layer層,與VGG等的并無差別。

layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 224
    mean_value: 104
    mean_value: 117
    mean_value: 123
  }
  data_param {
    source: "examples/imagenet/ilsvrc12_train_lmdb"
    batch_size: 32
    backend: LMDB
  }
}

以下數(shù)層則為網(wǎng)絡(luò)中inception_3a 模塊的組成情況。

layer {
  name: "inception_3a/1x1"
  type: "Convolution"
  bottom: "pool2/3x3_s2"
  top: "inception_3a/1x1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    kernel_size: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_1x1"
  type: "ReLU"
  bottom: "inception_3a/1x1"
  top: "inception_3a/1x1"
}
layer {
  name: "inception_3a/3x3_reduce"
  type: "Convolution"
  bottom: "pool2/3x3_s2"
  top: "inception_3a/3x3_reduce"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_3x3_reduce"
  type: "ReLU"
  bottom: "inception_3a/3x3_reduce"
  top: "inception_3a/3x3_reduce"
}
layer {
  name: "inception_3a/3x3"
  type: "Convolution"
  bottom: "inception_3a/3x3_reduce"
  top: "inception_3a/3x3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_3x3"
  type: "ReLU"
  bottom: "inception_3a/3x3"
  top: "inception_3a/3x3"
}
layer {
  name: "inception_3a/5x5_reduce"
  type: "Convolution"
  bottom: "pool2/3x3_s2"
  top: "inception_3a/5x5_reduce"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 16
    kernel_size: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_5x5_reduce"
  type: "ReLU"
  bottom: "inception_3a/5x5_reduce"
  top: "inception_3a/5x5_reduce"
}
layer {
  name: "inception_3a/5x5"
  type: "Convolution"
  bottom: "inception_3a/5x5_reduce"
  top: "inception_3a/5x5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 32
    pad: 2
    kernel_size: 5
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_5x5"
  type: "ReLU"
  bottom: "inception_3a/5x5"
  top: "inception_3a/5x5"
}
layer {
  name: "inception_3a/pool"
  type: "Pooling"
  bottom: "pool2/3x3_s2"
  top: "inception_3a/pool"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 1
    pad: 1
  }
}
layer {
  name: "inception_3a/pool_proj"
  type: "Convolution"
  bottom: "inception_3a/pool"
  top: "inception_3a/pool_proj"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 32
    kernel_size: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0.2
    }
  }
}
layer {
  name: "inception_3a/relu_pool_proj"
  type: "ReLU"
  bottom: "inception_3a/pool_proj"
  top: "inception_3a/pool_proj"
}
layer {
  name: "inception_3a/output"
  type: "Concat"
  bottom: "inception_3a/1x1"
  bottom: "inception_3a/3x3"
  bottom: "inception_3a/5x5"
  bottom: "inception_3a/pool_proj"
  top: "inception_3a/output"
}

最后則是其AvgPool/DropOut/FC的使用。及最終所生成的loss與accuracy top-1/top-5實(shí)現(xiàn)。

layer {
  name: "pool5/7x7_s1"
  type: "Pooling"
  bottom: "inception_5b/output"
  top: "pool5/7x7_s1"
  pooling_param {
    pool: AVE
    kernel_size: 7
    stride: 1
  }
}
layer {
  name: "pool5/drop_7x7_s1"
  type: "Dropout"
  bottom: "pool5/7x7_s1"
  top: "pool5/7x7_s1"
  dropout_param {
    dropout_ratio: 0.4
  }
}
layer {
  name: "loss3/classifier"
  type: "InnerProduct"
  bottom: "pool5/7x7_s1"
  top: "loss3/classifier"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 1000
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "loss3/loss3"
  type: "SoftmaxWithLoss"
  bottom: "loss3/classifier"
  bottom: "label"
  top: "loss3/loss3"
  loss_weight: 1
}
layer {
  name: "loss3/top-1"
  type: "Accuracy"
  bottom: "loss3/classifier"
  bottom: "label"
  top: "loss3/top-1"
  include {
    phase: TEST
  }
}
layer {
  name: "loss3/top-5"
  type: "Accuracy"
  bottom: "loss3/classifier"
  bottom: "label"
  top: "loss3/top-5"
  include {
    phase: TEST
  }
  accuracy_param {
    top_k: 5
  }
}

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容