VGG卷積神經(jīng)網(wǎng)絡(luò)模型解析
一:VGG介紹與模型結(jié)構(gòu)
VGG全稱是Visual Geometry Group屬于牛津大學科學工程系,其發(fā)布了一些列以VGG開頭的卷積網(wǎng)絡(luò)模型,可以應(yīng)用在人臉識別、圖像分類等方面,分別從VGG16~VGG19。VGG研究卷積網(wǎng)絡(luò)深度的初衷是想搞清楚卷積網(wǎng)絡(luò)深度是如何影響大規(guī)模圖像分類與識別的精度和準確率的,最初是VGG-16號稱非常深的卷積網(wǎng)絡(luò)全稱為(GG-Very-Deep-16 CNN),VGG在加深網(wǎng)絡(luò)層數(shù)同時為了避免參數(shù)過多,在所有層都采用3x3的小卷積核,卷積層步長被設(shè)置為1。VGG的輸入被設(shè)置為224x244大小的RGB圖像,在訓練集圖像上對所有圖像計算RGB均值,然后把圖像作為輸入傳入VGG卷積網(wǎng)絡(luò),使用3x3或者1x1的filter,卷積步長被固定1。VGG全連接層有3層,根據(jù)卷積層+全連接層總數(shù)目的不同可以從VGG11 ~ VGG19,最少的VGG11有8個卷積層與3個全連接層,最多的VGG19有16個卷積層+3個全連接層,此外VGG網(wǎng)絡(luò)并不是在每個卷積層后面跟上一個池化層,還是總數(shù)5個池化層,分布在不同的卷積層之下,下圖是VGG11 ~GVV19的結(jié)構(gòu)圖:
考慮到整個網(wǎng)絡(luò)的精簡結(jié)構(gòu)顯示,ReLU激活函數(shù)并沒有被顯示在上述結(jié)構(gòu)中。上述結(jié)構(gòu)中一些說明:
- conv表示卷積層
- FC表示全連接層
- conv3表示卷積層使用3x3 filters
- conv3-64表示 深度64
- maxpool表示***池化
上述VGG11 ~ VGG19參數(shù)總數(shù)列表如下:

在實際處理中還可以對***個全連接層改為7x7的卷積網(wǎng)絡(luò),后面兩個全連接層改為1x1的卷積網(wǎng)絡(luò),這個整個VGG就變成一個全卷積網(wǎng)絡(luò)FCN。在VGG網(wǎng)絡(luò)之前,卷積神經(jīng)網(wǎng)絡(luò)CNN很少有突破10層的,VGG在加深CNN網(wǎng)絡(luò)深度方面首先做出了貢獻,但是VGG也有自身的局限性,不能***制的加深網(wǎng)絡(luò),在網(wǎng)絡(luò)加深到一定層數(shù)之后就會出現(xiàn)訓練效果褪化、梯度消逝或者梯度爆炸等問題,總的來說VGG在剛提出的時候也是風靡一時,在ImageNet競賽數(shù)據(jù)集上都取得了不錯的效果

在其他類似數(shù)據(jù)上同樣表現(xiàn)不俗:

二:預(yù)訓練模型使用(Caffe)
VGG本身提供了預(yù)訓練模型供大家可以自由使用,預(yù)訓練的VGG-16模型與VGG-19模型下載地址可以在這里發(fā)現(xiàn):
http://www.robots.ox.ac.uk/~vgg/research/very_deep/
下載VGG-16模型之后使用OpenCV DNN模塊相關(guān)API,就可以實現(xiàn)一個圖像分類器,支持1000種圖像分類,基于ImageNet 2014-ILSVRC數(shù)據(jù)集訓練。原圖:

VGG-16預(yù)測分類結(jié)果:

稍微有點尷尬的是,OpenCL初始化內(nèi)存不夠了,只能說我的機器不給力:

演示網(wǎng)絡(luò)加載與圖像分類的OpenCV程序代碼如下:
- Net net = readNetFromCaffe(model_txt_file, model_bin_file);
- if (net.empty()) {
- printf("read caffe model data failure...\n");
- return -1;
- }
- Mat inputBlob = blobFromImage(src, 1.0, Size(w, h), Scalar(104, 117, 123));
- Mat prob;
- for (int i = 0; i < 10; i++) {
- net.setInput(inputBlob, "data");
- prob = net.forward("prob");
- }
- Mat probMat = prob.reshape(1, 1);
- Point classNumber;
- double classProb;
- minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber);
- int classidx = classNumber.x;
- printf("\n current image classification : %s, possible : %.2f", labels.at(classidx).c_str(), classProb);
- putText(src, labels.at(classidx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8);
- imshow("Image Classification", src);
學習OpenCV 深度學習視頻教程 點擊下面: