VGG16學習筆記

轉載自:http://deanhan.com/2018/07/26/vgg16/ ,侵權則刪

摘要

本文對圖片分類任務中經典的深度學習模型VGG16進行了簡要介紹,分析了其結構,並討論了其優缺點。調用Keras中已有的VGG16模型測試其分類性能,結果表明VGG16對三幅測試圖片均能正確分類。

前言

VGG是由Simonyan 和Zisserman在文獻《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷積神經網絡模型,其名稱來源於作者所在的牛津大學視覺幾何組(Visual Geometry Group)的縮寫。

該模型參加2014年的 ImageNet圖像分類與定位挑戰賽,取得了優異成績:在分類任務上排名第二,在定位任務上排名第一。

結構

VGG中根據卷積核大小卷積層數目的不同,可分爲AA-LRN,B,C,D,E共6個配置(ConvNet Configuration),其中以D,E兩種配置較爲常用,分別稱爲VGG16VGG19

下圖給出了VGG的六種結構配置:

 

上圖中,每一列對應一種結構配置。例如,圖中綠色部分即指明瞭VGG16所採用的結構。

我們針對VGG16進行具體分析發現,VGG16共包含:

  • 13個卷積層(Convolutional Layer),分別用conv3-XXX表示
  • 3個全連接層(Fully connected Layer),分別用FC-XXXX表示
  • 5個池化層(Pool layer),分別用maxpool表示

其中,卷積層和全連接層具有權重係數,因此也被稱爲權重層,總數目爲13+3=16,這即是

VGG16中16的來源。(池化層不涉及權重,因此不屬於權重層,不被計數)。

特點

VGG16的突出特點是簡單,體現在:

  1. 卷積層均採用相同的卷積核參數

    卷積層均表示爲conv3-XXX,其中conv3說明該卷積層採用的卷積核的尺寸(kernel size)是3,即寬(width)和高(height)均爲3,3*3很小的卷積核尺寸,結合其它參數(步幅stride=1,填充方式padding=same),這樣就能夠使得每一個卷積層(張量)與前一層(張量)保持相同的寬和高。XXX代表卷積層的通道數。

  2. 池化層均採用相同的池化核參數

    池化層的參數均爲2××2,步幅stride=2,max的池化方式,這樣就能夠使得每一個池化層(張量)的寬和高是前一層(張量)的1212。

  3. 模型是由若干卷積層和池化層堆疊(stack)的方式構成,比較容易形成較深的網絡結構(在2014年,16層已經被認爲很深了)。

綜合上述分析,可以概括VGG的優點爲: Small filters, Deeper networks.

 

塊結構

我們注意圖1右側,VGG16的卷積層和池化層可以劃分爲不同的塊(Block),從前到後依次編號爲Block1~block5。每一個塊內包含若干卷積層一個池化層。例如:Block4包含:

  • 3個卷積層,conv3-512
  • 1個池化層,maxpool

並且同一塊內,卷積層的通道(channel)數是相同的,例如:

  • block2中包含2個卷積層,每個卷積層用conv3-128表示,即卷積核爲:3x3x3,通道數都是128
  • block3中包含3個卷積層,每個卷積層用conv3-256表示,即卷積核爲:3x3x3,通道數都是256

下面給出按照塊劃分的VGG16的結構圖,可以結合圖2進行理解:

 

VGG的輸入圖像是 224x224x3 的圖像張量(tensor),隨着層數的增加,後一個塊內的張量相比於前一個塊內的張量:

  • 通道數翻倍,由64依次增加到128,再到256,直至512保持不變,不再翻倍
  • 高和寬變減半,由 224→112→56→28→14→7

權重參數

儘管VGG的結構簡單,但是所包含的權重數目卻很大,達到了驚人的139,357,544個參數。這些參數包括卷積核權重全連接層權重

  • 例如,對於第一層卷積,由於輸入圖的通道數是3,網絡必須學習大小爲3x3,通道數爲3的的卷積核,這樣的卷積核有64個,因此總共有(3x3x3)x64 = 1728個參數
  • 計算全連接層的權重參數數目的方法爲:前一層節點數×本層的節點數前一層節點數×本層的節點數。因此,全連接層的參數分別爲:
    • 7x7x512x4096 = 1027,645,444
    • 4096x4096 = 16,781,321
    • 4096x1000 = 4096000

FeiFei Li在CS231的課件中給出了整個網絡的全部參數的計算過程(不考慮偏置),如下圖所示:

圖中藍色是計算權重參數數量的部分;紅色是計算所需存儲容量的部分。

VGG16具有如此之大的參數數目,可以預期它具有很高的擬合能力;但同時缺點也很明顯:

  • 即訓練時間過長,調參難度大。
  • 需要的存儲容量大,不利於部署。例如存儲VGG16權重值文件的大小爲500多MB,不利於安裝到嵌入式系統中。

實踐

下面,我們應用Keras對VGG16的圖像分類能力進行試驗。

Keras是一個高層神經網絡API,Keras由純Python編寫 ,是tensorflow和Theano等底層深度學習庫的高級封裝 。使用Keras時,我們不需要直接調用底層API構建深度學習網絡,僅調用keras已經封裝好的函數即可。

本次試驗平臺:python 3.6 + tensorflow 1.8 + keras 2.2,Google Colab

源代碼如下:

複製代碼

 1 # -*- coding: utf-8 -*-
 2 """
 3 Spyder Editor
 4 
 5 This is a temporary script file.
 6 """
 7 import matplotlib.pyplot as plt
 8 
 9 from keras.applications.vgg16 import VGG16
10 from keras.preprocessing import image
11 from keras.applications.vgg16 import preprocess_input, decode_predictions
12 import numpy as np
13 
14 def percent(value):
15     return '%.2f%%' % (value * 100)
16 
17 # include_top=True,表示會載入完整的 VGG16 模型,包括加在最後3層的卷積層
18 # include_top=False,表示會載入 VGG16 的模型,不包括加在最後3層的卷積層,通常是取得 Features
19 # 若下載失敗,請先刪除 c:\<使用者>\.keras\models\vgg16_weights_tf_dim_ordering_tf_kernels.h5
20 model = VGG16(weights='imagenet', include_top=True)
21 
22 
23 # Input:要辨識的影像
24 img_path = 'frog.jpg'
25 
26 #img_path = 'tiger.jpg' 並轉化爲224*224的標準尺寸
27 img = image.load_img(img_path, target_size=(224, 224))
28 
29 
30 x = image.img_to_array(img) #轉化爲浮點型
31 x = np.expand_dims(x, axis=0)#轉化爲張量size爲(1, 224, 224, 3)
32 x = preprocess_input(x)
33 
34 # 預測,取得features,維度為 (1,1000)
35 features = model.predict(x)
36 
37 # 取得前五個最可能的類別及機率
38 pred=decode_predictions(features, top=5)[0]
39 
40 
41 #整理預測結果,value
42 values = []
43 bar_label = []
44 for element in pred:
45     values.append(element[2])
46     bar_label.append(element[1])
47 
48 #繪圖並保存
49 fig=plt.figure(u"Top-5 預測結果")
50 ax = fig.add_subplot(111) 
51 ax.bar(range(len(values)), values, tick_label=bar_label, width=0.5, fc='g')
52 ax.set_ylabel(u'probability') 
53 ax.set_title(u'Top-5') 
54 for a,b in zip(range(len(values)), values):
55     ax.text(a, b+0.0005, percent(b), ha='center', va = 'bottom', fontsize=7)
56 
57 fig = plt.gcf()
58 plt.show()
59 
60 name=img_path[0:-4]+'_pred'
61 fig.savefig(name, dpi=200)

複製代碼

上述程序的基本流程是:

  1. 載入相關模塊,keras ,matplotlib,numpy
  2. 下載已經訓練好的模型文件:
  3. 導入測試圖像
  4. 應用模型文件對圖像分類

需要額外說明的是:

  • 程序運行過程中,語句model = VGG16(weights='imagenet', include_top=True)會下載已經訓練好的文件到c:\<使用者>\.keras\models文件夾下,模型的文件名爲vgg16_weights_tf_dim_ordering_tf_kernels.h5,大小爲527MB

  • 語句pred=decode_predictions(features, top=5)[0]會下載分類信息文件到c:\<使用者>\.keras\models文件夾下,模型的文件名爲imagenet_class_index.json,該文件指明瞭ImageNet大賽所用的1000個圖像類的信息。(由於下載地址在aws上,梯子請自備)

  • 程序運行結束,會在工作目錄下生成測試圖片的預測圖,給出了最有可能的前5個類列。名稱爲:測試文件名_pred.png

  • 在程序中還可以查看模型的結構,語句爲:model.summary(),命令行輸出模型的結構配置爲:

複製代碼

 1 _________________________________________________________________
 2 Layer (type)                 Output Shape              Param #   
 3 =================================================================
 4 input_12 (InputLayer)        (None, 224, 224, 3)       0         
 5 _________________________________________________________________
 6 block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
 7 _________________________________________________________________
 8 block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
 9 _________________________________________________________________
10 block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         
11 _________________________________________________________________
12 block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     
13 _________________________________________________________________
14 block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    
15 _________________________________________________________________
16 block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0         
17 _________________________________________________________________
18 block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168    
19 _________________________________________________________________
20 block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080    
21 _________________________________________________________________
22 block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080    
23 _________________________________________________________________
24 block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0         
25 _________________________________________________________________
26 block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160   
27 _________________________________________________________________
28 block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808   
29 _________________________________________________________________
30 block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808   
31 _________________________________________________________________
32 block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0         
33 _________________________________________________________________
34 block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808   
35 _________________________________________________________________
36 block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   
37 _________________________________________________________________
38 block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
39 _________________________________________________________________
40 block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
41 _________________________________________________________________
42 flatten (Flatten)            (None, 25088)             0         
43 _________________________________________________________________
44 fc1 (Dense)                  (None, 4096)              102764544 
45 _________________________________________________________________
46 fc2 (Dense)                  (None, 4096)              16781312  
47 _________________________________________________________________
48 predictions (Dense)          (None, 1000)              4097000   
49 =================================================================
50 Total params: 138,357,544
51 Trainable params: 138,357,544
52 Non-trainable params: 0
53 _________________________________________________________________

複製代碼

可以看到總的訓練參數爲 138,357,544。

代碼及圖片文件全部放在我的github

結果

分別對虎(tiger),貓(cat),捲紙(paper_towel)三張圖片進行分類:

 

 




 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章